CSS Selectors Cheatsheet: Master Basic, Attribute & Pseudo Selectors

Introduction: What are CSS Selectors?

CSS selectors are patterns used to select and style HTML elements. They are the bridge between your HTML content and CSS styling, allowing you to precisely target specific elements or groups of elements. Mastering selectors is crucial for efficient styling, reducing code redundancy, and creating maintainable stylesheets.

Basic Selectors

SelectorSyntaxDescriptionExample
Universal*Selects all elements* { margin: 0; }
Type/ElementelementSelects all instances of specified elementp { color: blue; }
Class.classnameSelects elements with specified class.highlight { background: yellow; }
ID#idnameSelects element with specified ID#header { position: fixed; }
Groupselector1, selector2Applies same style to multiple selectorsh1, h2, h3 { font-family: Arial; }

Combinator Selectors

SelectorSyntaxDescriptionExample
Descendantancestor descendantSelects all descendantsdiv p { line-height: 1.5; }
Childparent > childSelects direct children onlyul > li { list-style: none; }
Adjacent Siblingelement + siblingSelects element immediately afterh2 + p { font-weight: bold; }
General Siblingelement ~ siblingsSelects all siblings afterh2 ~ p { color: gray; }

Attribute Selectors

SelectorSyntaxDescriptionExample
Has Attribute[attr]Elements with specified attribute[disabled] { opacity: 0.5; }
Exact Match[attr="value"]Attribute equals value[type="checkbox"] { margin: 0; }
Contains Word[attr~="value"]Attribute contains word[class~="btn"] { padding: 5px; }
Begins With[attr^="value"]Attribute begins with value[href^="https"] { color: green; }
Ends With[attr$="value"]Attribute ends with value[src$=".jpg"] { border: 1px solid; }
Contains Substring[attr*="value"]Attribute contains substring[class*="col"] { float: left; }
Hyphen-Separated`[attr=”value”]`Attribute starts with value followed by hyphen
Case Insensitive[attr="value" i]Case-insensitive matching[type="text" i] { border: none; }

Pseudo-Class Selectors

Link & User Interaction

