Skip to main content
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Gert Franz
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Gert Franz

Applying CSS Flexbox To Pseudo-Elements

By
Published in Comments (4)

The other day, I was listening to Episode 14 of the CSS Podcast: Pseudo Elements, hosted by Una Kravets and Adam Argyle, when Adam said something quite thought-provoking: he mentioned that you can apply CSS Flexbox to pseudo-elements in order to perfectly align icons. I didn't know if we was referring to the pseudo-element being a flex-item? Or, if he meant applying display: flex to the pseudo-element itself. In the end, it doesn't really matter because both use-cases are awesome! As such, I wanted to take a quick look at what we can do with CSS Flexbox and a pseudo-element. And, for funzies, I'm throwing in the attr() function because I've never actually used it before.

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

To experiment with CSS Flexbox and pseudo-elements, I've created a demo in which I have a list of people; and, before each person, I'm going to include a little avatar-like element that contains the person's initials. Each person in the list has this type of HTML markup:

<div data-initials="BC" class="person">
	Bethany Chang
</div>

What you'll notice here is that the initials aren't in the text-content of the div element. Instead, they are being provided in the data-initials attribute. In the CSS, we're going to extract those initials using the attr(data-initials) function and then apply them to the view using the :before pseudo-element's content property.

The :before pseudo-element is going to have display: flex, which will allow us to center the initials inside the rendered pseudo-element. This is a really cool feature of CSS Flexbox: when you give an element a Flex Layout, any text-nodes that are direct-descendants of that Flex layout receive an implicit flex-item wrapper complete with default flex values:

Applying display:flex to a pseudo-element gives its content an implicit flex-item wrapper.

With the display: flex on our :before pseudo-element, and the implicit flex-item wrapper on the content, we can then use align-items and justify-content to horizontally and vertically center the content within the dimensions of the pseudo-element!

If this weren't a big enough bowl of awesome, we can make this even moar awesome by applying display: flex to the parent element as well (the div in our case)! By doing this, it makes the :before pseudo-element both a Flex-item and a Flex layout - oh chickens! This allows us to then space and align the pseudo-element relative to the person's name, which will, itself, receive an implicit flex-item wrapper.

Here's the code for the full demo:

<!doctype html>
<html lan="en">
<head>
	<meta charset="utf-8" />
	<title>
		Applying CSS Flexbox To Pseudo-Elements
	</title>
</head>
<body>

	<h1>
		Applying CSS Flexbox To Pseudo-Elements
	</h1>

	<style type="text/css">

		.person {
			align-items: center ;
			display: flex ;
			font-size: 20px ;
			margin: 10px 0px 10px 0px ;
		}
		.person:before {
			/*
				When we apply "display: flex" to the pseudo-element, the CONTENT within
				the pseudo-element is given an IMPLICIT WRAPPER, making it the only item
				in this local flexbox layout. This allows us to use "align-items" and
				"justify-content" as a means to center the CONTENT within the dimensions
				of the pseudo-element.
			*/
			align-items: center ;
			content: attr( data-initials ) ;
			display: flex ;
			justify-content: center ;

			/* Other styling ... */
			background-color: #111111 ;
			border-radius: 100% 100% 100% 100% ;
			color: #ffffff ;
			font-family: monospace ;
			font-size: 12px ;
			font-weight: 600 ;
			height: 36px ;
			letter-spacing: 1px ;
			line-height: 12px ;
			margin-right: 10px ;
			text-transform: uppercase ;
			width: 36px ;
		}

	</style>

	<div data-initials="CD" class="person">
		Connor Donovan
	</div>
	<div data-initials="RA" class="person">
		Rachel Ali
	</div>
	<div data-initials="RM" class="person">
		Robert Marsden
	</div>
	<div data-initials="AD" class="person">
		Aaliyah Derrick
	</div>
	<div data-initials="AE" class="person">
		Alena Esparza
	</div>
	<div data-initials="DD" class="person">
		Dannielle Douglas
	</div>
	<div data-initials="FR" class="person">
		Florrie Romero
	</div>
	<div data-initials="BC" class="person">
		Bethany Chang
	</div>
	<div data-initials="NH" class="person">
		Nabeel Hartley
	</div>
	<div data-initials="NA" class="person">
		Neil Anthony
	</div>

	<!-- Names generated using: https://www.name-generator.org.uk/quick/ -->

</body>
</html>

As you can see, both .person and .person:before are being given a Flex layout. And, when we run this code in the browser, we get the following output:

Initials being rendered in pseudo-element using attr() and CSS Flexbox.

CSS Flexbox is so awesome! Here, we have the :before pseudo-element acting as a sibling Flex-item to the person's name, which allows us to space it and center-align it. But, it's also acting as its own, local Flex-layout, which allows us to center the text-content of the initials both horizontally and vertically within the avatar-like circle.

CSS Flexbox is the best thing since sliced bread border-radius!

And, the attr() function is pretty cool as well. I've never used it before this; but, I kind of enjoy how clean it allows us to keep the markup. Of course, sometimes it is nice to have explicit elements that 1) make the code a bit less magical and, 2) allow us to hook into the HTML using element-selectors. But, still, I love the elegance of it all.

Anyway, just a fun little code-kata on CSS Flexbox, which has become my go-to layout technology (since I still have to support IE11 at work).

Want to use code from this post? Check out the license.

Reader Comments

9 Comments

Ben, to me your blog posts are of an enormous value, because it doesn't deal only about cfml, but covers about a lot of stuff, mysql, javascript, angular, vue, adobe cf, lucee cf CSS and more. You're still sharing so much to our community, even though your startup has evolved to a big and well known app. Others would have gone underground. Hope to see your posts as long as you still have time to do so. Thank you!

15,902 Comments

@Andreas,

Thank you very much for the kind words! I'm just happy to be adding some value when I can. Here's to a long and fruitful future!

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel