CSS Selectors and Specificity

Written by Web Developer

March 26, 2024
CSS Selectors and Specificity

CSS is one of the most crucial components of building any web application. A common problem developers face is that CSS styles apply differently than intended, particularly when multiple style properties come into play. This article discusses CSS selectors and specificity (rules defining how CSS styles are applied to specific elements). This will help us to understand and solve the issue of CSS styles getting overridden in the browser.

Understanding CSS Selectors


These selectors are the building blocks of CSS, enabling developers to target HTML elements with precision.

They include the following:

  • Universal Selector: The universal selector is represented by an asterisk (*). This selector acts like a wildcard and targets every element within a document or selects all the descendant elements when combined with other elements. It’s mostly used to apply styles universally.

  • Type Selector (Element Selector): This selector targets specific HTML tags or elements within your document. For instance, you can use ‘p’ as the selector to style all paragraphs within your document.

p {
  /* Styles for all paragraphs */
}
  • Class Selector: The class selector is identified with a leading dot (.) character. It targets elements with a specific class attribute, and it’s case-sensitive, allowing for the repeated application across various elements in a document. For example, a 'highlight' class can be used to emphasize different sections, as shown below:
.highlight {
  /* Styles for elements with class="highlight" */
}
  • ID Selector: The case-sensitive ID selector begins with a # rather than a dot character but is used the same way as a class selector. However, an ID can be used only once per page, and elements can only have a single ID value applied to them. It can select an element with the ID set on it, and you can precede the ID with a type selector to target the element only if both the element and ID match. For instance, styling the header of a page would typically use the ID Selector as follows:
#header {
  /* Styles for the element with id="header" */
}
  • Attribute Selector and Attribut-Value Selector: In CSS, you can use attribute selectors to target elements with certain attributes and Attribute-value to select elements based on the presence or value of their attributes. For example, [type="text"] selects all elements with type="text"
[type="text"] {
  /* styles */
}

Pseudo-Classes and Pseudo-Elements in CSS

Pseudo-classes and pseudo-elements represent another layer of sophistication in CSS selectors. Pseudo-classes, denoted by a colon (:), allow you to target elements in a specific state. For example, the :hover pseudo-class is widely used to define elements' styles when hovered over by a mouse pointer. This feature enhances user interaction, as shown in the following snippet:

a:hover {
  /* styles */
}

Pseudo-elements behave similarly. However, they act like you added a whole new HTML element into the markup rather than applying a class to existing elements. Pseudo-elements start with a double colon ::. Some early pseudo-elements used the single colon syntax, so you may see this in code or examples. Modern browsers support the early pseudo-elements with single or double-colon syntax for backward compatibility. For example, if you wanted to select the first line of a paragraph, you could wrap it in a <span> element and use an element selector. The first-line pseudo-element selector will do this for you reliably — if the number of words increases or decreases, it will only select the first line. For example, ::before inserting content before an element's actual content.

p::before {
  /* styles */
  content: "Before text";
}
90%

💸 90% OFF YOUR FIRST MONTH WITH ALL VERPEX CLOUD WEB HOSTING PLANS

with the discount code

MOVEME

Save Now

Combinators in CSS

Combinators enable more complex and precise elements targeting based on their relationship in the document hierarchy.

Descendant Combinator

The descendant combinator — typically represented by a single space (" ") character — combines two selectors such that elements matched by the second selector are selected if they have an ancestor element matching the first selector. Selectors that utilize a descendant combinator are called descendant selectors. For example, div p selects all <p> elements that are descendants of a <div>.

div p {
  /* styles */
}

Child Combinator

The child combinator (>) is placed between two CSS selectors. It matches only those elements matched by the second selector that are the direct children of elements matched by the first. Descendant elements further down the hierarchy don't match. For example, to select only <p> elements that are direct children of <article> elements, ul > li selects all <li> elements that are direct children of a <ul>.

ul > li {
  /* styles */
}

The next-sibling combinator

The next-sibling combinator (+) is placed between two CSS selectors. It matches only those elements matched by the second selector, the next sibling element of the first selector. For example, to select all <img> elements that are immediately preceded by a <p> element:

p + img

A common use case is to do something with a paragraph that follows a heading, as in the example below. In that example, we look for any paragraph that shares a parent element with an <h1> and immediately follows that <h1>. Suppose you insert some other element, such as an <h2>, in between the <h1> and the <p>. In that case, you will find that the paragraph is no longer matched by the selector and so does not get the background and foreground color applied when the element is adjacent. ​​For example, h2 + p selects the <p> element that directly follows an <h2>.

h2 + p {
  /* styles */
}

Adjacent and Subsequent-sibling Combinator

If you want to select siblings of an element even if they are not directly adjacent, then you can use the subsequent-sibling combinator (~). To select all <img> elements that come anywhere after <p> elements, we'd do this:

p ~ img

For example, h2 ~ p selects all <p> elements that are siblings of an <h2>.

h2 ~ p {
  /* styles */
}

You can combine any selectors we discovered in previous lessons with combinators to pick out part of your document. For example, to select list items with a class of "a" which are direct children of a <ul>, try the following:

ul > li[class="a"] {
}

