CSS's ::before
and ::after
pseudo-elements allow you to use any non-replacement elements (for example, they are suitable for<div> But not applicable<code><img alt="7 Practical Uses for the ::before and ::after Pseudo-Elements in CSS" >
) Insert "content" before and after. This actually allows you to display content on a webpage that may not exist in HTML content. You shouldn't use it for actual content because it's not so good in terms of accessibility, because you can't even select and copy text that is inserted on the page in this way - it's just decorative content. In this article, I'll walk you through seven different examples that show how to create interesting effects using ::before
and ::after
.
Note that for most examples, I only explain the code sections that are particularly relevant to the CSS pseudo-elements. That is, if you want to see other styles of code, all CSS is included in the embedded demo.
When users visit your website, their internet connection (or factors beyond your control) may prevent your image from being downloaded, so the browser displays corrupted image icons and alternative text for the image (if it does exist).
How to use custom placeholders instead? You can do this using ::before
and ::after
and some CSS positioning.
First, we need to use relative positioning on image elements. We will use absolute positioning on one of the pseudo-elements later, so this relative position ensures that the pseudo-element is within the contents of the image element, rather than being completely out of the document stream.
img { display: block; /*Avoid space below the image caused by row height*/ position: relative; width: 100%; }
Next, let's use the ::before
pseudo-element of the image to create an area that corrupts the image effect. We will first style it with a light gray background and a slightly darker border.
img::before { background-color: hsl(0, 0%, 93.3%); border: 1px dashed hsl(0, 0%, 66.7%); /* ... */ }
<img alt="7 Practical Uses for the ::before and ::after Pseudo-Elements in CSS" >
is a replacement element. Why use ::before
pseudo-element on it? It doesn't work! correct. In this case, when the image fails to load, the pseudo-element will be displayed in Chrome and Firefox, which is exactly what you want. Meanwhile, Safari only displays the styles applied to alternative text.
The style applies to the upper left corner of the corrupted image.
So far, everything went well. Now we can set it to a block-level element ( display: block
) and give it a height to fill the entire available space.
img::before { /* ... */ display: block; height: 100%; }
We can further improve the style. For example, let's round the corners. We should also leave some space for the alternative text by providing full width and absolute positioning for pseudo-elements to better control over the placement of the content where we want it.
img::before { /* ... */ border-radius: 4px; content: ""; position: absolute; width: 100%; }
If you stop here and check your work, you may scratch your head because the alternative text suddenly disappears.
This is because we set content
to an empty string (we need to display the content and styles we generated) and overwrite the entire space, including the actual alternative text. It's there, we just can't see it.
We can display the alternative text by substitution (get it?), this time with the help of the ::after
pseudo-element. content
attribute can actually use attr()
function to display alt
attribute text of the image:
img::after { content: attr(alt); /*Some simple styles*/ font-weight: bold; position: absolute; height: 100%; left: 0px; text-align: center; top: 1px; width: 100%; }
This is awesome! At least in Chrome.
However, this is not the case in Firefox.
A quick workaround is to use the property selector (in this case img[alt]
) to directly locate the alt
attribute and position similar styles there to match Chrome.
img[alt] { text-align: center; font-weight: bold; color: hsl(0, 0%, 60%); }
Now we have an excellent placeholder consistent in Chrome and Firefox.
Block citations are citations or excerpts from works. They also provide a very good opportunity to break a wall of text with visually interesting content.
There are various ways to style block references. Chris has a five-style set that dates back to 2007.
I want to look at another technique, one that combines ::before
and ::after
. As we saw in the previous example, we can use content
property to display the generated content and apply other properties to decorate it. Let's put large quotes at the beginning and end of the block reference.
HTML is simple:
<blockquote> </blockquote>
Some decorations in CSS:
blockquote { font-style: italic; line-height: 1.618; font-size: 1.2em; width: 30em; position: relative; padding: 40px 80px; }
Note position: relative
in it, because as you will learn, it is crucial for positioning block references.
As you might guess, we will use ::before
for the first quote and ::after
for the end quote. Now we can simply call content
property on both and generate the tag in it. However, CSS provides us with open-quote
and close-quote
values.
blockquote::before { content: open-quote; /*Place it in the upper left corner*/ top: 0; left: 0; } blockquote::after { content: close-quote; /*Place it in the lower right corner*/ bottom: 0; right: 0; }
This gives us the quotes we want, but I allow me to sort out the styles a little:
blockquote::before, blockquote::after { background-color: #cccccccc; display: block; width: 60px; height: 60px; line-height: 1.618; font-size: 3em; border-radius: 100%; text-align: center; position: absolute; }
We have order in HTML (<ol></ol>
) and disorder (<ul></ul>
) List. Both have default styles determined by the browser user agent stylesheet. However, using ::before
pseudo-element, we can override these "default" styles with our own content. Guess what? We can use emojis (?) on content
property!
.name-list li::before { content: "?"; margin-right: 15px; font-size: 20px; }
While this is good, it is worth noting that we can actually use ::marker
pseudo-element, which is specifically used to style list markers. Eric Meyer shows us how it works, which may be a better approach in the long run.
One of the cleverest tricks to style a form is to create toggle switches using the standard HTML checkbox. In fact, Preethi Sam recently shared a way when showing some other checkbox style tips using CSS masks.
As the name implies, the toggle switch is used to toggle or switch the selected and unselected states of check box elements.
<label> <input type="checkbox"> </label>
All customizations are due to being added to the ::before
and ::after
pseudo-elements<label></label>
Modification of elements. But first, here are some<label></label>
Basic CSS for elements:
.container { background: #212221; background: linear-gradient(to right, #1560bd, #e90); border-radius: 50px; height: 40px; position: relative; width: 75px; }
We will hide the default appearance of the checkbox while taking up all space. Strange? It is invisible, but technically still exists. We do this by:
input { -webkit-appearance: none; /* Safari */ cursor: pointer; /*Show it is an interactive element*/ height: 100%; position: absolute; width: 100%; }
Now let's use its ::before
pseudo-element settings<input>
Style of elements. This style will change the appearance of the input, bringing us closer to the final result.
input::before { background: #ffff; border-radius: 50px; content: ""; height: 70%; position: absolute; top: 50%; transform: translate(7px, -50%); /*Move style to the center of the element*/ width: 85%; }
What, wait? You might think that ::before
does not work with replacement elements, e.g.<input>
. This is correct, but only if the input type is an image, this is equivalent to<img alt="7 Practical Uses for the ::before and ::after Pseudo-Elements in CSS" >
element. Other form controls (such as check boxes) are defined as non-replacement elements in the HTML specification.
Next, we need to create the "Toggle" button, which happens that we can still create using the ::after
pseudo-element. However, there are two points worth mentioning:
transform
property to move to<input>
the center of .input::after { background: linear-gradient(to right, orange, #8e2de2); border-radius: 50px; content: ""; height: 25px; opacity: 0.6; position: absolute; top: 50%; transform: translate(7px, -50%); transition: all .4s; width: 25px; }
Try clicking the toggle button. Nothing happened. This is because we didn't actually change<input>
selected status. Even if we change it, the result is…unpleasant.
The solution is to apply the :checked
property to<input>
:: ::after
pseudo-element. By specifically positioning the selected state of the checkbox and linking it to the ::after
pseudo-element, we can move the toggle button back to its original position.
input:checked::after { opacity: 1; transform: translate(170%, -50%); }
We can decorate images with borders to make them stand out or blend more seamlessly into the design. Did you know we can use gradients on borders? Well, we can use ::before
(and of course there are other ways).
The core idea is to create a gradient on the image and use the CSS z-index
attribute and negative values. Negative values pull the gradient below the image in stacking order. This means that the image is always displayed on top as long as the gradient has a negative z-index
.
.gradient-border::before { /*Give style*/ content: ""; /*Fill the entire space*/ position: absolute; top: 0; left: 0; bottom: 0; right: 0; /*Create gradient*/ background-image: linear-gradient(#1a1a1a, #1560bd); /*Stack the gradients behind the image*/ z-index: -1; } figure { /*Delete the default margin*/ margin: 0; /*Squeeze the image to display the gradient behind it*/ padding: 10px; }
This is similar to what we did in the previous example, but here we are applying a gradient at the top of the image. Why do we do this? It can be a great way to add some texture and depth to the image. Alternatively, if there is text on the top that requires extra contrast to improve readability, it can be used to brighten or darken the image.
While this is similar to what we just did, you will notice some obvious differences:
figure::before { background-image: linear-gradient(to top right, #1a1a1a, transparent); content: ""; height: 100%; position: absolute; width: 100%; }
Have you seen it? There is no z-index
as it is OK to stack gradients on top of the image. We also introduce transparency into the background gradient, which allows the image to be displayed through the gradient. You know, like superposition.
Most, if not all, we try to customize the default style of HTML radio buttons, which is usually done with ::before
and ::after
, just like we did with checkboxes before.
We first set some basic styles, just to prepare:
/*Center all content*/ .flex-center { align-items: center; display: flex; justify-content: center; } /*Style of form element*/ .form { background: #ccc; height: 100vh; width: 100%; } /*Entered style*/ .form-row { background: #ffff; border-radius: 50px; height: 40px; margin: 10px; overflow: hidden; position: relative; width: 150px; }
Now let's use appearance: none;
to delete the default style of the radio button:
.form-input { -webkit-appearance: none; /* Safari */ appearance: none; }
::before
should be in the upper left corner of the radio button, and when selected, we will change its background color.
.form-input::before { /*Give style*/ content: ''; /*Show it is interactive*/ cursor: pointer; /*Position it to the upper left corner of the input*/ position: absolute; top: 0; left: 0; /*Occupy the entire space*/ height: 100%; width: 100%; } /*When the input is selected...*/ .form-input:checked::before { /*Change background color*/ background: #21209c; }
We still need to use ::after
to solve some problems. Specifically, when the radio button is selected, we want to change the color of the circular ring to white because in its current state the ring is blue.
.form-input::after { /*Give style*/ content: ''; /*Show it is interactive*/ cursor: pointer; /*Some border styles*/ border-radius: 50px; border: 4px solid #21209c; /*Positioning Ring*/ position: absolute; left: 10%; top: 50%; transform: translate(0, -50%); /*Set size*/ height: 15px; width: 15px; } /*When the input is selected...*/ .form-input:checked::after { /*Change the border of ::after to white*/ border: 4px solid #ffffff; }
The form tag is still unavailable here. We need to directly locate the form label to add the color, and when the form input is selected, we change the color to the visible color.
.form-label { color: #21209c; font-size: 1.1rem; margin-left: 10px; }
Click the button and there is still nothing to react. What's going on? position: absolute
on ::before
and ::after
obscures the content when the radio button is selected, because anything that occurs in the HTML document hierarchy is obscured unless they are moved to a new location in the HTML document, or their location has been changed using CSS. Therefore, each time a radio button is selected, its label is overwritten.
You probably already know how to solve this problem, because we solved a similar problem in another example before? We apply z-index: 1
(or position: absolute
) to form tags.
.form-label { color: #21209c; font-size: 1.1rem; margin-left: 10px; z-index: 1; /*Make sure the labels are stacked on top*/ /* position: absolute; This is an alternative option*/ }
We've covered seven different ways to create interesting effects using ::before
and ::after
pseudo-elements, customize default styles, make useful placeholders, and add borders to images.
We are by no means covering all the possibilities that can be unlocked when leveraging these other elements that can be selected using CSS. However, Lynn Fisher has made it a hobby, using a single element to create amazing designs. And let's not forget Diana Smith's CSS art, which uses pseudo-elements in multiple places for realistic painting effects.
The above is the detailed content of 7 Practical Uses for the ::before and ::after Pseudo-Elements in CSS. For more information, please follow other related articles on the PHP Chinese website!