Is it possible to apply a :before or :after pseudo-element to an input field element?

I'm having trouble incorporating the :after CSS pseudo-element on an input field. It seems to be working fine with a span, but not with the input field.

<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>

The following code snippet works as expected (places the smiley face after "buu!" and before "some more"):

<span class="mystyle">buuu!</span>a some more

However, the next code snippet does not work - it only changes the color of "someValue" to red without displaying the smiley face:

<input class="mystyle" type="text" value="someValue">

I'm wondering what I might be doing incorrectly. Should I be using a different pseudo-selector?

It's worth noting that I am unable to wrap my input in a span because it is generated by a third-party control.

Answer №1

:before and :after appear inside a designated area

However, the element <input> is unable to contain additional elements.


Pseudo-elements are specifically designed to be applied to container elements only because they are rendered as child elements within the container itself. Since an input element cannot house other elements, it does not support pseudo-elements. On the other hand, a button, which is also a form element, can support them since it serves as a container for multiple sub-elements.

In cases where some browsers do display these pseudo-elements on non-container elements, it should be considered a bug and a deviation from standard compliance. The specification clearly outlines the intended behavior around element content...

W3C specification

Upon careful review of the official W3C specification, it states that these elements are placed inside a containing element:

Authors define the style and placement of generated content using the :before and :after pseudo-elements. As indicated by their names, these pseudo-elements determine the location of content before and after the document tree content of an element. The 'content' property, in conjunction with these pseudo-elements, dictates what will be inserted.

It is evident from this explanation that the generated content appears within a specific container.

Answer №2

:after and :before won't work on Internet Explorer 7 and below for any elements.

They're also not meant for use on replaced elements like form elements (inputs) and image elements.

In simple terms, achieving this with just CSS is impossible.

However, if you use jQuery, you can do this:

$(".mystyle").after("add your smiley here");

Check out the API docs on .after for more information.

To add your content using JavaScript. This method will work on all browsers.

Answer №3

Interestingly, certain types of input seem to function properly. Especially in the realm of Chrome,

<input type="checkbox" />

work flawlessly, much like

<input type="radio" />

It appears that only type=text and a few others encounter issues.

Answer №4

Here's a different method (assuming you are able to modify the HTML): include an empty <span></span> directly after the input field, and style it using CSS with input.mystyle + span:after

.field_with_errors {
  display: inline;
  color: red;
}
.field_with_errors input+span:after {
  content: "*"
}
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
  <input type="text" /><span></span> 
</div>

I employ this strategy in AngularJS as it automatically adds the .ng-invalid classes to <input> form elements and the form itself, but not to the <label>.

Answer №5

:before and :after can be utilized within a container, allowing for their application to elements with an end tag.

This does not hold true for self-closing elements.

It is worth noting that self-closing elements (such as img/hr/input) are also referred to as 'Replaced Elements', as they get substituted with their corresponding content. They are essentially "External Objects". For more information, visitthis link.

Answer №6

A common misconception lies in the interpretation of the terms before and after. These words do not pertain to the element itself, but rather to the content within the element. This means that element:before refers to content before it, and element:after pertains to content after it, while still being contained within the original element.

The input element lacks content from a CSS perspective, resulting in no :before or :after pseudo content. Similarly, this applies to other void or replaced elements as well.

It's important to note that there isn't a pseudo element that references anything outside the element.

In an alternate reality, these pseudo elements might have been named differently to avoid confusion. It is also conceivable that there could be a pseudo element that exists outside the element itself. However, at present, such a scenario does not exist in our current universe.

Answer №7

To indicate required fields, I utilized the background-image property to create a red dot.

input[type="text"][required] {
  background-image: radial-gradient(red 15%, transparent 16%);
  background-size: 1em 1em;
  background-position: top right;
  background-repeat: no-repeat
}

Check out the snippet below for a demonstration:

