4

Implemented a clear button using -webkit-search-cancel-button following the next post:

https://stackoverflow.com/a/64267916/1065145

The problem with the implementation referenced above is that it renders the clear icon invisible when out of focus, but it still occupies space and it doesn't look nice at all:

enter image description here

It can be either a long placeholder on a small device or a long user query:

enter image description here

Trying to solve it with display: none doesn't really work, because it still renders invisible when the input is in focus, but there is no user input yet and only the placeholder is shown (and part of it is eaten by the invisible icon).

Q. Is there a way to make icon truly invisible so it is shown only on two conditions:

  1. The input is in focus.
  2. User has provided some input and the placeholder is gone.
Denis Kulagin
  • 8,472
  • 17
  • 60
  • 129

2 Answers2

4

display: none; and display: block; worked for me (the newest Chrome). It it necessary to add dispay block when in focus (input[type="search"]:focus::-webkit-search-cancel-button).

If it still not working, try with !important. Sometimes browser style is harder to override. (I'm not recommending using !important, but sometimes there is no other way).

if you want show clear button even with no tekst provided by user add:

input[type="search"]::-webkit-search-cancel-button {
    opacity: 1 !important;
}

input[type="search"] {
  border: 1px solid gray;
  padding: .2em .4em;
  border-radius: .2em;
}

input[type="search"].dark {
  background: #222;
  color: #fff;
}

input[type="search"].light {
  background: #fff;
  color: #222;
}

input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  height: 1em;
  width: 1em;
  margin-left: .5em;
  border-radius: 50em;
  background: url(https://pro.fontawesome.com/releases/v5.10.0/svgs/solid/times-circle.svg) no-repeat 50% 50%;
  background-size: contain;
  display: none;
  pointer-events: none;
}

input[type="search"]:focus::-webkit-search-cancel-button {
  display: block;
  pointer-events: all;
}

input[type="search"].dark::-webkit-search-cancel-button {
  filter: invert(1);
}
<input type="search" placeholder="search" class="light">
<input type="search" placeholder="search" class="dark">

Edited:

I manage to do it, like you wanted.

I used: https://developer.mozilla.org/en-US/docs/Web/CSS/:placeholder-shown

I also left outline borders for better understanding.

input[type="search"] {
  border: 1px solid gray;
  padding: .2em .4em;
  border-radius: .2em;
}

input[type="search"].dark {
  background: #222;
  color: #fff;
}

input[type="search"].light {
  background: #fff;
  color: #222;
}
input[type="search"]::-webkit-textfield-decoration-container {
  width: 100%;
}

/* normal state, with placeholder and no value */
input[type="search"]:placeholder-shown::-webkit-textfield-decoration-container {
  outline: 1px dotted yellow;
}

/* focused state, with placeholder and no value */
input[type="search"]:placeholder-shown:focus::-webkit-textfield-decoration-container {
  outline: 1px dotted red;
}

/* focused state, with value */
input[type="search"]:not(:placeholder-shown):focus::-webkit-textfield-decoration-container {
  outline: 1px dotted green;
}

input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  height: 1em;
  width: 0;
  border-radius: 50em;
  background: url(https://pro.fontawesome.com/releases/v5.10.0/svgs/solid/times-circle.svg) no-repeat 50% 50%;
  background-size: contain;
  pointer-events: none;
}
input[type="search"]:not(:placeholder-shown):focus::-webkit-search-cancel-button {
  display: block;
  width: 1em;
  margin-left: .5em;
}

input[type="search"]:focus::-webkit-search-cancel-button {
  pointer-events: all;
}

input[type="search"].dark::-webkit-search-cancel-button {
  filter: invert(1);
}
<input type="search" placeholder="search search search search search search" class="light">
<input type="search" placeholder="search search search search search search" class="dark">
Izabela Furdzik
  • 511
  • 6
  • 8
  • Thanks. Is it possible not to show *a clear icon* when an input field is in focus, but there is no text provided by the user (therefore a placeholder is shown instead)? – Denis Kulagin Oct 31 '21 at 10:49
  • See my code snippet. It is working like that. – Izabela Furdzik Oct 31 '21 at 11:22
  • Please check https://jsbin.com/davaxew . If you click on the input field and it gets focused, the icon area (while the icon itself is invisible) pushes a placeholder text which is an undesired behavior. – Denis Kulagin Oct 31 '21 at 15:19
  • You were right, I am sorry. I corrected my original answer with desired output. Check it out :) – Izabela Furdzik Nov 01 '21 at 07:38
-1

I have checked you're issue and from my point of view the easiest way to solve the issue is the following:

input[type="search"]::-webkit-search-cancel-button {
display: none;
}

input[type="search"]:focus::-webkit-search-cancel-button {
display: block;
}

You should add those 2 lines to you're existing code and should be fine :)

Code is here : https://codepen.io/BaciuTudor/pen/YzxaYKV