Labs ICT

CSS Selectors

A selector allows us to associate one or more declarations to one or more elements on the page.

Basic selectors

Suppose we have a pelement on the page, and we want to display the words into it using the yellow color.


p {
  color: yellow;    
}

Here in the aboved example we target p element as a selector which will apply the style to all ptag that we have in the page.

Every HTML tag has a corresponding selector, for example: div, span, img.

If a selector matches multiple elements, all the elements in the page will be affected by the change.

HTML elements have 2 attributes which are very commonly used within CSS to associate styling to a specific element on the page: class and id.

There is one big difference between those two: inside an HTML document you can repeat the same class value across multiple elements, but you can only use an id once. As a corollary, using classes you can select an element with 2 or more specific class names, something not possible using ids.

Classes are identified using the . symbol, while ids using the # symbol.

Example using a class:


.my-class {
  color: yellow;    
}

Example using a id:


#my-id {
  color: yellow;    
}

So far we've seen how to target an element, a class or an id. Let's introduce more powerful selectors.

Why would you want to do that, if the class or id already provides a way to target that element? You might have to do that to have more specificity. We'll see what that means later.

Targeting multiple classes

You can target an element with a specific class using .class-name , as you saw previously. You can target an element with 2 (or more) classes by combining the class names separated with a dot, without spaces.

Example:


.my-class.another-class {
  color: yellow;    
}

A selector can target one or more items:


p, a {
  font-size: 16px;         
}

Combining classes and ids

In the same way, you can combine a class and an id.

Example:


.my-class#my-id {
  color: yellow;    
}

Grouping selectors

You can also group selectors together, to apply the same styles to different elements. To do that, you just need to separate the selectors with a comma.

Example:


p, a, .my-class {
  color: yellow;    
}

Follow the document tree with selectors

We've seen how to target an element in the page by using a tag name, a class or an id.

You can create a more specific selector by combining multiple items to follow the document tree structure. For example, if you have a span tag nested inside a p tag, you can target that one without applying the style to a span tag not included in a p tag:

Example:


p span {
  color: blue;    
}

See how we used a space between the two tokens p and span.

This works even if the element on the right is multiple levels deep.

To make the dependency strict on the first level, you can use the > symbol between the two tokens:

Example:


p > span {
  color: blue;
}    

In this case, if a span is not a first children of the p element, it's not going to have the new color applied.


<div>
  <p>
    <span>This is going to be blue</span>
    <div>
      <span>This is not going to be blue</span>
    </div>
  </p>  
</div>

Adjacent sibling selectors let us style an element only if preceded by a specific element. We do so using the + operator:

Example:


p + span {
  color: yellow;
}    

This will assign the color yellow to all span elements preceded by a p element:

Example

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>My First Page</title>
  <style>
   p > span {
     color: yellow;    
   }
  </style>
</head>
<body>
  <div>
    <p>
      <span>This is going to be yellow</span>
      <div>
        <span>This is not going to be yellow</span>
      </div>
    </p>  
  </div>
</body>
</html>

We have a lot more selectors we can use:

  • Attribute selectors
  • Pseudo class selectors
  • Pseudo element selectors
  • And more...

We'll find all about them in their respective sections.

Best Practices

Do:

  • Use class selectors for styling (most maintainable)
  • Keep selectors simple and readable
  • Use semantic HTML elements as base selectors
  • Consider specificity when writing selectors
  • Use BEM methodology for class naming
  • Test selectors across different browsers
  • Use descendant selectors for nested styling
  • Consider performance impact of complex selectors
  • Use attribute selectors for form validation styling
  • Document complex selectors in comments

Don't:

  • Overly specific selectors (avoid !important)
  • Use ID selectors for styling (use for JavaScript hooks)
  • Nest selectors too deeply (performance issues)
  • Use inline styles (hard to maintain)
  • Rely on element selectors alone (not specific enough)
  • Use universal selector (*) unnecessarily
  • Create selectors that are too complex to understand
  • Ignore browser compatibility for advanced selectors
  • Use selectors for layout (use CSS Grid/Flexbox)
  • Assume selectors work the same in all contexts

Important Considerations

Pro Tip:

  • Use CSS custom properties with selectors for theming
  • Combine selectors efficiently for complex styling
  • Use CSS preprocessors for better selector organization
  • Consider CSS-in-JS for component-based architectures
  • Use selector specificity calculators for debugging

Warning:

  • Complex selectors can impact rendering performance
  • Selector specificity can cause unexpected overrides
  • Browser support varies for advanced selectors
  • Dynamic content may affect selector behavior
  • Third-party CSS can interfere with your selectors

Accessibility:

  • Use semantic selectors for screen readers
  • Ensure focus states are properly styled
  • Test selectors with assistive technologies
  • Use ARIA attributes with attribute selectors
  • Consider keyboard navigation in selector design

Performance:

  • Rightmost selector is evaluated first
  • Avoid universal selectors in large documents
  • Class selectors are faster than attribute selectors
  • ID selectors are fastest but less maintainable
  • Consider CSS containment for performance optimization

Selector Specificity Guidelines

Specificity Best Practices:

  • Use low specificity selectors for base styles
  • Increase specificity only when necessary
  • Use class combinations instead of nesting
  • Document specificity rules in your style guide
  • Test specificity conflicts thoroughly
  • Use CSS custom properties to reduce specificity needs
  • Consider component-based architecture for specificity

Avoid Specificity Issues:

  • Don't use !important to override specificity
  • Avoid overly specific selectors
  • Don't rely on source order for conflicts
  • Avoid inline styles that have highest specificity
  • Don't ignore specificity in complex projects
  • Avoid mixing ID and class selectors unnecessarily

Advanced Selector Techniques

Advanced Approaches:

  • Use attribute selectors for form validation states
  • Combine pseudo-classes for interactive elements
  • Use structural pseudo-classes for complex layouts
  • Implement CSS-only solutions with selectors
  • Use negation pseudo-class for exclusions
  • Combine selectors for component variations

Advanced Selector Pitfalls:

  • Don't overcomplicate selectors for simple tasks
  • Avoid browser-specific selectors unless necessary
  • Don't use experimental selectors in production
  • Avoid selectors that are hard to debug
  • Don't ignore fallbacks for unsupported selectors

Looking Ahead

We have a lot more selectors we can use:

  • Attribute selectors
  • Pseudo class selectors
  • Pseudo element selectors
  • And more...
We'll explore all these advanced selectors in their respective sections, where we'll dive deep into each type with practical examples and best practices.

๐Ÿงช Quick Quiz

How do you select an element with id 'header'?

โ† CSS Syntax
CSS Combinators โ†’