body {
  background-color: rgb(0,159,214);
  font: normal 1em Helvetica,Arial;
  padding: 2em;
}
input[type="text"], textarea {
  background-color: #eee;
  border: none;
  border-radius: .125em;
  display: block;
  font: inherit;
  font-size: 1.5em;
  line-height: 2em;
  margin: .5em auto;
  padding: 0 .5em;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  width: 50%;
}
input[type="text"][required] {
  background-image: linear-gradient(45deg, transparent, transparent 50%, red 50%, red 100%);
  background-position: top right;
  background-size: .5em .5em;
  background-repeat: no-repeat;
}
textarea[required] {
  background-image: radial-gradient(red 20%, transparent 25%);
  background-size: 1em 1em;
  background-position: top right;
  background-repeat: no-repeat
}
<input type="text" placeholder="Required" required>

<textarea placeholder="Required" required></textarea>

Alternatively, you can also View on Codepen

Answer №8

While you can't insert a pseudo element inside an input element, you can utilize a shadow element such as a placeholder instead!

input[type="text"] {   
  &::-webkit-input-placeholder {
    &:before {
      // your code
    }
  }
}

To extend this functionality to other browsers, incorporate :-moz-placeholder, ::-moz-placeholder and :-ms-input-placeholder within separate selectors. Avoid grouping the selectors, as an unrecognized selector by a browser could invalidate the entire statement.

UPDATE: The provided code is tailored for CSS preprocessors (SASS, LESS...). For non-preprocessed stylesheets, use:

input[type="text"]::-webkit-input-placeholder:before { // your code }

Answer №9

An effective CSS-only solution:

The key is to assume that there is a DOM element placed immediately after the text field.

/*
 * The magic happens here:
 * This selector targets the first DOM element following
 * the input text and sets its content before it (:before).
 */
input#myTextField + *:before {
  content: "👍";
} 
<input id="myTextField" class="mystyle" type="text" value="someValue" />
<!--
  There must be something following an input text field,
  whatever it may be.
  -->
<span></span>

(*) Keep in mind these limitations:

  • You need to rely on having a subsequent DOM element,
  • You need to ensure no other input fields come after yours.

In most cases, this method proves efficient and eliminates any jQuery dependency with 100% CSS utilization.

Answer №10

After encountering the same issue, I stumbled upon this post which provided me with a helpful solution. Instead of replacing the input's value, the suggestion is to remove it and position a span behind it that matches the size. This span can also have a :before pseudo class applied to it along with an icon font of your choice.

<style type="text/css">

form {position: relative; }
.mystyle:before {content:url(smiley.gif); width: 30px; height: 30px; position: absolute; }
.mystyle {color:red; width: 30px; height: 30px; z-index: 1; position: absolute; }
</style>

<form>
<input class="mystyle" type="text" value=""><span class="mystyle"></span>
</form>

Answer №11

In the question, there is a mention of an "input field." While it seems like the original poster was specifically referring to input fields with type=text, it's worth noting that ::after and ::before pseudo elements can also render for various other types of input fields:

input::before {
    content: "My content" /* 11 different input types will display this */
}    

For a comprehensive demonstration showcasing all input types and clearly indicating which ones are compatible with the ::before pseudo element in this case, check out this extensive demo.

To recap, here is a list of all input types capable of rendering pseudo content:

  1. checkbox
  2. color
  3. date
  4. datetime-local
  5. file
  6. image
  7. month
  8. radio
  9. range
  10. time
  11. week

Answer №12

Like others have pointed out, input elements act as void elements and most browsers do not support the use of ::before or ::after pseudo-elements within them.

However, there are discussions within the CSS Working Group about potentially allowing the usage of ::before and ::after on input elements with appearance: none.

A thread on this topic can be found at ,

Safari and Chrome currently support pseudo-elements on form inputs, while other browsers do not. Although there was consideration to remove this feature, it is still being used on approximately 0.07% of pages, which exceeds our removal threshold by 20 times.

