Cool things you can do with ::before and ::after
(Originally posted on https://dev.to/debadeepsen/cool-things-you-can-do-with-before-and-after-9m9)
It's nice to know about the pseudo-elements ::before
and ::after
, because there's a whole lot of styling you can do with them. The main advantage of these pseudo-elements is that they are already existing children of the elements you want to style, so you don't have to introduce any more element into the DOM, keeping your HTML cleaner. So, instead of
<div class="element">
<div class="inner"></div>
Actual content of this element
</div>
<style>
.inner {
/* something */
}
</style>
You can do this -
<div class="element">
Actual content of this element
</div>
<style>
.element::before {
/* something */
}
</style>
Both of these behave according to the box model of CSS when styled, and can be moved around inside their parent (or outside) using the position
attribute and by setting the left
, right
, top
, or bottom
values. They can have their own width
, height
, and background
too.
Armed with that knowledge, let us see examples of some neat styling features that you can achieve with them. I'm not going to explain too much, everything is in its own CodeSandbox, feel free to launch them and explore the code. If you have questions feel free to ask in the comments.
::before
and::after
must have content, so remember to set content to "" wherever applicable. To learn why they must have some content in them, check out css - Why do the :before and :after pseudo-elements require a 'content' property? - Stack Overflow
1. Custom bulleted list
This one is probably the simplest of this lot. The idea is to turn off the default bullets of the list with list-style-type: none
and insert your own content via the ::before
pseudo-element. While you can achieve a similar effect with the traditional list-style-image
approach, this method allows you use any of your favorite Unicode characters as bullet, and also allows you to style them independently.
2. Info/Question/Success/Error etc. Icon
Similar to the above approach, here we're using that technique to render meaningful icons in alert boxes. Suppose you have a box that displays some information. Another that displays a warning message, and something else that asks a question. You can just provide your div
s with the respective CSS classes and let ::before
do the rest.
Btw, this is also an example where the
content
property of the pseudo-element is set to a URL, instead of text like in the earlier example.
3. A folded, wrapped-around effect
The trick here is to use the pseudo-element to display like the "wrapped-around" bit. For this (I learned this on CSS Tricks: The Shapes of CSS), we make its width zero, but also make it take up space with borders. The top and right borders are visible, while the remaining two are transparent, effectively rendering them invisible.
4. Gradient border
Here, we're styling the ::before
element to slightly outsize its parent (while also sending it behind it), and giving it a gradient for a background, so the parent element with the actual content stays on top of it, and the largely hidden pseudo-element has only a few pixels from each side peeking out, giving the impression of a border.
5. Corner borders
Honest confession: I saw this on a news website somewhere, loved it aaaaaaand, um, pressed F12 and stole the code. To be fair, they had done it with extra div
s which I then converted to pseudo-element code, so I kind of improved upon it I guess? The principle is the same as above, but we use both ::before
and ::after
in this case.
6. Transition effect on hover
Suppose you have a button with a linear-gradient
as a background. Now, there's a difference between how CSS treats a gradient and a color. Colors are just seen as solid colors, while gradients are actually rendered as if they were background images. Which means that normally, you wouldn't be able to add any kind of transition
to the background. That doesn't mean you cannot achieve a similar effect, though. In the example below, I have styled the ::before
pseudo-element to expand on hover with a transition. Because it's translucent and overlaid on top of the parent, you can see a subtle but smooth transition animation when you hover over the button.
That's all I can think of right now. What else do you think we can achieve with these pseudo-elements? Let me know in the comments.