- Inputs & CSS Pseudo Elements
- I was going somewhere with this…
- First the code
- Quick breakdown
- This is a silly hack
- In the end
- CSS Pseudo-elements
- Syntax
- The ::first-line Pseudo-element
- Example
- The ::first-letter Pseudo-element
- Example
- Pseudo-elements and HTML Classes
- Example
- Multiple Pseudo-elements
- Example
- CSS — The ::before Pseudo-element
- Example
- CSS — The ::after Pseudo-element
- Example
- CSS — The ::marker Pseudo-element
- Example
- CSS — The ::selection Pseudo-element
- Example
- All CSS Pseudo Elements
- All CSS Pseudo Classes
Inputs & CSS Pseudo Elements
In case you weren’t aware, an doesn’t allow ::before or ::after pseudo elements. None of the different input types do.
Why can’t you use these pseudo elements on inputs? Because these pseudo elements are only allowed to be used on container elements. Elements like inputs, images, and any other self closing element can’t use pseudo elements because they aren’t “container elements”. Meaning, they don’t allow any nested elements or content inside of them.
I was going somewhere with this…
Anyway, I was recently tasked with adding an icon to various call to action links / buttons on a website. The easiest way to do this was by replacing previous class name (which was still needed on some elements) for the new one. The new class using a ::before <> to position the icon on top of the existing button, which already had a set background.
However, a problem arose when some of the buttons that needed to be updated were elements. These elements couldn’t be changed to s, which would have allowed the pseudo element, due to styling overwrites / rewrites I would have had to make to buttons in general, and refactoring the code wasn’t an option at this time.
Hacking around with this some more, while I couldn’t modify the input element, I could wrap the input in other elements. This lead me to the following…
First the code
for="btn_cta" class="btn-icon"> type="submit" id="btn_cta" class="updated-btn-class" value="Submit" />
And some CSS to get the basic idea:
.btn-icon display: inline-block; position: relative; > .btn-icon::before background: url(/icon.png) no-repeat center center; background-size: 100% auto; height: 100%; left: 0; pointer-events: none; /* important */ position: absolute; top: 0; width: 2em; >
Quick breakdown
By wrapping the input in a span the submit button “acquires” the ability to have pseudo-elements.
Adding the pointer-events: none to the ::before pseudo-element makes sure that the icon doesn’t block mouse clicks or taps from reaching the input .
This is a silly hack
This method got me out of a pinch, but it is a hack and I really don’t recommend it unless you need to do quickly do something like this, and can go back and fix it later.
Why is this a hack? Because we have the element which can have pseudo-elements. I suppose this could be helpful for other text inputs that need an icon to be placed “within” the text field. But in many instances those icons are likely stand-ins for labels or other functional controls (e.g. show password or a search button). Those are “less hacky” use cases as they potentially serve functional purposes rather than being decorative only.
In the end
The proper solution to my initial problem was to convert all inputs that needed this icon to s. So, while I wanted to share this trick, my next order of business is to figure out a way to hack the source code and change the input to a button .
CSS Pseudo-elements
A CSS pseudo-element is used to style specified parts of an element.
For example, it can be used to:
- Style the first letter, or line, of an element
- Insert content before, or after, the content of an element
Syntax
The syntax of pseudo-elements:
The ::first-line Pseudo-element
The ::first-line pseudo-element is used to add a special style to the first line of a text.
The following example formats the first line of the text in all
elements:
Example
Note: The ::first-line pseudo-element can only be applied to block-level elements.
The following properties apply to the ::first-line pseudo-element:
- font properties
- color properties
- background properties
- word-spacing
- letter-spacing
- text-decoration
- vertical-align
- text-transform
- line-height
- clear
Notice the double colon notation — ::first-line versus :first-line
The double colon replaced the single-colon notation for pseudo-elements in CSS3. This was an attempt from W3C to distinguish between pseudo-classes and pseudo-elements.
The single-colon syntax was used for both pseudo-classes and pseudo-elements in CSS2 and CSS1.
For backward compatibility, the single-colon syntax is acceptable for CSS2 and CSS1 pseudo-elements.
The ::first-letter Pseudo-element
The ::first-letter pseudo-element is used to add a special style to the first letter of a text.
The following example formats the first letter of the text in all
elements:
Example
Note: The ::first-letter pseudo-element can only be applied to block-level elements.
The following properties apply to the ::first-letter pseudo- element:
- font properties
- color properties
- background properties
- margin properties
- padding properties
- border properties
- text-decoration
- vertical-align (only if «float» is «none»)
- text-transform
- line-height
- float
- clear
Pseudo-elements and HTML Classes
Pseudo-elements can be combined with HTML classes:
Example
The example above will display the first letter of paragraphs with in red and in a larger size.
Multiple Pseudo-elements
Several pseudo-elements can also be combined.
In the following example, the first letter of a paragraph will be red, in an xx-large font size. The rest of the first line will be blue, and in small-caps. The rest of the paragraph will be the default font size and color:
Example
p::first-letter <
color: #ff0000;
font-size: xx-large;
>
p::first-line color: #0000ff;
font-variant: small-caps;
>
CSS — The ::before Pseudo-element
The ::before pseudo-element can be used to insert some content before the content of an element.
The following example inserts an image before the content of each element:
Example
CSS — The ::after Pseudo-element
The ::after pseudo-element can be used to insert some content after the content of an element.
The following example inserts an image after the content of each element:
Example
CSS — The ::marker Pseudo-element
The ::marker pseudo-element selects the markers of list items.
The following example styles the markers of list items:
Example
CSS — The ::selection Pseudo-element
The ::selection pseudo-element matches the portion of an element that is selected by a user.
The following CSS properties can be applied to ::selection : color , background , cursor , and outline .
The following example makes the selected text red on a yellow background:
Example
All CSS Pseudo Elements
Selector | Example | Example description |
---|---|---|
::after | p::after | Insert something after the content of each element |
::before | p::before | Insert something before the content of each element |
::first-letter | p::first-letter | Selects the first letter of each element |
::first-line | p::first-line | Selects the first line of each element |
::marker | ::marker | Selects the markers of list items |
::selection | p::selection | Selects the portion of an element that is selected by a user |
All CSS Pseudo Classes
Selector | Example | Example description |
---|---|---|
:active | a:active | Selects the active link |
:checked | input:checked | Selects every checked element |
:disabled | input:disabled | Selects every disabled element |
:empty | p:empty | Selects every element that has no children |
:enabled | input:enabled | Selects every enabled element |
:first-child | p:first-child | Selects every elements that is the first child of its parent |
:first-of-type | p:first-of-type | Selects every element that is the first element of its parent |
:focus | input:focus | Selects the element that has focus |
:hover | a:hover | Selects links on mouse over |
:in-range | input:in-range | Selects elements with a value within a specified range |
:invalid | input:invalid | Selects all elements with an invalid value |
:lang(language) | p:lang(it) | Selects every element with a lang attribute value starting with «it» |
:last-child | p:last-child | Selects every elements that is the last child of its parent |
:last-of-type | p:last-of-type | Selects every element that is the last element of its parent |
:link | a:link | Selects all unvisited links |
:not(selector) | :not(p) | Selects every element that is not a element |
:nth-child(n) | p:nth-child(2) | Selects every element that is the second child of its parent |
:nth-last-child(n) | p:nth-last-child(2) | Selects every element that is the second child of its parent, counting from the last child |
:nth-last-of-type(n) | p:nth-last-of-type(2) | Selects every element that is the second element of its parent, counting from the last child |
:nth-of-type(n) | p:nth-of-type(2) | Selects every element that is the second element of its parent |
:only-of-type | p:only-of-type | Selects every element that is the only element of its parent |
:only-child | p:only-child | Selects every element that is the only child of its parent |
:optional | input:optional | Selects elements with no «required» attribute |
:out-of-range | input:out-of-range | Selects elements with a value outside a specified range |
:read-only | input:read-only | Selects elements with a «readonly» attribute specified |
:read-write | input:read-write | Selects elements with no «readonly» attribute |
:required | input:required | Selects elements with a «required» attribute specified |
:root | root | Selects the document’s root element |
:target | #news:target | Selects the current active #news element (clicked on a URL containing that anchor name) |
:valid | input:valid | Selects all elements with a valid value |
:visited | a:visited | Selects all visited links |