Delving deep into Selectors and Specificity in CSS

Why sometimes the styles applied by you aren't really applied ?


Welcome to Web Delve!

Hey, welcome to the first blog on Web Delve! I'm really glad you decided to click that link and trusted me to value your time while simplifying a concept for you.

Initially, the first episode was supposed to cover CSS combinators. However, I realized that there might be many people at the early stage of their journey who may not be familiar with the basic CSS selectors and how they are used to select different elements based on various needs. That's why the first edition will focus on explaining what CSS selectors are, and in a later edition, I'll delve into CSS combinators. Stay tuned!

Now, without further ado, let's delve into the web!

Applying CSS

Let's get the basics cleared. Whenever you want to style any element, you use CSS. There are three ways to do so:

Inline CSS

Inline CSS involves adding styles directly to an element's style attribute within the HTML document. This method is useful for quick, unique changes but is generally not recommended for larger projects because it can clutter your HTML and make maintenance more difficult.

<body>
  <h1 style="color:blue; text-align:center;">This is a heading</h1>
  <p style="color:red;">This is a paragraph.</p>
</body>

Here, the h1 element is styled to have blue text and centered alignment, while the p element is styled to have red text. Notice how each style is specified within the style attribute directly on the element.

Internal CSS

Internal CSS allows you to define styles in the <style> element within the <head> section of the HTML document. This method is useful for single-page sites or when you need to apply specific styles to a page without affecting other pages.

<head>
  <style>
    h1 {
      color: blue;
      text-align: center;
    }
    p {
      color: red;
    }
  </style>
</head>
<body>
  <h1>This is a heading</h1>
  <p>This is a paragraph.</p>
</body>

With internal CSS, you can see that the styles are centralized in one place within the document's head, making it easier to manage compared to inline CSS.

External CSS

External CSS involves creating a separate CSS file that contains all the styles and linking it to your HTML document. This is the preferred method for larger websites because it keeps the HTML clean and allows you to reuse styles across multiple pages.

index.html

<head>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <h1>This is a heading</h1>
  <p>This is a paragraph.</p>
</body>

styles.css

body {
  background-color: powderblue;
}
h1 {
  color: blue;
  text-align: center;
}
p {
  color: red;
}

Using external CSS, you can maintain a clear separation of concerns, making your codebase more modular and easier to maintain.

CSS Selectors Deep Dive

Let's explore every type of selector you might encounter in your CSS journey. Trust me, knowing these will make you a CSS wizard! πŸ§™β€β™‚οΈ

Basic Selectors

Element Selector

Targets all instances of a specific HTML tag.

p {
  color: green;
}

ID Selector

Targets a single, unique element.

#uniqueElement {
  color: green;
}

Class Selector

Targets elements with a specific class attribute.

.commonStyle {
  color: purple;
}

Universal Selector

Targets all elements in the document.

* {
  margin: 0;
  padding: 0;
}

Attribute Selectors

These powerful selectors let you target elements based on their attributes or attribute values. Here's the fun part:

/* Elements with the exact attribute */
[data-type] {
  background: yellow;
}
 
/* Elements with exact attribute value */
[data-type="primary"] {
  background: blue;
}
 
/* Elements with attribute containing word */
[class~="card"] {
  border: 1px solid gray;
}
 
/* Elements with attribute starting with value */
[class^="btn-"] {
  padding: 10px;
}
 
/* Elements with attribute ending with value */
[href$=".pdf"] {
  color: red;
}
 
/* Elements with attribute containing value */
[class*="container"] {
  max-width: 1200px;
}

Pseudo-classes

Hey, ever wondered how to style elements based on their state or position? That's where pseudo-classes come in! 🎯

/* Link states */
a:link {
  color: blue;
}
a:visited {
  color: purple;
}
a:hover {
  color: red;
}
a:active {
  color: green;
}
 
/* Structural pseudo-classes */
li:first-child {
  font-weight: bold;
}
li:last-child {
  font-style: italic;
}
li:nth-child(2n) {
  background: #f0f0f0;
}
li:nth-of-type(odd) {
  background: #e0e0e0;
}
 
