{"id":292093,"date":"2019-07-08T13:45:05","date_gmt":"2019-07-08T20:45:05","guid":{"rendered":"http:\/\/css-tricks.com\/?p=292093"},"modified":"2019-07-09T09:45:49","modified_gmt":"2019-07-09T16:45:49","slug":"a-little-reminder-that-pseudo-elements-are-children-kinda","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/a-little-reminder-that-pseudo-elements-are-children-kinda\/","title":{"rendered":"A Little Reminder That Pseudo Elements are Children, Kinda."},"content":{"rendered":"

Here’s a container with some child elements:<\/p>\n

<div class=\"container\">\r\n  <div>item<\/div>\r\n  <div>item<\/div>\r\n  <div>item<\/div>\r\n<\/div><\/code><\/pre>\n

If I do:<\/p>\n

.container::before {\r\n  content: \"x\"\r\n}<\/code><\/pre>\n

I’m essentially doing:<\/p>\n

<div class=\"container\">\r\n  [[[ ::before psuedo-element here ]]]\r\n  <div>item<\/div>\r\n  <div>item<\/div>\r\n  <div>item<\/div>\r\n<\/div><\/code><\/pre>\n

Which will behave just like a child element mostly<\/em>. One tricky thing is that no selector selects it other than the one you used to create it (or a similar selector that is literally a ::before<\/code> or ::after<\/code> that ends up in the same place).<\/p>\n

<\/p>\n

To illustrate, say I set up that container to be a 2×3 grid and make each item a kind of pillbox design:<\/p>\n

.container {\r\n  display: grid;\r\n  grid-template-columns: 1fr 1fr;\r\n  grid-gap: 0.5rem;\r\n}\r\n\r\n.container > * {\r\n  background: darkgray;\r\n  border-radius: 4px;\r\n  padding: 0.5rem;\r\n}<\/code><\/pre>\n

Without the pseudo-element, that would be like this:<\/p>\n

\"Six<\/figure>\n

If I add that pseudo-element selector as above, I’d get this:<\/p>\n

\"Six<\/figure>\n

It makes sense, but it can also come as a surprise. Pseudo-elements are often decorative (they should pretty much only<\/em> be decorative), so having it participate in a content grid just feels weird.<\/p>\n

Notice that the .container > *<\/code> selector didn’t pick it up and make it darkgray<\/code> because you can’t select a pseudo-element that way. That’s another minor gotcha.<\/p>\n

In my day-to-day, I find pseudo-elements are typically absolutely-positioned to do something decorative — so, if you had:<\/p>\n

.container::before {\r\n  content: \"\";\r\n  position: absolute;\r\n  \/* Do something decorative *\/\r\n}<\/code><\/pre>\n

…you probably wouldn’t even notice. Technically, the pseudo-element is still a child, so it’s still in there doing its thing, but isn’t participating in the grid. This isn’t unique to CSS Grid either. For instance, you’ll find by using flexbox that your pseudo-element becomes a flex item. You’re free to float your pseudo-element or do any other sort of layout with it as well. <\/p>\n

DevTools makes it fairly clear that it is in the DOM like a child element:<\/p>\n

\"DevTools<\/figure>\n

There are a couple more gotchas!<\/p>\n

One is :nth-child()<\/code>. You’d think that if pseduo-elements are actually children, they would effect :nth-child()<\/code> calculations<\/a>, but they don’t. That means doing something like this:<\/p>\n

.container > :nth-child(2) {\r\n  background: red;\r\n}<\/code><\/pre>\n

…is going to select the same element whether or not there is a ::before<\/code> pseudo-element or not. The same is true for ::after<\/code> and :nth-last-child<\/code> and friends. That’s why I put “kinda” in the title. If pseudo-elements were exactly like child elements, they would affect these selectors.<\/p>\n

Another gotcha is that you can’t select a pseudo-element in JavaScript like you could a regular child element. document.querySelector(\".container::before\");<\/code> is going to return null<\/code>. If the reason you are trying to get your hands on the pseudo-element in JavaScript is to see its styles, you can do that with a little CSSOM<\/abbr> magic<\/a>:<\/p>\n

const styles = window.getComputedStyle(\r\n  document.querySelector('.container'),\r\n  '::before'\r\n);\r\nconsole.log(styles.content); \/\/ \"x\"\r\nconsole.log(styles.color); \/\/ rgb(255, 0, 0)\r\nconsole.log(styles.getPropertyValue('color'); \/\/ rgb(255, 0, 0)<\/code><\/pre>\n

Have you run into any gotchas with pseudo-elements?<\/p>\n","protected":false},"excerpt":{"rendered":"

Here’s a container with some child elements: <div class=”container”> <div>item<\/div> <div>item<\/div> <div>item<\/div> <\/div> If I do: .container::before { content: “x” } I’m essentially doing: <div class=”container”> [[[ ::before psuedo-element here ]]] <div>item<\/div> <div>item<\/div> <div>item<\/div> <\/div> Which will behave just like a child element mostly. One tricky thing is that no selector selects it other than […]<\/p>\n","protected":false},"author":3,"featured_media":292168,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[1154],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/06\/pseudo-child.png?fit=1200%2C600&ssl=1","jetpack-related-posts":[{"id":305295,"url":"https:\/\/css-tricks.com\/4-css-grid-properties-and-one-value-for-most-of-your-layout-needs\/","url_meta":{"origin":292093,"position":0},"title":"4 CSS Grid Properties (and One Value) for Most of Your Layout Needs","date":"March 30, 2020","format":false,"excerpt":"CSS Grid provides us with a powerful layout system for websites. The CSS-Tricks guide gives you a comprehensive overview of Grid\u2019s properties with layout examples. What we\u2019re going to do here is a reverse approach to show you the smallest possible set of grid properties you need to know to\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/03\/css-grid-properties.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":298798,"url":"https:\/\/css-tricks.com\/techniques-for-a-newspaper-layout-with-css-grid-and-border-lines-between-elements\/","url_meta":{"origin":292093,"position":1},"title":"Techniques for a Newspaper Layout with CSS Grid and Border Lines Between Elements","date":"November 20, 2019","format":false,"excerpt":"I recently had to craft a newspaper-like design that featured multiple row and column spans with divider lines in between them. Take a look at the mockup graphic here and see if it makes you sweat at all. If you\u2019re like me, you have been around a while and know\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/11\/newspaper-stack.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":257517,"url":"https:\/\/css-tricks.com\/difference-explicit-implicit-grids\/","url_meta":{"origin":292093,"position":2},"title":"The Difference Between Explicit and Implicit Grids","date":"August 10, 2017","format":false,"excerpt":"Grid Layout finally gives us the ability to define grids in CSS and place items into grid cells. This on its own is great, but the fact that we don't have to specify each track and we don't have to place every item manually makes the new module even better.\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":307873,"url":"https:\/\/css-tricks.com\/david-barons-thoughts-on-an-implementable-path-forward-for-container-queries\/","url_meta":{"origin":292093,"position":3},"title":"[David Baron’s] Thoughts on an implementable path forward for Container Queries","date":"April 29, 2020","format":false,"excerpt":"That's the title of a public post from David Baron, a Principal Engineer at Firefox, with thoughts toward container queries. I know a lot of people have been holding their breath waiting for David's ideas, as he's one of few uniquely qualified to understand the ins and outs of this\u2026","rel":"","context":"In "Link"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":372634,"url":"https:\/\/css-tricks.com\/using-grid-named-areas-to-visualize-and-reference-your-layout\/","url_meta":{"origin":292093,"position":4},"title":"Using Grid Named Areas to Visualize (and Reference) Your Layout","date":"August 26, 2022","format":false,"excerpt":"Whenever we build simple or complex layouts using CSS Grid, we're usually positioning items with line numbers. Grid layouts contain grid lines that are automatically indexed with positive and negative line numbers (that is unless we explicitly name them). Positioning items with line numbers is a fine way to lay\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/08\/Modern-Desktop-Breakpoint.jpg?fit=1200%2C720&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":376528,"url":"https:\/\/css-tricks.com\/animating-css-grid-how-to-examples\/","url_meta":{"origin":292093,"position":5},"title":"Animating CSS Grid (How To + Examples)","date":"January 25, 2023","format":false,"excerpt":"I\u2019m pleased to shine a light on the fact that the CSS grid-template-rows and grid-template-columns properties are now animatable in all major web browsers! Well, CSS Grid has technically supported animations for a long time, as it\u2019s baked right into the CSS Grid Layout Module Level 1 spec. But animating\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2023\/01\/grid-animation.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"featured_media_src_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/06\/pseudo-child.png?fit=1024%2C512&ssl=1","_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/292093"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=292093"}],"version-history":[{"count":7,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/292093\/revisions"}],"predecessor-version":[{"id":292679,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/292093\/revisions\/292679"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/292168"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=292093"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=292093"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=292093"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}