Explain Codes LogoExplain Codes Logo

Can I use a :before or :after pseudo-element on an input field?

html
responsive-design
css
accessibility
Alex KataevbyAlex KataevΒ·Jan 31, 2025
⚑TLDR

Sorry for the buzzkill, but input fields don't play well with :before or :after. Plan B: A wrapper div is our knight in shining armor:

<div class="input-icon"> <input type="text" /> </div>
.input-icon::before { content: 'πŸ”Ž'; /* Sherlock Holmes, anyone? */ /* Position it like a selfie in a mirror */ }

Next step, add some bling to .input-icon to mimic an input field's aura.

The "why" behind input's cold shoulder to pseudo-elements

Input elements are the rebellious kids of HTML family. Being replaced elements, these folks keep their content's look-n-feel under their hats, letting the browser (user agent) call the shots. These pseudo-elements :before and :after aim to tweak content, but hit the wall with <input> fields.

Let's crack some alternatives for jazzing up input fields

Next up, we're battling limitations and turning them into opportunities for a jazzier <input>.

Embracing adjacent sibling selectors

We can pull a sibling card with CSS + to target your <input>'s next of kin:

<input type="text" id="search" /> <span></span>
#search + span::after { content: 'πŸ”Ž'; /* When Sherlock goes undercover */ }

When you want the added content outside the box but still visually tied to input, this move is your best bet.

Cozying up with label elements

Being a bit old school, we can also use label with for attribute hitched to the input's id:

<label for="search" class="input-label">Search:</label> <input type="text" id="search"/>
.input-label::after { content: 'πŸ”'; /* Your search warrant is served! */ }

It's a win-win as it amps up accessibility and pulls a semantic link between the label and input.

Button play

For a game-changer, a button accepts pseudo-elements like a boss:

<button type="submit" class="search-button"> Search </button>
.search-button::before { content: 'πŸ”'; /* Button playing detective now */ }

This lets the button showoff icons or additional content like a pro, before or after the visible text.

Getting fancy with some real-world cases

Now let's get down and dirty with some real-world scenarios and tweak them to our advantage.

Handling checkboxes and radios

Breaking news: Pseudo-elements do put up a show with checkbox and radio. Not with type="text" though.

input[type="checkbox"] + label::before { content: 'βœ”'; /* Checkmate! */ }

Vous pouvez style an associated label with pseudo-content. Here's your golden ticket for a custom checkbox and radio inputs!

Considering background images

Sometimes, dressing up the input field's background with an icon does the trick:

input[type="text"] { background-image: url('search-icon.png'); background-repeat: no-repeat; padding-left: 20px; /* Adjust to avoid your text photobomb it */ }

Say hello to a method that shows the exit door to pseudo-elements while nailing their job visually.

Leveling up compatibility & considering polyfills

In this game of styling workaround thrones, mind the cross-browser support. Good compatibility is expected from ::before and ::after, but tripwires like IE7 need caution. For such highlights, a JavaScript polyfill might enter the arena for the rescue.

AngularJS: A different ballgame

If your bag is the AngularJS or similar frameworks, input + span:after can hit it out of the park with form validation styles, and indicators for errors or valid inputs.

The lowdown on replaced elements

To crack the cryptic logic of replaced elements, consider the deep dive into the CSS Replaced Elements Documentation. Turn the page to discover browser plays on elements like <input>, <textarea>, <video>, and many more.