rory rory - 15 days ago 4
CSS Question

Click not completing due to Css Transition

When I click on the search icon the event fires as it should. But when the search box is expanded the click doesn't fire, instead, the search box goes back to being small again.

Edit: See claudios snippet for the behaviour I mean

Edit 2:

.mouseDown()
instead of
.click()
works.
So it seems that when I click on the search icon, focus in the searchbox is lost which makes it go back to it's original size. This would appear to happen before the mouseUp event which means the coords for the search icon are no longer the same as the
.click()
event.

enter image description here enter image description here

So I fired up the debugger, set the search box to focus and set my breakpoints and it works. Can I assume my Css transitions are preventing the click action from completing? And if so how do I get the click in before the css takes effect?

Here is all the relevant code:



jQuery('.icon-wrapper').click(function(){
var searchQuery = jQuery('#searchBox').val();
if(searchQuery != ""){
alert("I got clicked!");
return;
}
});

.expandable-search input[type=search]:focus {
width: 80%;
}

input[type=search] {
-webkit-appearance: textfield;
-webkit-box-sizing: content-box;
font-family: inherit;
font-size: 100%;
}


input[type=search] {
border: solid 1px #ccc;
padding: 9px 10px 9px 32px;
width: 55px;

-webkit-border-radius: 10em;
-moz-border-radius: 10em;
border-radius: 10em;

-webkit-transition: all .5s;
-moz-transition: all .5s;
transition: all .5s;
}


.expandable-search input[type=search] {
padding-left: 10px;
color: transparent;
}

.expandable-search input[type=search]:hover {
background-color: #fff;
}

span.icon-wrapper:hover {
cursor: pointer;
}

.expandable-search input[type=search]:focus {
width: 130px;
padding-left: 32px;
color: #000;
background-color: #fff;
cursor: auto;
}
.expandable-search input:-moz-placeholder {
color: transparent;
}
.expandable-search input::-webkit-input-placeholder {
color: transparent;
}

.expandable-search .icon-wrapper:after {
content: url("http://ak-static.legacy.net/obituaries/images/obituary/obituaryportal/icon_search.png");
font-family:"Glyphicons Halflings";
position: absolute;
left: 20px;
top: 10px;
color: #212121;
font-size: 20px;
left: 50px;
top: 15px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<li class="expandable-search vertical-center">
<input type="search" id="searchBox">
<span class="icon-wrapper"></span>
</li>




Answer

As far as I could understand the issue you want that the icon has two jobs

  1. first expand the search input
  2. after that act like a submit button. Maybe even check if the search input has value. If yes, do the request for example a post via ajax, otherwise do nothing or display a message that the user has to fill in something.

Working with CSS :focus

One problem is that each time you click now on the icon, the search input will lose its focus because your icon is not content of this input. So the :focus you add with CSS will be removed. One solution would be to work with pseudo elements and simply put the icon in the :after or :before content, but since you can't use any of them on inputs, you have to do a workaround to achieve what you want. So in your case I think the only way is to simulate the focus via JavaScript.

You could achieve this with following code

HTML

<div id="search">
  <button id="search-button">
    <i class="ion-ios-search"></i>
  </button>
  <input type="search" id="search-input" />
</div>

CSS

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: #eee;
}

input {
  display: none;
}

#search {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 40px;
  font-size: 0;
}

#search-button,
#search-input {
  display: inline-block;
  background: white;
  border: none;
  outline: none;
}

#search-button {
  position: relative;
  width: 40px;
  height: 100%;
  border: none;
  cursor: pointer;
}

#search-button i {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 30px;
  margin: 0;
}

#search-input {
  height: 100%;
  width: 0;
  font-size: 20px;
  vertical-align: top;
  transition: 0.3s;
  padding: 0;
}

.clicked + #search-input {
  width: 200px;
}

jQuery

var $searchButton = $("#search-button");
var $searchInput = $("#search-input");

$searchButton.click(function() {
  $searchInput.focus();
  if ($searchInput.val() !== "") {
    alert("post");
  } else if (!$(this).hasClass("clicked") && $searchInput.val() === "") {
    $(this).addClass("clicked");
  } else if ($(this).hasClass("clicked") && $searchInput.val() === "") {
    alert("fill");
  }
});

$(document).click(function(e){
  if(!$("#search").has(e.target).length && $searchInput.val() === ""){
    $searchButton.removeClass("clicked");
  }
});

var $searchButton = $("#search-button");
var $searchInput = $("#search-input");

$searchButton.click(function() {
  $searchInput.focus();
  if ($searchInput.val() !== "") {
    alert("post");
  } else if (!$(this).hasClass("clicked") && $searchInput.val() === "") {
    $(this).addClass("clicked");
  } else if ($(this).hasClass("clicked") && $searchInput.val() === "") {
    alert("fill something in");
  }
});

$(document).click(function(e) {
  if (!$("#search").has(e.target).length && $searchInput.val() === "") {
    $searchButton.removeClass("clicked");
  }
});
* {
  box-sizing: border-box;
}
html,
body {
  height: 100%;
}
body {
  margin: 0;
  background: #eee;
}
input {
  display: none;
}
#search {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 40px;
  font-size: 0;
}
#search-button,
#search-input {
  display: inline-block;
  background: white;
  border: none;
  outline: none;
}
#search-button {
  position: relative;
  width: 40px;
  height: 100%;
  border: none;
  cursor: pointer;
}
#search-button i {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 30px;
  margin: 0;
}
#search-input {
  height: 100%;
  width: 0;
  font-size: 20px;
  vertical-align: top;
  transition: 0.3s;
  padding: 0;
}
.clicked + #search-input {
  width: 200px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="search">
  <button id="search-button">
    <i class="ion-ios-search"></i>
  </button>
  <input type="search" id="search-input" />
</div>

Comments