/* Form states */
input:focus {
  border-color: blue;
}
input:disabled {
  background: #ddd;
}
input:checked + label {
  color: green;
}
 
/* Content states */
p:empty {
  display: none;
}
div:not(.excluded) {
  background: #fff;
}

Pseudo-elements

Want to create some cool effects or add content? Pseudo-elements are your friends! 🎨

/* First letter and line */
p::first-letter {
  font-size: 2em;
  font-weight: bold;
}
 
p::first-line {
  font-style: italic;
}
 
/* Before and after elements */
.quote::before {
  content: "πŸ“’";
  margin-right: 5px;
}
 
.quote::after {
  content: """;
  font-size: 1.5em;
}
 
/* Selection styling */
::selection {
  background: yellow;
  color: black;
}
 
/* Placeholder text */
input::placeholder {
  color: #999;
  font-style: italic;
}

The Art of CSS Specificity

Alright, let's talk about something that often confuses even experienced developers - CSS specificity. Think of it as a battle where different selectors compete to style an element. Let me break it down for you! 🎯

Specificity Hierarchy

Here's how the points stack up (from highest to lowest):

  1. Inline Styles (style="...") - 1000 points
  2. ID Selectors (#id) - 100 points
  3. Class Selectors (.class), Attribute Selectors ([type="radio"]), and Pseudo-classes (:hover) - 10 points
  4. Element Selectors (p, div) and Pseudo-elements (::before) - 1 point

Let's see this in action with some examples:

/* Specificity: 1 point */
p {
  color: red;
}
 
/* Specificity: 10 points */
.text {
  color: blue;
}
 
/* Specificity: 11 points (1 + 10) */
p.text {
  color: green;
}
 
/* Specificity: 100 points */
#unique {
  color: purple;
}
 
/* Specificity: 111 points (1 + 10 + 100) */
p.text#unique {
  color: orange;
}

Real-world Specificity Examples

Let's look at some common scenarios:

<p class="text highlight" id="unique" style="color: pink;">
  What color will I be?
</p>
/* Competing styles */
p {
  color: red;
} /* 1 point */
.text {
  color: blue;
} /* 10 points */
p.text {
  color: green;
} /* 11 points */
.highlight {
  color: yellow;
} /* 10 points */
#unique {
  color: purple;
} /* 100 points */
p.text.highlight {
  color: orange;
} /* 21 points */
p#unique.highlight {
  color: brown;
} /* 111 points */

In this case, the inline style (pink) wins because it has the highest specificity (1000 points)!

Specificity Tricks and Tips

Here's something cool - you can combine selectors to increase specificity without using IDs:

/* Instead of using an ID */
#sidebar {
  background: #f0f0f0;
}
 
/* Use multiple classes (more maintainable) */
.sidebar.theme-light.layout-left {
  background: #f0f0f0;
}

And here's a neat trick for when you absolutely need to override something:

/* Using :not() to increase specificity without changing the selected elements */
.button:not(:not(*)) {
  background: blue;
}
 
/* Each additional :not() adds another point! */
.button:not(:not(*)):not(:not(*)) {
  background: red;
}

Conclusion

Whew! That was quite a journey through the world of CSS selectors and specificity! Remember, understanding these concepts isn't just about memorizing syntax - it's about knowing which tool to use when. Think of CSS selectors as your artistic brushes, each one perfect for different situations.

In our next blog post, we'll dive even deeper into advanced CSS techniques, including custom properties (CSS variables), calc() functions, and modern layout techniques with Grid and Flexbox. You won't want to miss it!

Pro Tip: Start simple and gradually add complexity. Don't try to memorize everything at once - build your knowledge through practice and real-world applications.

Hope you liked this deep dive! πŸš€
Until Next Time,
Happy coding! ✨

P.S. Don't forget to try out these selectors in your browser's developer tools. It's the best way to learn! πŸ› οΈ