To define specifications for pseudo-elements on inputs, it would require detailing the internal structure of inputs to some extent, which has not been accomplished yet (and may not be feasible). However, Boris suggested in a bug report discussion that allowing it on inputs with appearance:none could essentially treat them as <div>s instead of "kinda-replaced" elements.

Answer №13

As mentioned in a note within the CSS 2.1 specification, the interaction of :before and :after pseudo-elements with replaced elements like IMG in HTML is not fully defined. It is stated that this will be addressed more thoroughly in a future iteration of the specification. Even though input is no longer considered a replaced element, the ambiguity surrounding the effects of :before and :after on it persists.

To overcome this issue, it is advisable to explore alternative strategies for resolving the problem at hand. Embedding generated content into a text input control could potentially mislead users as it may seem like part of the default value yet remain unchangeable. This leads to confusion where the content seems mandatory but does not actually get submitted along with form data.

Answer №14

Check out what to do next:

label[for="userName"] {
  position: relative;
}

label[for="userName"]::after {
  content: '[after]';
  width: 22px;
  height: 22px;
  display: inline-block;
  position: absolute;
  right: -30px;
}
<label for="userName">
Name:
<input type="text" name="userName" id="userName">
</label>

Answer №15

To utilize a before or after pseudo-element, it is necessary to have some sort of wrapper around the input element. A workaround for this involves using a before pseudo-element on the wrapper div of an input and positioning it inside the input. While unconventional, this method can prove effective in certain situations, especially when responsiveness is a priority. If needed, the before pseudo-element can easily be modified to an after pseudo-element for inserting different content.

See the Example in Action

Implementing a dollar sign inside an input as a pseudo-element: http://jsfiddle.net/kapunahele/ose4r8uj/1/

The HTML Structure:

<div class="test">
    <input type="text"></input>
</div>

The CSS Styling:

input {
    margin: 3em;
    padding-left: 2em;
    padding-top: 1em;
    padding-bottom: 1em;
    width:20%; 
}

.test {
    position: relative;
    background-color: #dedede;
    display: inline;
}

.test:before {
    content: '$';
    position: absolute;
    top: 0;
    left: 40px;
    z-index: 1;
}

Answer №16

If you're attempting to customize the appearance of an input element using :before and :after, chances are you're aiming to replicate the styles of other span, div, or anchor elements within your CSS layout.

It's worth noting that as mentioned in Robert Koritnik's response, :before and :after pseudo-elements can only be used on container elements, and input elements do not qualify as containers.

However, with the introduction of HTML 5, the button element can serve as a container and function similarly to an input[type="submit|reset"] element.


    <style>
    .happy:after { content:url(smiley.gif); }
    </style>

    <form>
    <!-- won't work -->
    <input class="happy" type="submit" value="Submit" />

    <!-- works -->
    <button class="happy">Submit</button>
    </form>

Answer №17

:before and :after are specifically designed for elements that have the ability to contain child nodes, as they add a new node either before or after the existing content.

Answer №18

Although it has been pointed out that Firefox does not allow ::after and ::before content for elements that cannot display any content, an interesting workaround has been found:

input[type=checkbox] {
    -moz-appearance: initial;
}

Using ::after is the only way to restyle a checkbox or radiobox without adding extra markup like a span or label. Despite this not being in line with official specifications, some users find it acceptable to force Firefox to display ::before and ::after content.

Answer №19

Here is a technique I discovered to achieve this style:

.submit .btn input
{
   padding:11px 28px 12px 14px;
   background:#004990;
   border:none;
    color:#fff;
}

 .submit .btn
 {
     border:none;
     color:#fff;
     font-family: 'Open Sans', sans-serif;
     font-size:1em;
     min-width:96px;
     display:inline-block;
     position:relative;
 }

.submit .btn:after
{
    content:">";
    width:6px;
    height:17px;
    position:absolute;
    right:36px;
    color:#fff;
    top:7px;
}
<div class="submit">
  <div class="btn">
     <input value="Send" type="submit" />
  </div>
</div>