SelectorDescriptionExample
:linkUnvisited linksa:link { color: blue; }
:visitedVisited linksa:visited { color: purple; }
:hoverElement being hoveredbutton:hover { background: lightgray; }
:activeElement being activateda:active { color: red; }
:focusElement with focusinput:focus { border-color: blue; }
:focus-withinElement containing focused elementform:focus-within { background: #f9f9f9; }
:focus-visibleElement with keyboard focusbutton:focus-visible { outline: 2px solid blue; }

Form States

SelectorDescriptionExample
:checkedChecked inputsinput:checked + label { font-weight: bold; }
:disabledDisabled elementsbutton:disabled { cursor: not-allowed; }
:enabledEnabled elementsinput:enabled { background: white; }
:requiredRequired inputsinput:required { border-color: red; }
:optionalOptional inputsinput:optional { border-color: gray; }
:validValid inputsinput:valid { border-color: green; }
:invalidInvalid inputsinput:invalid { border-color: red; }
:in-rangeInput value within rangeinput:in-range { color: green; }
:out-of-rangeInput value outside rangeinput:out-of-range { color: red; }
:placeholder-shownInput showing placeholder textinput:placeholder-shown { font-style: italic; }

Structural Pseudo-Classes

SelectorDescriptionExample
:rootDocument root element:root { --main-color: blue; }
:first-childFirst child of parentli:first-child { font-weight: bold; }
:last-childLast child of parentli:last-child { border-bottom: none; }
:nth-child(n)Matches nth childtr:nth-child(odd) { background: #f2f2f2; }
:nth-last-child(n)Matches nth child from endli:nth-last-child(2) { color: red; }
:only-childOnly child of parentli:only-child { list-style: none; }
:first-of-typeFirst element of typep:first-of-type { font-size: larger; }
:last-of-typeLast element of typeimg:last-of-type { margin-bottom: 0; }
:nth-of-type(n)Matches nth element of typediv:nth-of-type(3n) { margin-right: 0; }
:nth-last-of-type(n)Matches nth element of type from endp:nth-last-of-type(2) { font-style: italic; }
:only-of-typeOnly element of typeh1:only-of-type { text-align: center; }
:emptyElement with no childrenp:empty { display: none; }

Negation & Matching

SelectorDescriptionExample
:not(selector)Elements not matching selectorinput:not([type="checkbox"]) { width: 100%; }
:is(selectors)Matches any of the selectors:is(h1, h2, h3) { color: blue; }
:where(selectors)Like :is() but with 0 specificity:where(section, article) p { line-height: 1.5; }
:has(selector)Elements containing matching elementsdiv:has(> img) { padding: 10px; }

Pseudo-Element Selectors

SelectorDescriptionExample
::beforeCreates content before elementp::before { content: "»"; color: red; }
::afterCreates content after elementa::after { content: " ↗"; font-size: small; }
::first-lineStyles first line of textp::first-line { font-weight: bold; }
::first-letterStyles first letter of textp::first-letter { font-size: 2em; }
::selectionStyles selected text::selection { background: yellow; color: black; }
::placeholderStyles input placeholder textinput::placeholder { color: #999; }
::markerStyles list item markersli::marker { color: red; }
::backdropStyles backdrop of full-screen elementsdialog::backdrop { background: rgba(0,0,0,0.5); }

Specificity & Cascade

Specificity Hierarchy (lowest to highest)

  1. Universal selectors (*) – 0,0,0,0
  2. Element/type selectors (div, p) – 0,0,0,1
  3. Class selectors (.class), attribute selectors ([attr]), pseudo-classes (:hover) – 0,0,1,0
  4. ID selectors (#id) – 0,1,0,0
  5. Inline styles (style="...") – 1,0,0,0
  6. !important (overrides all) – Not counted in specificity, but takes precedence

Specificity Calculation Examples

SelectorCalculationSpecificity Value
p1 element0,0,0,1
p.intro1 element, 1 class0,0,1,1
#nav a1 ID, 1 element0,1,0,1
.header .nav li a:hover2 classes, 2 elements, 1 pseudo-class0,0,3,2
[type="text"]1 attribute0,0,1,0
button.btn:not(.large)1 element, 2 classes, 1 pseudo-class0,0,3,1

Common Challenges & Solutions

Managing Specificity

Challenge: CSS conflicts due to high specificity selectors

Solutions:

  • Use classes instead of IDs when possible
  • Avoid deeply nested selectors
  • Use BEM or other naming conventions
  • Consider CSS custom properties for shared values
  • Use :where() to reduce specificity

Targeting Specific Elements

Challenge: Difficulty targeting elements in complex structures

Solutions:

  • Use child combinators (>) instead of descendant selectors
  • Leverage attribute selectors for unique targeting
  • Use :nth-child() or :nth-of-type() for positional selection
  • Apply the :not() pseudo-class to exclude elements
  • Use the :has() relational pseudo-class (with appropriate browser support checking)

Browser Compatibility

Challenge: Newer selectors not supported in all browsers

Solutions:

  • Check compatibility on Can I Use
  • Provide fallbacks for critical styling
  • Use feature detection when necessary
  • Consider using polyfills for essential features
  • Progressive enhancement: use basic selectors first, enhance with advanced ones

Best Practices & Tips

  • Prefer classes for styling: They provide good reusability without excessive specificity
  • Keep selectors simple: Aim for 2-3 levels deep maximum for better performance
  • Use semantic selectors: Target what an element is, not what it looks like
  • Avoid using ID selectors for styling: Reserve them for JavaScript hooks and anchors
  • Leverage the cascade: Use inheritance when appropriate instead of repeating styles
  • Think mobile-first: Structure selectors to prioritize mobile styling first
  • Comment complex selectors: Explain why a complicated selector is necessary
  • Use selector performance tools: Analyze and optimize selector efficiency
  • Organize selectors logically: Group related selectors together in your stylesheet
  • Test across browsers: Verify selectors work across your supported browser range

Resources for Further Learning

Interactive Tools

This cheatsheet covers all essential CSS selectors, providing a comprehensive reference for styling web pages with precision and efficiency.

Scroll to Top