Imagine you are building a simple search form, where a user types their search into an input box, and then clicks the search button to search.

Here's some sample HTML for the search form:

<input placeholder="Search..."> <button>Search!</button>

Note that the search button should only be clickable when something has actually been typed into the search box. You wouldn't want someone searching an empty string, right?

The JavaScript Way

Ordinarily, some quick JavaScript can be used to do this, for example:

inputElement.oninput = function(e) { if(inputElement.value != "") { activateSearchButton(); } else { deactivateSearchButton(); } };

The Cool-CSS-Trick Way

In my opinion, there's a more optimal way to accomplish this, without Javascript, using the :not(:placeholder-shown) CSS pseudo class. There are two parts of the pseudo class: :not() and :placeholder-shown .

:placeholder-shown — is active when the placeholder in an input box is shown. When the input box is empty, the placeholder will be shown, and when the user types something in, the placeholder won't be shown.

— is active when the placeholder in an input box is shown. When the input box is empty, the placeholder will be shown, and when the user types something in, the placeholder won't be shown. :not() — takes an argument of what selector(s) the style should not apply to.

So, :not(:placeholder-shown) simply means applying a style to an input element when the placeholder isn't shown; meaning that styles will only apply when the input box isn't empty.

We can combine this with the + CSS operator to make our search button functionality:

button { display: none; } input:not(:placeholder-shown) + button { display: block; }

Here, the button will only display when the input has content, which works exactly like the JavaScript version, just... without JavaScript.

Another Interesting Way to Use This

We can also combine this with the :focus pseudo class so that a style is only applied when the user is typing within an input box, like this:

<input type="text" placeholder="type something"> <p id="otherElement">You are typing</p>

#otherElement { display: none; } input:focus:not(:placeholder-shown) + #otherElement { display: block; }

Conclusions

This is a pretty neat trick in general, and has actually been really useful for me when building search forms, login forms, and the like. I hope you enjoyed this post, and find this CSS trick effective.

Note that the JavaScript code referenced at the beginning of this post will not work without necessary variable definitions, and that the :not(:placeholder-shown) pseudo class may not work on some web browsers, especially at the time of reading. I personally recommend checking for browser compatibility before implementing a feature in an app or website.

Thanks for scrolling.

— Gabriel Romualdo, October 2, 2019