To achieve the desired outcome, make sure the parent div takes on the padding and the :after pseudo-element. The first parent should be set to relative positioning while the second div must be absolute positioned to accurately place the after element.

Answer №20

Overview

This code snippet is designed to enhance the appearance of input elements on a webpage. It specifically targets the <input> element with type "submit" and adds a decorative border around it, as well as a checkmark inside a checkbox element.

Demo: Check out the live example here

Markup:

<p class="submit">
    <input id="submit-button" type="submit" value="Post">
    <br><br>
    <input id="submit-cb" type="checkbox" checked>
</p>

Styling:

#submit-button::before,
#submit-cb::before {
    content: ' ';
    background: transparent;
    border: 3px solid crimson;
    display: inline-block;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: -3px -3px;
}

Answer №21

Illustration of a switcher with before and after effects simply enclose your input within a div block

.fm-form-control {
  position: relative;
  margin-top: 25px;
  margin-bottom: 25.2px;
}


.fm-switcher {
  display: none;
}
.fm-switcher:checked + .fm-placeholder-switcher:after {
  background-color: #94c6e7;
}
.fm-switcher:checked + .fm-placeholder-switcher:before {
  left: 24px;
}
.fm-switcher[disabled] + .fm-placeholder-switcher {
  cursor: not-allowed;
}
.fm-switcher[disabled] + .fm-placeholder-switcher:before {
  background-color: #cbd0d3;
}
.fm-switcher[disabled] + .fm-placeholder-switcher:after {
  background-color: #eaeded;
  border-color: #cbd0d3;
}

.fm-placeholder-switcher {
  padding-left: 53px;
  cursor: pointer;
  line-height: 24px;
}
.fm-placeholder-switcher:before {
  position: absolute;
  content: '';
  left: 0;
  top: 50%;
  width: 20px;
  height: 20px;
  margin-top: -10px;
  margin-left: 2px;
  background-color: #2980b9;
  z-index: 2;
  -moz-transition: all 0.15s ease-in-out;
  -o-transition: all 0.15s ease-in-out;
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
  border-radius: 12px;
}
.fm-placeholder-switcher:after {
  position: absolute;
  content: '';
  left: 0;
  top: 50%;
  width: 48px;
  height: 20px;
  margin-top: -12px;
  background-color: #ffffff;
  z-index: 1;
  border-radius: 12px;
  border: 2px solid #bdc3c7;
  -moz-transition: all 0.15s ease-in-out;
  -o-transition: all 0.15s ease-in-out;
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
}
<div class='fm-form-control'>
  <input class='fm-switcher' id='switcher_id' type='checkbox'>
  <label class='fm-placeholder-switcher' for='switcher_id'>
    Switcher
  </label>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Obtaining a link to a Wordpress post

How can I fix the 403 ERROR when trying to display a post thumbnail and direct the user to that post in PHP? I'm new to programming and unsure of what is causing this issue. PHP <?php query_posts('cat=5'); while (have_posts()) : the_pos ...

The text area in iOS 11 Safari's bootstrap modal is positioned off-center from the cursor

When using Safari with iOS 11, I noticed that the input textbox cursor is appearing outside of the input textbox. This issue is specific to iOS 11 Safari and we are unsure why it is happening. As shown in the image, the cursor is not within the email input ...

Jquery bypasses original stylesheet settings when inline styles are removed

I have a CSS file with various styles defined within it. One style in particular has the property position set to 'fixed', but this only applies to specific combinations of classes. For example: .mystyle.blue { position: fixed; } Here, el ...

Basic JavaScript Calculator Utilizing JQuery

I have been diligently working on a Javascript Calculator for quite some time now. The CSS and HTML elements seem to be in order. However, the calculator is only functioning properly for sevens and division operations! While the input for other numbers g ...

What is the best way to determine if my table does not have any data stored in

Is there a way to detect when my table is empty so that I can display an error message rather than showing an empty table? Here's the code snippet in question: <?php $search = $_REQUEST['search']; if ($search == "") { echo "Please e ...