However, when creating big lists of selectors that select very specific parts of your document, it will be hard to reuse the CSS rules since you have made the selector very specific to the location of that element in the markup. Creating and applying a simple class to the element in question is often better. That said, your knowledge of combinators will be very useful if you need to style something in your document and cannot access the HTML, perhaps due to it being generated by a CMS.

What is CSS Specificity?


What is CSS Specificity

In web development, it is common to write many CSS rules for one element, but sometimes, they may not get applied because the browser decides which rule will be applied to the element. This is called CSS Specificity.

What rule will take precedence over the others, and why? The one with the most specificity will win. If two or more rules have the same specificity, the one that appears last will prevail.

Technically, !important doesn't affect specificity, but when used in a selector, it will override the other CSS selectors and apply !important. It's always bad practice to use !important as it breaks the natural CSS cascading in stylesheets and is difficult to debug.

Here are some key reasons why specificity is important in web development:

  • Modularity and Code Maintenance: Specificity promotes modular style organization, enabling developers to create reusable, independent styles that are easier to maintain and update without unwanted side effects.

  • Debugging and Troubleshooting: Understanding specificity aids developers in troubleshooting issues with rendering styles as expected, identifying conflicting rules, and adjusting specificity accordingly.

  • Efficient Styling: Using the appropriate level of specificity allows developers to create efficient, targeted styles, reducing the need for complex or redundant rules, resulting in cleaner and more maintainable code.

  • Collaborative Development: Understanding specificity in collaborative development environments ensures that styles applied by different team members do not conflict, resulting in a smoother process.

Understanding Specificity Rules


When you create a web application, the browser parses the HTML, creates the DOM, and parses the CSS. Once the CSS has been parsed and sorted, it determines which CSS to apply to which element based on the rules and the position of the element selector.

Below is the order of specificity rules with precedence:

  • Inline style: Inline style has the highest priority.

  • ID Selector: It has the second highest priority.

  • Classes, Pseudo-Classes, and Attributes: These selectors have the lowest priority.

Apart from this, we have a few more that have priority based on CSS imports:

  • Internal style
  • External CSS
  • Inline style

These CSS files will inherit properties written in them once we include them in our application. We will be able to apply internal CSS that overrides the external CSS properties, and the same thing will happen in the case of inline CSS. Inline CSS overrides the external and internal CSS. If we add many classes with many properties, yet we only have one ID selector, then that ID selector will have a higher specificity weight than others.

In the example below, we have one external.css file with an identical class to what is mentioned in the internal CSS file. Therefore, when rendered in the browser, internal CSS will override the external CSS .div-color class because of specificity rules, and inline CSS will override the internal CSS .div-color class because inline CSS has a higher priority than internal and internal has more than external.

Tips On How To Effectively Use Selectors and Manage Specificity In CSS


CSS Specificity is the rule applied to CSS selectors to determine which style is applied to which element. The more specific a CSS style is, the higher point value it accrues, and the likelier it is to be present on the element’s style. There are many benefits to understanding CSS Specificity; some of these are important tips to keep in mind to help with effective styling:

CSS can quickly become unruly when we don’t stop to think about architecture for our style sheets and instead throw a ton of CSS selectors around without thinking about specificity. Adopting a CSS naming architecture is one way to combat messy CSS and ensure your specificity rules are being applied as intended. Block-element-modifier (BEM) is one of the most commonly used CSS naming architectures.

It helps you write cleaner and less CSS Code: It’s not uncommon to see a codebase riddled with !important overrides. Although !important gives you a way to say, “Forget all those other styles, I want this one to be applied!!!” it can cause serious issues when you need to update a style, and you’re unsure where to begin. CSS Specificity allows you to include the CSS necessary to style your elements correctly. It’s easier to quickly change a style when you know which selector styles that specific element. Plus, you’ll probably find yourself writing less CSS code overall, which will help with maintainability.

20%

💰 EXTRA 20% OFF ALL VERPEX SHARED WEB HOSTING PLANS

with the discount code

AWESOME

Save Now

Conclusion


In this article, we covered the different types of CSS selectors and their significance. We also delved into the concept of specificity and its impact on CSS coding practices. By understanding how to efficiently utilize CSS selectors and manage specificity, you can achieve a more streamlined, orderly, and maintainable CSS codebase.

Frequently Asked Questions

Can free HTML editors support other languages like CSS and JavaScript?

Yes, free HTML editors often support languages like CSS and JavaScript, enabling integrated web development.

What security measures are essential for CSS hosting?

Key security measures for CSS hosting include SSL/TLS encryption, regular software updates, firewalls, and protection against DDoS attacks. These features safeguard your CSS files and the overall integrity of your website.

How does CSS hosting affect SEO and site performance?

Good CSS hosting improves site loading times, a crucial factor for SEO. Fast loading speeds enhance user experience, which is a significant ranking factor for search engines. Efficient CSS hosting also ensures better uptime, another important aspect for maintaining and improving your site’s SEO ranking.

What is the impact of server location on CSS hosting performance?

Server location significantly affects the loading speed of CSS files. Hosting your CSS closer to your user base ensures faster download times, reducing website latency and improving user experience.

Discount

🚀 90% OFF YOUR FIRST MONTH WITH ALL VERPEX CLOUD WEB HOSTING PLANS

with the discount code

MOVEME

Save Now
Jivo Live Chat