L U L L A B O T + F R O N T E N D A W E S O M E L U L L A B O T + F R O N T E N D A W E S O M E { 1 M I K E H E R C H E L } CSS Selectors 101++ @ M I K E H E R C H E L
L U L L A B O T + F R O N T E N D A W E S O M E What We'll Cover ⭑ Memes ⭑ What are we trying to solve? ⭑ Basic level selectors ⭑ Combining selectors ⭑ Chaining ⭑ Pseudo-elements ⭑ Pseudo-classes ⭑ Some cool (and weird) recipes 5
L U L L A B O T + F R O N T E N D A W E S O M E ”CSS is easy. It's just a few thousand key value pairs that have quirks in each browser that you have to memorize. — Dave Rupert 6
L U L L A B O T + F R O N T E N D A W E S O M E 19 .text-align-center { text-align: center; } .user-login-form input[type="submit"] { background-color: #01639a; color: #fff; height: 54px; padding-left: 27px; padding-right: 27px; } .user-login-form input[type="submit"]:hover, .user-login-form input[type="submit"]:focus { background-color: #024062; } .user-login-form input[type="submit"]:active { background-color: #002337; }
L U L L A B O T + F R O N T E N D A W E S O M E .text-align-center { text-align: center; } .user-login-form input[type="submit"] { background-color: #01639a; color: #fff; height: 54px; padding-left: 27px; padding-right: 27px; } .user-login-form input[type="submit"]:hover, .user-login-form input[type="submit"]:focus { background-color: #024062; } .user-login-form input[type="submit"]:active { background-color: #002337; } CSS selectors
L U L L A B O T + F R O N T E N D A W E S O M E .text-align-center { text-align: center; } .user-login-form input[type="submit"] { background-color: #01639a; color: #fff; height: 54px; padding-left: 27px; padding-right: 27px; } .user-login-form input[type="submit"]:hover, .user-login-form input[type="submit"]:focus { background-color: #024062; } .user-login-form input[type="submit"]:active { background-color: #002337; } CSS declarations
L U L L A B O T + F R O N T E N D A W E S O M E .text-align-center { text-align: center; } .user-login-form input[type="submit"] { background-color: #01639a; color: #fff; height: 54px; padding-left: 27px; padding-right: 27px; } .user-login-form input[type="submit"]:hover, .user-login-form input[type="submit"]:focus { background-color: #024062; } .user-login-form input[type="submit"]:active { background-color: #002337; } CSS selectors
L U L L A B O T + F R O N T E N D A W E S O M E if (!Drupal.unobtainium.settings.subMenuProcessed && subNav !== null) { const button = subNav.querySelector('.subnav__button'); const subNavInner = subNav.querySelector('.subnav__inner'); const activeClass = 'js-active'; function isSubNavOpen() { return subNavInner.classList.contains(activeClass); } 26 CSS selectors in JavaScript
L U L L A B O T + F R O N T E N D A W E S O M E An element (aka node) 28 class="mega-menu__button" type="button" aria-controls="primary-nav-our-science" aria-expanded="false">Our Science ID Class Attribute value Attribute
L U L L A B O T + F R O N T E N D A W E S O M E Element selector 30 li { break-inside: avoid; } Note lack of preceding period or hash. This selects all elements.
L U L L A B O T + F R O N T E N D A W E S O M E Class selector 32 .mega-submenu { font-weight: 700; letter-spacing: .05em; column-count: 2; } Period (.) designates the selector as an class. Note the period is not present in the HTML. This selects all elements that have a class of “mega-submenu”.
L U L L A B O T + F R O N T E N D A W E S O M E ID selector 34 #primary-nav-our-science { display: flex; align-items: center; } Hash (#) designates the selector as an ID. Note the hash is not present in the HTML. This selects all elements with an ID of “primary-nav-our-science”. Note that IDs should be unique.
L U L L A B O T + F R O N T E N D A W E S O M E Attribute selector 36 [aria-expanded] { color: #434251; } Square brackets selects elements that have the matching attribute. This selects all elements that have an “aria-expanded” attribute.
L U L L A B O T + F R O N T E N D A W E S O M E Attribute selector with value 38 [aria-expanded="true"] { color: #434251; } Matches both the attribute and its value. This selects all elements that have an “aria-expanded” attribute set to “true”.
L U L L A B O T + F R O N T E N D A W E S O M E Attribute selector that starts with value 40 [href^="https"] { color: #434251; } Carrot (^) will match when value of attribute starts with the the value that’s in quotes. This selects all elements that have an “href” attribute, whose value begins with “https”.
L U L L A B O T + F R O N T E N D A W E S O M E Attribute selector that ends with value 41 [href$="pdf"] { color: #434251; } Dollar ($) will match when value of attribute ends with the the value that’s in quotes. This selects all elements that have an “href” attribute, whose value ends with “pdf”.
L U L L A B O T + F R O N T E N D A W E S O M E Attribute selector that contains value 42 [href*="this-text"] { color: #434251; } Asterisk (*) will match when value of attribute contains with the the value that’s in quotes.
L U L L A B O T + F R O N T E N D A W E S O M E Can you use attribute selectors in place of class or ID selectors? 43 [class="mega-submenu"] { font-weight: 700; letter-spacing: .05em; column-count: 2; }
L U L L A B O T + F R O N T E N D A W E S O M E Descendent selector 46 #primary-nav-our-science .mega-submenu a { position: relative; } Space in between selectors will select all instances of the last selector that has the corresponding parent selectors. This selector selects all elements that have a parent who has a class of “mega-submenu”... who are nested under any element that has an ID of “primary-nav-our-science”.
L U L L A B O T + F R O N T E N D A W E S O M E Direct child selector 48 .flex > li { position: relative; } Greater-than symbol in between selectors will select all instances of the last selector that is a direct child of the selector preceding the greater-than symbol.
L U L L A B O T + F R O N T E N D A W E S O M E General sibling selector 50 .my-class ~ li { position: relative; } The tilde (~) will select all elements that are siblings and appear subsequent to the previous selector (before the tilde). This will select any elements that are siblings and subsequent to an element that has a class of “my-class”.
L U L L A B O T + F R O N T E N D A W E S O M E Adjacent sibling selector 52 .my-class + li { position: relative; } The plus (+) will select the very next element that is a sibling. This will select a element if it is directly subsequent to an element that has a class of “my-class”.
L U L L A B O T + F R O N T E N D A W E S O M E Chain selectors by omitting spaces 55 ul.flex { position: relative; } Note the lack of space preceding the period. This selects all elements with a class of “flex”.
L U L L A B O T + F R O N T E N D A W E S O M E Chaining selectors 57 button.btn--primary[type="submit"] { position: relative; } This selects all button elements that have a CSS class of “btn--primary” and a “type” attribute that is set to “submit”.
L U L L A B O T + F R O N T E N D A W E S O M E Chaining selectors 58 button.form-item.btn--primary[type="submit"] { position: relative; } This selects all button elements that have ● CSS class of “form-item” ● CSS class of “btn--primary” ● “type” attribute that is set to “submit”.
L U L L A B O T + F R O N T E N D A W E S O M E Chaining selectors 59 button.form-item.btn--primary[type="submit"][aria-expanded="false"] { position: relative; } This selects all button elements that have ● CSS class of “form-item” ● CSS class of “btn--primary” ● “type” attribute that is set to “submit” ● “aria-expanded” attribute that is set to “false”
L U L L A B O T + F R O N T E N D A W E S O M E Combining selectors 60 section.bg-gray-10 .card--publication, section.bg-blue-20 .card--publication, section.bg-gradient-blue .card--publication { background-color: #fff; } Combine selectors with a comma (,).
L U L L A B O T + F R O N T E N D A W E S O M E 64 ::before and ::after pseudo-elements enable you to insert DOM nodes at the beginning and ending of elements*. * Most elements
L U L L A B O T + F R O N T E N D A W E S O M E Creating :before and :after elements 66 button:after { content: "→"; } The content property must be used to instantiate the element. Note that any text placed in this is not visible to screen readers.
L U L L A B O T + F R O N T E N D A W E S O M E Common use cases for :before and :after ⭑ Insert decorative text ⭑ Insert an image (by giving the it a size and background image) ⭑ Give it a shape and style it 67
L U L L A B O T + F R O N T E N D A W E S O M E Example use case 68 ● The “Play” icon is a :before pseudo-element styled to be a triangle. ● The “Pause” icon is the same transparent :before pseudo-element with border-left and border-right set. https://lullabot.com/podcasts
L U L L A B O T + F R O N T E N D A W E S O M E Other useful pseudo-elements ⭑ :first-letter ⭑ :first-line ⭑ :placeholder ⭑ :selection More at https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements 69
L U L L A B O T + F R O N T E N D A W E S O M E Hover state 71 :hover { background-color: red; } This selects all elements when in a hover state. Every element will turn red on hover.
L U L L A B O T + F R O N T E N D A W E S O M E Hover state 72 .my-button:hover { background-color: red; } This selects the element that has a “my-button” class when the element is hovered over.
L U L L A B O T + F R O N T E N D A W E S O M E Focus state 73 .my-button:focus { background-color: red; } This selects the element that has a “my-button” class, when the element has focus.
L U L L A B O T + F R O N T E N D A W E S O M E Focus-within state 74 .my-menu:focus-within { display: block; } This selects the element that has a “my-menu” class, when any element inside of this element has focus.
L U L L A B O T + F R O N T E N D A W E S O M E Checked state 75 input[type="checkbox"]:checked { border: solid 2px red; } This selects any input element that has a type attribute that is set to “checkbox”, and is checked.
L U L L A B O T + F R O N T E N D A W E S O M E Other useful state selectors ⭑ :active ⭑ :disabled ⭑ :visited More at https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes 76
L U L L A B O T + F R O N T E N D A W E S O M E :not() 78 .cards--border-blue:not(.is-active) { border-color: #eeb41e; } Selects the opposite of what is in the parenthesis. This selector is looking elements that have the “cards--border-blue” class but do not have the “is-active” class.
L U L L A B O T + F R O N T E N D A W E S O M E :not() 79 .cards--border-blue:not(:focus) { border-color: #eeb41e; } This selector is looking elements that have the “cards--border-blue” class are not in focus.
L U L L A B O T + F R O N T E N D A W E S O M E :first-child and :last-child 80 .mega-submenu li:last-child a { border-color: #eeb41e; } Selects the first or last sibling element. This particular selector will select an tag that appears under a that is also the last element under its parent, which is under a “menu-submenu” class.
L U L L A B O T + F R O N T E N D A W E S O M E :first-child and :last-child 82 .mega-submenu li:not(:last-child) { margin-bottom: 27px; } Selects the first or last element under an element. This particular ruleset will select all of the tags that are under the “menu-submenu” class — except for the last one, and add a bottom margin to it.
L U L L A B O T + F R O N T E N D A W E S O M E :nth-child(even) and :nth-child(odd) 83 tbody tr:nth-child(even) { background: #eee; } Selects the even or odd numbered elements. This particular selector creates a “zebra stripe” pattern and which makes alternate table rows have a light background color.
L U L L A B O T + F R O N T E N D A W E S O M E :nth-child(x) 84 .mega-submenu li:nth-child(2) { border-color: #eeb41e; } Selects the specific nth element. This particular selector will select the 2nd tag under its parent, if it is under an element with a “menu-submenu” class.
L U L L A B O T + F R O N T E N D A W E S O M E :nth-child(xn) 85 .mega-submenu li:nth-child(4n) { border-color: #eeb41e; } Selects every xth element. This particular selector will select every 4th tag under its parent, if it is under an element with a “menu-submenu” class.
L U L L A B O T + F R O N T E N D A W E S O M E :nth-child(xn + y) 86 .mega-submenu li:nth-child(4n + 1) { border-color: #eeb41e; } Selects every xth element, but moving up y position(s). This particular selector will select every 4th tag under its parent starting moving one position up.
L U L L A B O T + F R O N T E N D A W E S O M E :only-child 88 .mega-submenu li:only-child { border-color: #eeb41e; } Selects the element under .mega-submenu if it is the only child of its parent.
L U L L A B O T + F R O N T E N D A W E S O M E :nth-last-child() 89 .mega-submenu li:nth-last-child(4n + 1) { border-color: #eeb41e; } Selects every xth element from the end, but moving up y position(s). This particular selector will select every 4th tag under its parent starting from the end moving one position up.
L U L L A B O T + F R O N T E N D A W E S O M E :nth-of-type() 90 .mega-submenu li:nth-of-type(4n + 1) { border-color: #eeb41e; } Selects every xth element of the specified type, but moving up y position(s). This particular selector will select every 4th tag under its parent starting moving one position up.
L U L L A B O T + F R O N T E N D A W E S O M E :only-of-type 91 .mega-submenu li:only-of-type { border-color: #eeb41e; } Selects the element of the same type under .mega-submenu if it is the only child of the same type under its parent.
L U L L A B O T + F R O N T E N D A W E S O M E :last-of-type() 92 .mega-submenu li:last-of-type(2) { border-color: #eeb41e; } Matches elements of a given type, based on their position among a group of siblings, counting from the end.
L U L L A B O T + F R O N T E N D A W E S O M E :empty 93 .mega-submenu li:empty { border-color: #eeb41e; } Matches elements that do not have any text, white space, or HTML comments.
L U L L A B O T + F R O N T E N D A W E S O M E Add icon to end of links that are email address 95 a[href^="mailto"]:after { content: "✉"; /* Unicode envelope. */ margin-left: 3px; }
L U L L A B O T + F R O N T E N D A W E S O M E Add icon to end of links that are PDFs 96 a[href$="pdf"]:after { content: ''; display: inline-block; vertical-align: middle; width: 20px; height: 20px; background: url('/images/pdf-icon.svg') no-repeat center; margin-left: 3px; }
L U L L A B O T + F R O N T E N D A W E S O M E Quantity selector 97 .my-parent > *:first-child:nth-last-child(4), .my-parent > *:first-child:nth-last-child(4) ~ * { /* This only selects elements if there's exactly 4 siblings. */ }
L U L L A B O T + F R O N T E N D A W E S O M E Multiple selector 98 .my-parent > *:first-child:nth-last-child(4n), .my-parent > *:first-child:nth-last-child(4n) ~ * { /* Selects elements if there's a multiple of 4 siblings. */ }
L U L L A B O T + F R O N T E N D A W E S O M E Only show element when checkbox is checked 99 .my-menu-container { display: none; } .my-checkbox:checked ~ .my-menu-container { display: block; }