Track every click on any hyperlink throughout the entire webpage

I am attempting to capture any click event on a link throughout the entire page. For example, when a user clicks on the following link: <a href="/abc">abc<a/> I want to be able to retrieve the anchor tag like so: <span hre="/abc">abc& ...

Ways to specifically select an element based on its type and class

I am struggling to create a vanilla JS function that will resize fonts in a container with a specified class. I came across this demo, which seemed promising. However, the 'Javascript' version uses the $() jquery selector to target elements, maki ...

Utilizing Cascading Style Sheets for customizing a numbered list

I am looking to create HTML that will generate the following output: OL { counter-reset: numeric } OL LI OL LI OL { counter-reset: latin } LI { display: block } LI:before { content: counters(numeric, ".") " "; counter-increment: numer ...

"Enhance your listening experience with an audio player featuring album covers as captivating

Is there a way to create an audio player with the album cover image serving as the background, while ensuring all control buttons are displayed on top of that same image? I attempted using the following code snippet: <audio controls = 'controls&ap ...

Animating or transitioning CSS keyframes to an inline value when the page is initially loaded

In my current project, I am working on creating HTML and CSS-based bar representations of percentage values. The structure of the code is as follows: Using HTML: <div class="chart"> <div class="bar" style="width:43%"></div> </div&g ...

Enhancing an element with a modifier in CSS using BEM conventions without the need for @extend

Trying to grasp the best method for writing BEM modifier rules within parent classes. I've utilized SASS's @extend but question if this is the right approach. For example: If there is a class called .form structured like this: <div className= ...

Is there a problem with Chrome's display?

I'm currently using Chrome version 53.0.2785.143 and have noticed a rendering issue that tends to occur more frequently within my application when utilizing CSS transform scale. Feel free to check out this JSFiddle link which demonstrates the problem ...

Combination of words & design having "background-image:url"

Currently utilizing Thymeleaf within a Spring Boot project, the following code initializes an image in the center of the screen (sourced from this .html ): <div class="col-lg-9 image_col order-lg-2 order-1"> <div class="single_product_image"& ...

Guide to setting up a horizontal button menu and dropdown submenu beneath the navigation bar using Bootstrap 4

How can I design a horizontal button menu with submenus below the navigation bar in Bootstrap 4? Take a look at the image below to see what I'm aiming for: https://i.sstatic.net/j6b8a.png https://i.sstatic.net/rmtrM.png If you have any ideas or su ...

Create a scrollable horizontal list of items

I am encountering an issue with my mat chip list in Angular Material. I have a mat chip list filled with mat-chips that I want to display in a single row. If there are more items than can fit on the screen, I would like the area to be scrollable horizonta ...

Guide on inserting text input value into the href attribute of a hyperlink

Lately, I've been facing an issue that has been troubling me for the past few hours. I have a search input field where users can enter text and click send. The entered text should then be added to the href attribute and sent to the results page for qu ...

Where exactly is Bootstrap hiding?

Currently, I am in the process of working on a web application using Spring. My goal is to set up a bootstrap test table for the application and apply different themes to it. However, I am facing an issue where Bootstrap seems to be missing. I'm unsur ...

How can I disable the submit button when there is a change in the form input fields using PHP?

I am looking to disable a button that will submit my form if the fields are not changed. So, if I change a field, I would like to be able to submit the form by enabling the button, but only if at least one field is changed. <?php $listeToitures = $db- ...

The request for data:image/png;base64,{{image}} could not be processed due to an invalid URL

I am facing an issue with converting image data that I receive from the server using Angular.js for use in ionic-framework. Here is the code snippet I have been working with: $http.post(link, { token: token, reservationCode: reservatio ...

What is the best method for displaying the toggle button for Drawer/Sidebar above the main content and appbar?

After reviewing Vatsal's suggestion, it appears that moving the toggle button above the drawer is the solution to our main issue. By taking advantage of the open state of the drawer, we can adjust the left property of the button in the toggleButton cl ...