<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bill Mei</title>
    <description>The latest articles on Forem by Bill Mei (@billmei).</description>
    <link>https://forem.com/billmei</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F203486%2Fc10cf01d-a407-4e61-9099-f794cfa60473.jpg</url>
      <title>Forem: Bill Mei</title>
      <link>https://forem.com/billmei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/billmei"/>
    <language>en</language>
    <item>
      <title>The Definitive Guide to CSS Cascading and Specificity</title>
      <dc:creator>Bill Mei</dc:creator>
      <pubDate>Mon, 12 Aug 2019 16:43:38 +0000</pubDate>
      <link>https://forem.com/billmei/the-definitive-guide-to-css-cascading-and-specificity-3o8o</link>
      <guid>https://forem.com/billmei/the-definitive-guide-to-css-cascading-and-specificity-3o8o</guid>
      <description>&lt;p&gt;&lt;small&gt;This article is an excerpt from &lt;a href="https://www.painlesscss.com/guide-to-css-specificity.html" rel="noopener noreferrer"&gt;&lt;em&gt;Painless CSS&lt;/em&gt;&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Cascading is an important part of Cascading Stylesheets, but it’s often explained poorly and online tutorials lead to more confusion than clarity. I think that’s a shame because there is a vastly more effective mental model I’ve found for explaining CSS Cascading. Instead of thinking about “cascading” or “specificity”, the secret is to imagine it as a “CSS Tournament” instead.&lt;/p&gt;

&lt;p&gt;Tournaments are held to determine the winner of a conflict. &lt;strong&gt;The purpose of the CSS Tournament is to resolve conflicts between two or more CSS properties that are trying to apply the same style onto the same HTML element.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Ftournament-before.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Ftournament-before.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nc"&gt;.maroon&lt;/span&gt;&lt;span class="nf"&gt;#malamute&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.sapphire-shepherd&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nc"&gt;.headline.content&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;#purple-poodle&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;underline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;#teal-terrier&lt;/span&gt;&lt;span class="nc"&gt;.fullpage&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.submit-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fullpage"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"teal-terrier"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"purple-poodle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sapphire-shepherd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"maroon headline content"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"malamute"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"submit-btn"&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          What happens when you hover over me?
        &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;There are four competitors in this tournament. Each competitor submits three entries into this competition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry 1 consists of the number of ID selectors in the CSS rule&lt;/li&gt;
&lt;li&gt;Entry 2 consists of the number of class, attribute, and pseudo-class selectors in the CSS rule&lt;/li&gt;
&lt;li&gt;Entry 3 consists of the number of tag and pseudo-element selectors in the CSS rule&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FIntroduction.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FIntroduction.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The number inside each box represents the count of selectors assigned to that entry.&lt;/p&gt;

&lt;p&gt;Our competitors are fighting over the &lt;code&gt;cursor&lt;/code&gt; CSS property, and these are the declarations in conflict:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cursor: copy;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cursor: wait;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cursor: pointer;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cursor: help;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Winning the &lt;em&gt;CSS Tournament&lt;/em&gt; comes with a glamorous prize: the winner’s &lt;code&gt;cursor&lt;/code&gt; value will apply to the selected &lt;code&gt;button&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s meet the competitors:&lt;/p&gt;

&lt;h3&gt;
  
  
  Competitor 1: Maroon Malamute
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nc"&gt;.maroon&lt;/span&gt;&lt;span class="nf"&gt;#malamute&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This CSS rule has one ID selector (&lt;code&gt;#malamute&lt;/code&gt;), one class selector (&lt;code&gt;.maroon&lt;/code&gt;), one attribute selector (&lt;code&gt;[disabled]&lt;/code&gt;), and two tag selectors (&lt;code&gt;p&lt;/code&gt;, &lt;code&gt;button&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FMaroon-Malamute.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FMaroon-Malamute.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can summarize this competitor’s entries with a single number: &lt;code&gt;122&lt;/code&gt;. This number is also known as the &lt;em&gt;Specificity Level&lt;/em&gt; (or &lt;em&gt;Specificity Score&lt;/em&gt;) of the selector. The higher this score, the higher the specificity.&lt;/p&gt;

&lt;p&gt;Let’s meet the other competitors:&lt;/p&gt;

&lt;h3&gt;
  
  
  Competitor 2: Sapphire Shepherd
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.sapphire-shepherd&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nc"&gt;.headline.content&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FSapphire-Shepherd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FSapphire-Shepherd.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This selector has a specificity score of &lt;code&gt;041&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Competitor 3: Purple Poodle
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#purple-poodle&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;underline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FPurple-Poodle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FPurple-Poodle.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This selector has a specificity score of &lt;code&gt;101&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Competitor 4: Teal Terrier
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#teal-terrier&lt;/span&gt;&lt;span class="nc"&gt;.fullpage&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.submit-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FTeal-Terrier.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FTeal-Terrier.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This selector has a specificity score of &lt;code&gt;121&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tournament Rules
&lt;/h2&gt;

&lt;p&gt;While there is a conflict for &lt;code&gt;cursor&lt;/code&gt;, the declarations below are not in competition with each other. They don’t participate in the tournament and they are all immediately applied as a style onto the &lt;code&gt;button&lt;/code&gt; without needing to participate in the tournament.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;margin: 100px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;padding: 2rem;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;text-decoration: underline;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;line-height: 2.5;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are three rounds to the tournament. In Round 1, all competitors submit their score from Entry 1 into the round. The competitor with the highest score wins that round. Similarly, competitors submit Entry 2 for Round 2, and Entry 3 for Round 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Round 1
&lt;/h3&gt;

&lt;p&gt;For Round 1, we look at the number of ID selectors for all competitors. The competitor with the greatest number of ID selectors wins this round:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-1-Before.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-1-Before.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sapphire Shepherd has no ID selectors, so it is immediately eliminated from Round 1!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-1-After.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-1-After.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once a competitor is eliminated, it doesn’t get to participate in any subsequent rounds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Maroon Malamute, Purple Poodle, and Teal Terrier are tied at 1 ID selector each, so they all move on to Round 2.&lt;/p&gt;

&lt;h3&gt;
  
  
  Round 2
&lt;/h3&gt;

&lt;p&gt;For Round 2, look at the number of class, attribute, and pseudo-class selectors for all remaining competitors. The competitor with the most of these wins this round:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-2-Before.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-2-Before.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even though Sapphire Shepherd has the greatest number of class selectors in this round, it was already eliminated in the previous round, so it doesn’t win! It doesn’t matter if a competitor “could have won” if it stayed in the tournament—once a competitor is eliminated, it’s permanently gone.&lt;/p&gt;

&lt;p&gt;Both Maroon Malamute and Teal Terrier are tied in first place for Round 2, so they move forward to Round 3 and Purple Poodle is eliminated:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-2-After.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-2-After.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Round 3
&lt;/h3&gt;

&lt;p&gt;For Round 3, look at the number of tag and pseudo-element selectors for all remaining competitors. The competitor with the most of these wins the tournament!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-3-Before.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-3-Before.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maroon Malamute has &lt;code&gt;2&lt;/code&gt; tag selectors and Teal Terrier has &lt;code&gt;1&lt;/code&gt; tag selector, so &lt;strong&gt;Maroon Malamute&lt;/strong&gt; wins the tournament!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-3-After.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2FRound-3-After.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final outcome is that the maroon malamute CSS rule “wins” over the others:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nc"&gt;.maroon&lt;/span&gt;&lt;span class="nf"&gt;#malamute&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the declaration &lt;code&gt;cursor: copy&lt;/code&gt; is applied to the selected HTML element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Ftournament-after.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Ftournament-after.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, &lt;code&gt;cursor&lt;/code&gt; was the only CSS property in conflict. If there were more than one property in conflict (say, two or more CSS rules both had different &lt;code&gt;margin&lt;/code&gt; values), then we would run this tournament again for the next property (&lt;code&gt;margin&lt;/code&gt;), starting over from the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shortcut: Specificity Score
&lt;/h2&gt;

&lt;p&gt;Now that you understand the tournament analogy, let’s simplify this whole thing to make it easier to use in practice.&lt;/p&gt;

&lt;p&gt;First, instead of breaking up entries by ID, class, and tag selectors, let’s just assign scores to each CSS rule as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every ID selector is worth 100 points&lt;/li&gt;
&lt;li&gt;Every class, attribute, or pseudo-class selector is worth 10 points&lt;/li&gt;
&lt;li&gt;Every tag or pseudo-element selector is worth 1 point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, we’ll add up all the scores for each competitor:&lt;/p&gt;

&lt;h4&gt;
  
  
  Competitor 1: Maroon Malamute
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;p.maroon#malamute button[disabled] {}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(1 × 100) + (2 × 10) + (2 × 1) = 122&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Maroon Malamute has &lt;code&gt;122&lt;/code&gt; points.&lt;/p&gt;

&lt;h4&gt;
  
  
  Competitor 2: Sapphire Shepherd
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;.sapphire-shepherd p.headline.content button[disabled] {}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(0 × 100) + (4 × 10) + (1 × 1) = 41&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sapphire Shepherd has &lt;code&gt;041&lt;/code&gt; points.&lt;/p&gt;

&lt;h4&gt;
  
  
  Competitor 3: Purple Poodle
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;#purple-poodle button {}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(1 × 100) + (0 × 10) + (1 × 1) = 101&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Purple Poodle has &lt;code&gt;101&lt;/code&gt; points.&lt;/p&gt;

&lt;h4&gt;
  
  
  Competitor 4: Teal Terrier
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;#teal-terrier.fullpage button.submit-btn {}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(1 × 100) + (2 × 10) + (1 × 1) = 121&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Teal Terrier has &lt;code&gt;121&lt;/code&gt; points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Specificity Rank
&lt;/h3&gt;

&lt;p&gt;Next, instead of going through the tournament round by round, let’s just sort all the specificity scores for each of our competitors from highest to lowest:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;122&lt;/code&gt; points: Maroon Malamute&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;121&lt;/code&gt; points: Teal Terrier&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;101&lt;/code&gt; points: Purple Poodle&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;041&lt;/code&gt; points: Sapphire Shepherd&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Who’s the winner? Simple! The winner of the tournament is the competitor with the highest score: Maroon Malamute. Another neat fact is that reading this list from bottom to top is the order in which the competitors were eliminated! So Sapphire Shepherd was eliminated first, then Purple Poodle was eliminated second, then Teal Terrier was eliminated third.&lt;/p&gt;

&lt;p&gt;“Wait a sec,” you may ask, “why did you go through the trouble of explaining the whole tournament analogy when this ranking method is so much easier?” Well, that’s because this shortcut of sorting the specificity scores doesn’t work when you have more than 9 classes (or tags, or IDs, etc.) on an element. Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.big.big.big.big.big.big.big.big.big.big.big.big.big&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;xx-large&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.medium.medium&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;medium&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;#x-small&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;x-small&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"medium big"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"x-small"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  What size am I?
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the “scores”:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.big.big.big.big.big.big.big.big.big.big.big.big.big {}&lt;/code&gt; has a score of &lt;code&gt;(13 × 10) = 130&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.medium.medium {}&lt;/code&gt; has a score of &lt;code&gt;(2 × 10) = 20&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#x-small {}&lt;/code&gt; has a score of &lt;code&gt;(1 × 100) = 100&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You would expect the size of the element to be &lt;code&gt;xx-large&lt;/code&gt;, but it is in fact &lt;code&gt;x-small&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-087.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-087.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the original tournament analogy, the rounds (and entries) are separate from each other. The shortcut ranking method doesn’t work for more than 9 classes because the moment you add the 10th class to a selector which already has a score of 90, its score becomes 100 and it “overpowers” the ID selector, which shouldn’t happen. This problem occurs because we’re using a base-10 counting system, and you could avoid it by changing the base, but at that point it’s much simpler just to use the tournament analogy as your mental model.&lt;/p&gt;

&lt;p&gt;Luckily, in practice we usually don’t write more than 9 selectors in a CSS rule, so our shortcut of adding together all the specificity scores works handily for most situations you encounter in the real world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exceptions to the Tournament
&lt;/h2&gt;

&lt;p&gt;Normally the winner of the tournament is the CSS declaration that gets rendered; but there are certain exceptions where a declaration that is not the winner gets rendered instead:&lt;/p&gt;

&lt;h3&gt;
  
  
  Inline Styles
&lt;/h3&gt;

&lt;p&gt;Any inline styles on an HTML element (where you write your CSS directly on the HTML element using the &lt;code&gt;style&lt;/code&gt; attribute, instead of using a separate stylesheet) automatically override any winners of the tournament. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#bold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-weight: normal;"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  This text is not bold.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-088.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-088.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to the reasons I described in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Chapter 6&lt;/a&gt; of the &lt;em&gt;Painless CSS&lt;/em&gt; book, this is another reason why we try to avoid inline styles: they can’t be overwritten by any CSS rules we write in our stylesheets.&lt;/p&gt;

&lt;p&gt;Counterintuitively, using inline styles can be a &lt;em&gt;best practice&lt;/em&gt; in certain situations when you coding for a front-end framework such as React, Vue, or Angular. I have a discussion about this later in &lt;a href="https://www.painlesscss.com/guide-to-css-specificity.html#beyond-cascading" rel="noopener noreferrer"&gt;Beyond Cascading&lt;/a&gt;. For now, we’ll avoid using inline styles. &lt;/p&gt;

&lt;p&gt;This is an exception to this exception! While inline styles override the tournament winners, any declarations that use the &lt;code&gt;!important&lt;/code&gt; keyword will override an inline style.&lt;/p&gt;

&lt;h3&gt;
  
  
  !important
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;!important&lt;/code&gt; is a special keyword in CSS that makes your declaration &lt;em&gt;always&lt;/em&gt; win the tournament, no matter what, &lt;em&gt;even if there are inline styles on the element&lt;/em&gt;! It looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#not-bold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-weight: normal;"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"not-bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  This text IS bold.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-089.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-089.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We avoid using &lt;code&gt;!important&lt;/code&gt; in our CSS because it can’t be overwritten.&lt;sup&gt;&lt;a href="https://www.painlesscss.com/guide-to-css-specificity.html#footnotes" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;&lt;/sup&gt; If you change your mind later, you can’t overpower it with a different rule; you have to remove the &lt;code&gt;!important&lt;/code&gt; and then also check every &lt;em&gt;other&lt;/em&gt; rule for that element to make sure nothing else breaks, because usually the reason an &lt;code&gt;!important&lt;/code&gt; was added in the first place was to unbreak some buggy code.&lt;/p&gt;

&lt;p&gt;The true nightmare of a CSS author is to open up a CSS file and see &lt;code&gt;!important&lt;/code&gt; sprinkled everywhere! Selectors in this kind of situation are called &lt;em&gt;Overspecified&lt;/em&gt; or &lt;em&gt;Overpowered&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is also why I recommend avoiding IDs for CSS styling, because IDs are also highly powered. No matter how many CSS classes you write, you cannot override an ID.&lt;/p&gt;

&lt;p&gt;The tournament analogy gives us an intuitive sense for why overpowered selectors are bad. If a selector is enormously powerful in the tournament, it wins faster and at earlier rounds, meaning the only way to beat a powerful selector is to write another style that is even more highly powered.&lt;/p&gt;

&lt;p&gt;This tendency for specificity to always escalate is known as a &lt;em&gt;specificity war&lt;/em&gt;. Like stockpiling nuclear weapons, no one wins at this war—it only becomes harder to de-escalate as specificity increases. The only way to avoid an all-out specificity war is to not stockpile highly powered selectors in the first place.&lt;sup&gt;&lt;a href="https://www.painlesscss.com/guide-to-css-specificity.html#footnotes" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tied until the end
&lt;/h3&gt;

&lt;p&gt;What if we reach the last round of the tournament, and there is still a tie?&lt;/p&gt;

&lt;p&gt;If we get to the end of the tournament and there is still a tie, then the final tiebreaker is the location of the CSS rule in the source CSS file. Anything that is written later (nearer to the bottom of the file) will win over anything that is written earlier (nearer to the top of the file).&lt;/p&gt;

&lt;p&gt;If you import multiple CSS files into your HTML document, (e.g. you have multiple &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tags), then it’s the last file (nearer to the bottom of the HTML document) that wins the tie. Thus, the tournament can never be tied all the way through, because the final tiebreaker is the physical location of the code, and this is always unique.&lt;/p&gt;

&lt;p&gt;This is also how duplicate declarations are resolved; if you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but then later in the same file you write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;color: blue&lt;/code&gt; will get applied to your &lt;code&gt;span&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thus, the order in which you import any third-party CSS files is important, (e.g. using &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tags, or &lt;code&gt;@import&lt;/code&gt;) because changing the order will change the outcome of the last tiebreaker. In practice, this means the first thing we import is our &lt;code&gt;normalize.css&lt;/code&gt; or &lt;code&gt;reset.css&lt;/code&gt; file for standardizing the User Agent Stylesheet, followed by any third-party CSS frameworks such as Foundation or Bootstrap, followed by our own site-specific code.&lt;/p&gt;

&lt;p&gt;The tiebreaker rule is why I recommend &lt;em&gt;against&lt;/em&gt; tag selectors and encourage you to use class selectors instead, because tag selectors are &lt;em&gt;underspecified&lt;/em&gt;. Tag selectors have the lowest power, so they are too sensitive to their order in your CSS file, and your design can break if you ever re-order your imports, as the tiebreaker outcome will change in a re-ordering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inheritance
&lt;/h3&gt;

&lt;p&gt;Inherited properties are always given a specificity score of &lt;code&gt;000&lt;/code&gt;, no matter what their original specificity was.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#powerful&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.unpowerful&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"powerful"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-weight: bold;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"unpowerful"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;CSS rules everything around me&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;font-weight&lt;/code&gt; is an inherited property on the child, it doesn’t matter that the parent is both a highly powered ID selector and has an &lt;code&gt;!important&lt;/code&gt;, the &lt;code&gt;.unpowerful&lt;/code&gt; selector will win in this situation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-090.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-090.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, if we change our HTML so that the ID &lt;code&gt;#powerful&lt;/code&gt; becomes non-inherited,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"unpowerful"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"powerful"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    CSS rules everything around me
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then the ID will win as expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-091.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-091.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The “generational distance” (whether the property was inherited from a parent, or a grandparent) doesn’t matter—only CSS selectors that directly select your element have a specificity greater than &lt;code&gt;000&lt;/code&gt;. Only when there are &lt;em&gt;no&lt;/em&gt; CSS rules directly selecting your HTML element will parents win over grandparents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"powerful"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"unpowerful"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;CSS rules everything around me&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-090.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-090.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Universal Selector
&lt;/h3&gt;

&lt;p&gt;The Universal Selector &lt;code&gt;*&lt;/code&gt; has a specificity of &lt;code&gt;000&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Participants
&lt;/h3&gt;

&lt;p&gt;Keep in mind that the tournament only applies to properties in conflict in each other on a &lt;em&gt;selected&lt;/em&gt; element—if two selectors don’t select the same element, then they are not in conflict. For example, what color will the button background be?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Specificity: 001 */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;orange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="nc"&gt;.submit-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Specificity: 011 */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"submit-btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;What color am I?&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-093.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-093.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer is it will be &lt;code&gt;orange&lt;/code&gt;! This is because the selector &lt;code&gt;button .submit‑btn&lt;/code&gt; is not selecting our element (it would have selected any &lt;em&gt;children&lt;/em&gt; of a button with a class of &lt;code&gt;.submit‑btn&lt;/code&gt;), and despite its higher power, it does not even participate in the tournament! If the second selector had instead been &lt;code&gt;button.submit‑btn&lt;/code&gt; (notice the lack of a space), then the button background color will indeed be &lt;code&gt;green&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also keep in mind that a tournament is not needed when properties are not fighting each other. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.welcome-message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;salmon&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;seashell&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#headline&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lavender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"headline"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"welcome-message"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Welcome to my blog
&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;color&lt;/code&gt; and &lt;code&gt;margin-top&lt;/code&gt; are talking about different things, so they can both apply to the same element at the same time because they’re not fighting each other. However, &lt;code&gt;background-color&lt;/code&gt; is in a fight, so for this property we use the tournament to find a winner. &lt;code&gt;#headline&lt;/code&gt; wins the tournament against &lt;code&gt;.welcome-message&lt;/code&gt; so the element is given a &lt;code&gt;background-color&lt;/code&gt; of &lt;code&gt;lavender&lt;/code&gt;. The final set of properties applied to our &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;color: salmon;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;margin-top: 0;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;background-color: lavender;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-094.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-094.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Combinators
&lt;/h3&gt;

&lt;p&gt;Combinators are ignored in our tournament. To determine the winner of a round, we follow only the scoring rules laid about above. You would think that changing from a broad selector like &lt;code&gt; &lt;/code&gt; (the descendent combinator) to a more narrow selector like &lt;code&gt;&amp;gt;&lt;/code&gt; (the child combinator) would change the outcome of the tournament, but combinators only affect whether or not the CSS rule is eligible to participate in the tournament in the first place (since it changes whether or not our element is actually selected), and they do nothing to the specificity scores.&lt;/p&gt;

&lt;p&gt;Here’s an example; what color will our text be?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;firebrick&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;aquamarine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;span&amp;gt;&lt;/span&gt;What color am I?&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-095.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-095.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer is the text will be &lt;code&gt;aquamarine&lt;/code&gt;! It totally seems like &lt;code&gt;p &amp;gt; span&lt;/code&gt; should win because the extra child combinator &lt;code&gt;&amp;gt;&lt;/code&gt; makes it look “more specific” since it’s narrowing down to &lt;em&gt;direct&lt;/em&gt; children instead of &lt;em&gt;all&lt;/em&gt; descendants, but the &lt;code&gt;&amp;gt;&lt;/code&gt; does not affect any of the specificity scores, so when we run the tournament we have a score of &lt;code&gt;002&lt;/code&gt; competing against a score of &lt;code&gt;002&lt;/code&gt;. Since the result of this tournament is a tie, the last selector &lt;code&gt;p span&lt;/code&gt; wins because of the tiebreaker rule, and our text is given a color of &lt;code&gt;aquamarine&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This example reveals the problem with the classical way of thinking about cascading. The popular explanation of comparing the CSSOM to how the HTML DOM is constructed will mislead you in this example because the structure of the tree has nothing to do with the results of our tournament.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Painless CSS Tournament
&lt;/h2&gt;

&lt;p&gt;Here is a summary of what we learned, which I shall refer to later as the &lt;em&gt;Painless CSS Tournament&lt;/em&gt;: the bottom-up model where we take the perspective of the HTML element, instead of the perspective of the browser rendering engine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Look at each element one by one, ask “what CSS rules apply to you?”&lt;/li&gt;
&lt;li&gt;Look at all the rules you found in Step 1, and list all the properties that apply from those rules (e.g. include all inherited properties and discard any non-inherited properties from parents).&lt;/li&gt;
&lt;li&gt;From the list of properties in Step 2, immediately apply all declarations which are not in a fight. You are left with a smaller list of properties which are in a fight.&lt;/li&gt;
&lt;li&gt;Going property by property, resolve each fight by using the tournament rules.&lt;/li&gt;
&lt;li&gt;And now you’re done!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Compare this to the classical (popular) way of explaining CSS cascading described in &lt;a href="https://www.painlesscss.com/" rel="noopener noreferrer"&gt;Chapter 9 of the book&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse the CSS and construct the CSSOM.&lt;/li&gt;
&lt;li&gt;“Cascade” rules through the CSSOM down to all elements, keeping track of which rules apply to what element using a tree.&lt;/li&gt;
&lt;li&gt;From the tree generated in Step 2, apply all declarations to their associated node on the tree.&lt;/li&gt;
&lt;li&gt;If there are any conflicts between properties, resolve the fight by comparing specificity scores.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The disadvantage of the top-down model is it does not help us debug CSS issues with individual elements. In the top-down model, we must go through the entire CSSOM to figure what styles are associated to a specific HTML element, and we can’t easily visualize the CSSOM tree in our heads.&lt;/p&gt;

&lt;p&gt;In contrast, it’s much easier to focus on one individual element and ask, “what CSS rules apply to you?” then go off and find those. In fact, the developer tools in your browser allow you do exactly this using the “Inspect” or “Inspect Element” feature, which will helpfully find all the rules associated with an element without you needing to go through the entirety of your website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-096.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-096.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;orchid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;seagreen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.command&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;royalblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.command&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;sienna&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nc"&gt;.command&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;aqua&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;#lasers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;hotpink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"command"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lasers"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Activate lasers!
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All CSS rules that apply to the inspected element show up conveniently in a list in the sidebar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-097.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-097.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even though it’s called “Cascading Style Sheets”, I like to disregard the whole “Cascading” concept and just think about it in terms of each element’s specificity score, and how that affects the outcome of the tournament.&lt;/p&gt;

&lt;h2&gt;
  
  
  After the Tournament
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Order of elimination
&lt;/h3&gt;

&lt;p&gt;Something cool you may have noticed when you opened the developer tools panel: the list of CSS rules we see is ordered according to where they finished in the tournament!&lt;/p&gt;

&lt;p&gt;You can think of this panel as a “leaderboard” for the tournament, where the 1st place winner of the tournament shows up at the top, then the selector below that is the 2nd place winner, and so forth.&lt;sup&gt;&lt;a href="https://www.painlesscss.com/guide-to-css-specificity.html#footnotes" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-098.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-098.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This becomes clear when you use the panel to disable styles. You can click on the checkbox beside any declaration to enable or disable it. If I disable the declaration that won 1st place, then the 2nd place declaration is the “winner” of the tournament instead, so it becomes the style that is applied to the HTML element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-099.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.painlesscss.com%2Fblog-images%2Fdiagram-099.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can take advantage of this ordering when debugging. To find a specific declaration, you should start at the top and then work your way down to understand what’s going on, because it’s more likely that the final property that survived the tournament is near the top.&lt;/p&gt;

&lt;p&gt;Once you find the declaration you’re looking for, you can stop there and you don’t need to continue scrolling down to the bottom, because anything nearer the bottom will have already lost the tournament long ago, meaning that you’re wasting your time if you keep scrolling—especially when debugging a large website with thousands of styles.&lt;/p&gt;

&lt;p&gt;If you’ve scrolled all the way to the bottom and still can’t find your declaration, remember to check the user agent stylesheet in the gray area! It may be that you forgot to style your component and the default style is being applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond Cascading: CSS-in-JS
&lt;/h2&gt;

&lt;p&gt;If you’re thinking to yourself, “this seems very complicated and a lot of work to keep track of”, I agree with you!&lt;/p&gt;

&lt;p&gt;To address this, the community invented CSS-in-JS libraries and inline style frameworks. Cascading, selectors, inheritance, and specificity are some of the hardest concepts about CSS to understand, so lots of developers sidestep the problem by using a library which abstracts away all of this, so you never have to worry about it again. These frameworks also give you other benefits such as code modularity (by removing the CSS global scope) and the ability to hook into automated tests.&lt;/p&gt;

&lt;p&gt;For more info about the benefits of a CSS-in-JS library, I recommend watching &lt;a href="https://www.youtube.com/watch?v=19gqsBc_Cx0" rel="noopener noreferrer"&gt;this talk by Max Stoiber&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Inline style frameworks highlight why you should not learn by memorizing knowledge from dogma. Some experienced developers have a visceral negative reaction to hearing “inline styles”, because they were taught early in their career the best practice to “never use inline styles”. Even I told you not to do it in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Chapter 6 of the book&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Indeed, “never use inline styles” was a best practice a long time ago when it made HTML hard to read, hard to debug, and hard to change. However, the technology chugs along and eventually upends the assumptions that lead to these “best practices”. New assumptions lead to new best practices.&lt;/p&gt;

&lt;p&gt;Inline styles are only painful when you write them by hand—but if you use a CSS-in-JS library to manage your inline styles for you, these downsides disappear, and you are left only with the advantages of code modularity, automated testing, and simple management that works hand-in-hand with a front-end JavaScript framework such as React.&lt;/p&gt;

&lt;p&gt;If you are stuck with the dogma of “never use inline styles”, you won’t have the curiosity to explore what it means when the original assumptions changed. This is why I’ve structured this book to encourage you to learn to reason for yourself using the &lt;a href="https://www.painlesscss.com/#toc" rel="noopener noreferrer"&gt;Five Steps to Painless CSS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After you’ve learned a framework like React, Angular or Vue, you can come back and learn a CSS-in-JS library to use in your projects. As of this writing (in 2019), the most popular framework that I recommend for CSS-in-JS is &lt;a href="https://www.styled-components.com/" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, if you don’t have to use the cascading or specificity rules by installing a CSS‑in‑JS framework, why learn cascading or specificity at all? I think these are still useful concepts to learn because while your CSS-in-JS framework can protect you from the perils of cascading 99% of the time, the 1% of the time when you encounter a horrible career-ending bug, you can have the confidence to fix it and save your career instead (true story).&lt;/p&gt;

&lt;p&gt;Keep in mind that not every website uses a CSS-in-JS framework, and for smaller websites you may not want to go through the trouble of setting up one, especially because it requires integration into a larger JavaScript framework such as React or Vue. In these situations, plain vanilla CSS works simply fine.&lt;/p&gt;

&lt;p&gt;Finally, the last reason why I think it’s still useful to learn all this, is because… umm well… “cascading” is right there in the name: &lt;em&gt;Cascading Style Sheets&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this article, and that it demystified CSS specificity and cascading for you. This article is an excerpt from &lt;em&gt;Painless CSS&lt;/em&gt;, a book and video course that teaches you CSS from first principles. You can learn more at &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="http://www.painlesscss.com" rel="noopener noreferrer"&gt;www.painlesscss.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>design</category>
    </item>
    <item>
      <title>Top 10 most deadly CSS mistakes made by new and experienced developers</title>
      <dc:creator>Bill Mei</dc:creator>
      <pubDate>Mon, 29 Jul 2019 19:00:18 +0000</pubDate>
      <link>https://forem.com/billmei/top-10-most-deadly-css-mistakes-made-by-new-and-experienced-developers-100d</link>
      <guid>https://forem.com/billmei/top-10-most-deadly-css-mistakes-made-by-new-and-experienced-developers-100d</guid>
      <description>&lt;p&gt;For years, I've seen numerous engineers working at my clients make the same common mistakes with Cascading Stylesheets (CSS). Even the talented, experienced engineers make these mistakes despite their expertise across broad technical areas because they haven't dedicated time to learning CSS the same way they dedicated time to learning algorithms in university.&lt;/p&gt;

&lt;p&gt;I think CSS is perceived as an unintuitive and difficult language to work with because of these common mistakes that thwart most developers when they try to write CSS. If you can avoid these mistakes, you'll see that CSS is actually a straightforward, easy-to-understand language that doesn't deserve its reputation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What follows are the top 10 most deadly mistakes I've seen engineers make throughout my consulting engagements&lt;/strong&gt;, listed in increasing order of severity. The more serious the mistake, the harder it is to recover from without a complete re-write of the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #10: Following the &lt;a href="https://en.wikipedia.org/wiki/Document_Object_Model" rel="noopener noreferrer"&gt;DOM&lt;/a&gt; when writing selectors
&lt;/h2&gt;

&lt;p&gt;Let's take this HTML page as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"main-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blog-row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blog-col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This link is not bold&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This link is bold&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This link is not bold&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some developers like to maintain a minimalist ethos where they try not to clutter up the HTML with lots of classes, by using the DOM structure as a guide to writing CSS selectors, so that their selectors follow the structure of the DOM tree like so:&lt;/p&gt;

&lt;h5&gt;
  
  
  🚫 Mistake
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.main-content&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.blog-row&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.blog-col&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.bold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Preprocessors like &lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;SASS&lt;/a&gt; make this especially tempting because they make it easy and natural to nest selectors:&lt;/p&gt;

&lt;h5&gt;
  
  
  🚫 Mistake
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sass"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt;
    &lt;span class="nc"&gt;.main-content&lt;/span&gt;
      &lt;span class="nc"&gt;.blog-row&lt;/span&gt;
        &lt;span class="nc"&gt;.blog-col&lt;/span&gt;
          &lt;span class="nt"&gt;section&lt;/span&gt;
            &lt;span class="nt"&gt;article&lt;/span&gt;
              &lt;span class="nt"&gt;p&lt;/span&gt;
                &lt;span class="nt"&gt;a&lt;/span&gt;
                  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this "minimalism" is misguided because by keeping the HTML “clean”, you end up cluttering the CSS and making it harder to understand, debug, and change. Your CSS becomes inflexible, as the long combinator chains force the CSS to take on the job of replicating the structure of HTML, but that’s not the job that CSS is supposed to do.&lt;/p&gt;

&lt;p&gt;The job of CSS is to provide styling, and the job of HTML is to provide the structure. &lt;strong&gt;Just because the DOM tree looks one way does not mean the CSS should match it&lt;/strong&gt;—the way you write CSS should be totally independent of the HTML. If you decide to change the structure of the HTML, then you’ll have to go back and update every combinator chain you’ve made in CSS as well, which is painful, error-prone, and adds unnecessary work.&lt;/p&gt;

&lt;p&gt;Instead, I recommend using targeted classes on your elements whenever possible. If you need to cherry-pick a specific element out of your page, a class selector can do the job just fine:&lt;/p&gt;

&lt;h5&gt;
  
  
  ✅ Correct
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Now if you ever change your mind about the ordering of the links on the page, you don’t need to re-write your entire CSS rule. You can simply move the &lt;code&gt;.bold&lt;/code&gt; class onto the element you desire.&lt;/p&gt;

&lt;p&gt;Luckily, this mistake is less of an issue if you use a CSS-in-JS implementation. However, CSS-in-JS is not yet widely adopted (as of 2019) and I still see unnecessarily chained selectors in codebases that do not use any preprocessors.&lt;/p&gt;

&lt;p&gt;More generally, you should avoid overly targeted or overspecified selectors, and also avoid using &lt;code&gt;!important&lt;/code&gt;. The &lt;a href="https://www.painlesscss.com/guide-to-css-specificity.html" rel="noopener noreferrer"&gt;CSS Specificity Tournament&lt;/a&gt; gives us an intuitive sense of why overpowered selectors are bad. If a selector is enormously powerful in the tournament, it wins faster and at earlier rounds, meaning the only way to beat a powerful selector is to write another selector that is even more highly powered.&lt;/p&gt;

&lt;p&gt;This tendency for specificity to always escalate is known as a &lt;em&gt;specificity war&lt;/em&gt;. Like stockpiling nuclear weapons, no one wins at this war—it only becomes harder to de-escalate as specificity increases. The only way to avoid an all-out specificity war is to not stockpile highly powered selectors in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #9: Ignoring SEO when writing HTML
&lt;/h2&gt;

&lt;p&gt;Search Engine Optimization (SEO) is not simply a task you offload to your offshore marketing team once you're done coding. SEO should be something you take into account while you're coding, especially because some factors that affect SEO are hard to change once they are already implemented in production; for example, your site's URL scheme or your services architecture.&lt;/p&gt;

&lt;p&gt;One thing that impacts SEO in the HTML itself is making sure you use &lt;em&gt;semantic tags&lt;/em&gt;, because your choice of tags affects how search engines understand and rank your content. &lt;strong&gt;If you want to show up near the top of the search results, choosing the right tags is one of the first places to start&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, let's say you are writing a blog post about real estate prices in Toronto. You could just put everything into &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements; however, a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; is a generic, unsemantic tag which doesn't imply any inherent meaning in the content. Instead, you should pick a more specific, semantic tag such as &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; to contain the article, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; to contain some links to other blog posts, and &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; to contain the tabular data about real estate prices.&lt;/p&gt;

&lt;p&gt;The advantage of choosing more specific, semantic tags over generic, unsemantic tags is that you are giving search engines more information about your website, which allows the search engine crawler to better understand and deliver content relevant to a reader's search query.&lt;/p&gt;

&lt;p&gt;Let's take a look at headers, for example. There are six potential header tags, in order from most important header to least important header:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h4&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h5&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; is your most important header, because it is a special signal to the search engine that this is the headline or title of your content (there is also the &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag, but most search engines take both into consideration). Additionally, if your user is vision impaired and uses a screen reader, most screen readers know to read &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;s aloud straight away because it is assumed that this is the headline of your content.&lt;/p&gt;

&lt;p&gt;This means that if you use an &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; for anything that is not a headline, or if you have &lt;em&gt;more than one&lt;/em&gt; &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; on a page, the search engine will be confused, and your "real" headline may not show up in the search results.&lt;/p&gt;

&lt;p&gt;The exception to this is when you nest multiple &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;s in different sections. Take the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;My cool blog post&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This blog is so cool!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Contact Us&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Tel: 867-5309&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though there are two &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;s on this page, the first one has a parent of &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; and the other one has a parent of &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;. Since the search engine understands that the &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; is inherently more interesting and important than the &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, it can appropriately use the &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;'s &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag instead of the &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;'s &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag to determine the headline. So in a certain sense, it matters who your parents are, to determine how important you are. Just like in real life. 😉&lt;/p&gt;

&lt;p&gt;There are many more factors that influence your search engine ranking beyond the ones mentioned. To stay on topic in this article, I encourage you to read a book on SEO if you're interested in learning about this topic in more detail. (How do you determine what is the best book on SEO? I wonder if it makes sense to just grab whatever one shows up first on Google. xkcd.com/125)&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #8: Using &lt;code&gt;px&lt;/code&gt; units
&lt;/h2&gt;

&lt;p&gt;Actually, using &lt;code&gt;px&lt;/code&gt; units is fine in certain cases. The real mistake is &lt;strong&gt;using absolute instead of relative units&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We prefer using relative measurements such as &lt;code&gt;em&lt;/code&gt; (The length of an &lt;a href="https://en.wikipedia.org/wiki/Em_(typography)" rel="noopener noreferrer"&gt;Em&lt;/a&gt;), &lt;code&gt;%&lt;/code&gt; (percent), &lt;code&gt;rem&lt;/code&gt; (root-Em), and others whenever possible. This ensures that the website scales proportionally according to your choice of font, and according to the user’s choice of zoom level.&lt;/p&gt;

&lt;h5&gt;
  
  
  🚫 Mistake
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  ✅ Correct
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;The problem with using absolute units like &lt;code&gt;px&lt;/code&gt; is that every user has a different monitor size, and their browser windows (viewports) also have assorted sizes. &lt;strong&gt;This is counterintuitive because in almost every other realm of our lives, like interior decorating, city planning, or baking, we always deal with absolute measures&lt;/strong&gt;. But on the web, the canvas that we’re painting on will suddenly change proportions every time a new person looks at it.&lt;/p&gt;

&lt;p&gt;This makes it impossible for your website to always have the same proportions everywhere, so you must try to place your elements in relative terms (brick B should be as big as brick A) instead of absolute terms (brick B is a 200px-by-400px rectangle); otherwise the available space on the screen does not scale appropriately to every window size. Relative units make this easy—&lt;code&gt;px&lt;/code&gt; locks your design to a specific zoom level and makes your design hard to scale to different devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #7: Trying to achieve a “Pixel Perfect” design
&lt;/h2&gt;

&lt;p&gt;More generally, “Pixel Perfect” design is a bad goal to aim for when writing CSS.&lt;/p&gt;

&lt;p&gt;Modern websites must work across a variety of devices (mobile, desktop, tablet, and watches), of which there is a cornucopia of screen sizes, screen resolutions, operating systems, user settings, and JavaScript engines that interfere with your ability to render “Pixel Perfect” designs.&lt;/p&gt;

&lt;p&gt;In my opinion, a cultish pursuit of “Pixel Perfect” design will cost you in significant extra code complexity to deal with these inconsistent rendering schemes (along with the increased risks of bugs that result from complex code) for a small benefit that will probably get washed out once the next generation of devices, operating system versions, and browser versions get released.&lt;/p&gt;

&lt;p&gt;In practice, the only situations where it makes business sense to pursue this kind of design perfection occur when you are a large company like Apple or Google and have the resources (money) to pay large design teams to make 0.01% improvements in the design. &lt;strong&gt;But unless your business also makes $400,000 per minute, a 0.01% improvement won't earn you millions more dollars more year—instead, it'll just create unnecessary engineering complexity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don’t confuse a “Pixel Perfect” design for great design. Truly great design is about leaving an emotional impact on the user that lasts with them. It’s the delight they get when they unbox your product and the joy they get from engaging with your website. It’s not the adoration of your choice of a 16pt font instead of a 15pt font.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #6: Breaking the document flow
&lt;/h2&gt;

&lt;p&gt;The tricky part about CSS is you can write different CSS code to achieve the same visual result. For example, to horizontally center an element on a page, you could use any of the following techniques, and they'll all look the same to the user:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Surround the element with &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt; until it looks centered&lt;/li&gt;
&lt;li&gt;Explicitly set the &lt;code&gt;width&lt;/code&gt; and left &lt;code&gt;margin&lt;/code&gt; of the element to a fixed value that makes it look centered.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;text-align: center&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;margin: 0 auto&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use a combination of &lt;code&gt;float&lt;/code&gt;ed siblings and a clearfix.&lt;/li&gt;
&lt;li&gt;Use a combination of &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, and &lt;code&gt;transform&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Which technique is best? Depending on your goals, it may be perfectly correct to use &lt;em&gt;any&lt;/em&gt; of the above techniques.&lt;/p&gt;

&lt;p&gt;Generally speaking, there are some rules of thumb we try to follow to select the best layout method.&lt;/p&gt;

&lt;p&gt;First, we eliminate any technique that uses absolute measures instead of relative measures. This means #1 &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt; and #2 explicitly setting the &lt;code&gt;width&lt;/code&gt; are out.&lt;/p&gt;

&lt;p&gt;Second, we prefer techniques that do &lt;em&gt;not&lt;/em&gt; modify the document flow over techniques that break the document flow. This is because elements follow the document flow by default, so if you break this default assumption, you'll make it harder for your co-workers (or yourself, 6 months from now) to understand what's going on. This means #5 &lt;code&gt;float&lt;/code&gt; and #6 &lt;code&gt;position&lt;/code&gt; are out.&lt;/p&gt;

&lt;p&gt;More generally, we prefer techniques that require as little change to other things as possible. Keeping your footprint small helps you avoid sprawling, complicated code that is hard to maintain.&lt;/p&gt;

&lt;p&gt;Technique #3, &lt;code&gt;text-align: center&lt;/code&gt; works only on inline elements, so we'll choose #3 whenever our HTML is already an inline element, and we avoid the extra need to add a &lt;code&gt;display: inline&lt;/code&gt; CSS declaration.&lt;/p&gt;

&lt;p&gt;Technique #4, &lt;code&gt;margin: 0 auto&lt;/code&gt; works only on block elements, so we'll choose #4 whenever our HTML is already a block element, and we avoid the extra need to add a &lt;code&gt;display: block&lt;/code&gt; CSS declaration.&lt;/p&gt;

&lt;p&gt;Breaking the document flow too frequently (e.g. overzealously using &lt;code&gt;float&lt;/code&gt;) increases your footprint and makes your layout harder to understand. When there are multiple options to write CSS code to achieve the same visual result, we prefer using techniques that have a smaller footprint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #5: Not separating design from layout
&lt;/h2&gt;

&lt;p&gt;The job of CSS is to provide styling, and the job of HTML is to provide the structure. Generally, you should first write HTML in a way that captures the information hierarchy of the page, ignoring any design concerns. Afterwards, you can add CSS to make things look nice.&lt;/p&gt;

&lt;p&gt;While HTML provides structure, it cannot always position elements on the exact spot of a page you want it to appear. Thus, you can use CSS to scaffold the correct layout of the page so that the elements appear in the right location. Once an element is placed into the right place on the page, it’s easy to dress it up after and make it look nice without worrying about its location, so &lt;strong&gt;you should think of the “layout CSS” as a different job from the “lipstick CSS”&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  🚫 Mistake
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.sidebar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"article"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"article sidebar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  ✅ Correct
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Layout */&lt;/span&gt;
&lt;span class="nc"&gt;.article&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.sidebar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.sidebar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Lipstick */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"article card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sidebar card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Making sure to keep the job of "lipstick" separate from the job of "layout" is also known as &lt;em&gt;separation of concerns&lt;/em&gt;, and this is a common software engineering principle that helps keep our code maintainable and easy-to-understand.&lt;/p&gt;

&lt;p&gt;We want to use the appropriate tool for the job because separating our CSS in this manner makes it easy to move an element to another part of the page without smudging the lipstick, and also makes it easy to change the color of the lipstick without disrupting the layout. Mixing the two forces us to do both jobs every time we add a new feature, even if it only warrants one job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #4: Designing for desktop before mobile
&lt;/h2&gt;

&lt;p&gt;Gone are the days where mobile websites were an optional extra tacked on by development agencies to pad invoices. Most people now surf the web on their phones and it's common to see more than 50% of your web traffic come from phones and tablets.&lt;/p&gt;

&lt;p&gt;People love to extol the "mobile first" philosophy but they forget that &lt;strong&gt;"mobile first" implies &lt;em&gt;desktop is a second-class citizen&lt;/em&gt;.&lt;/strong&gt; Instead, the "mobile first" champions behave in the opposite manner, by writing code for desktop first and then later trying to cram the site into a phone. They use &lt;code&gt;@media&lt;/code&gt; queries to handle the exceptional cases on mobile, but really &lt;em&gt;desktop&lt;/em&gt; should be the exceptional case.&lt;/p&gt;

&lt;p&gt;In this mobile era, your users first find you through their phones, and then only later do they upgrade to the desktop experience if they like your product enough.&lt;/p&gt;

&lt;p&gt;But does mobile truly come first in the minds of your designers, developers, and product managers? Do you code the mobile site first and then later build the desktop version? Do your designers create wireframes and mockups for mobile before they create wireframes and mockups for desktop? Do you perform A/B testing and solicit user feedback on the mobile version of your website before you test the desktop version?&lt;/p&gt;

&lt;h5&gt;
  
  
  🚫 Mistake
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;980px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;979px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  ✅ Correct
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;980px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;980px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/*
  Notice how this also avoids needing to
  write 979 instead of 980, so you don't
  need to search for two different values
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;These code samples come from &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;Painless CSS&lt;/a&gt;, a book and video course that teaches you CSS from first principles. You can download the full repo with all 60 code samples and solutions in &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;the course&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;That your users are mostly mobile users is not the only reason to design and develop for mobile before desktop. The primary reason is that it's fundamentally easier to develop for a small screen before scaling the design up to a large screen, and not the reverse. You can always make existing elements bigger to fill a blank space on a larger screen, but it's trickier to remove elements from a large screen to make them fit into a smaller one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhdn3qergz8z2g9u5dayr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhdn3qergz8z2g9u5dayr.png" alt="A diagram showing that as the design scales from a large screen to a small screen, it cannot be shrunk to fit into the smaller screen."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7bnevn7ib7yrisakwnlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7bnevn7ib7yrisakwnlz.png" alt="A diagram showing that as the design scales from a small screen to a large screen, it easily expands to fit the larger screen."&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;Image credit: &lt;a href="https://zurb.com/word/mobile-first" rel="noopener noreferrer"&gt;&lt;em&gt;Zurb&lt;/em&gt;&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;If you ship a mobile website without a desktop site, it will cost you $X to build now, and then $X again to add a desktop site later. But if you ship a desktop website without a mobile site, it will cost you $X to build now, and then $2X to add a mobile site later. &lt;strong&gt;This is what people mean by "technical debt": you are paying a lower cost today, at the expense of paying a greater cost over the long run.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, if you are blitzscaling, it may make sense to be "inefficient" and build only the desktop website to prove product-market fit with the understanding that a mobile site will cost more later, but this is a business decision. Engineers will prefer building the mobile site first even if it doesn't always make business sense, so adjust this advice accordingly depending on your stage of growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #3: Not using a naming scheme
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Namespaces are one honking great idea -- let's do more of those!&lt;br&gt;
— &lt;cite&gt;PEP 20: The Zen of Python&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's always exciting to dive straight into writing code without thinking carefully about your naming scheme for variables. For example, do you call it &lt;code&gt;img&lt;/code&gt; or &lt;code&gt;image&lt;/code&gt;? &lt;code&gt;blog-img&lt;/code&gt; or &lt;code&gt;img-blog&lt;/code&gt; or &lt;code&gt;blog-image&lt;/code&gt; or &lt;code&gt;blog-img&lt;/code&gt;? If you call it &lt;code&gt;blog-img&lt;/code&gt;, will you later agree on &lt;code&gt;ad-img&lt;/code&gt; and &lt;code&gt;thumbnail-img&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;It seems minor, but CSS is harder to refactor than other languages because we currently don't have any static analysis tools for CSS that let us perform automated refactoring/renaming. CSS classes can be dynamically added, removed, and constructed using JavaScript, so it's impossible to find "unused" CSS selectors—just because a snippet of CSS isn't being used in one state of one page, doesn't mean it's not used &lt;em&gt;ever&lt;/em&gt;. &lt;a href="http://getbem.com/introduction/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt; doesn't solve this problem if your team can't agree on whether to call it &lt;code&gt;.center&lt;/code&gt;, &lt;code&gt;.centre&lt;/code&gt;, &lt;code&gt;.centered&lt;/code&gt;, &lt;code&gt;.text-center&lt;/code&gt;, or &lt;code&gt;.align-center&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This problem is partially solved by using a CSS-in-JS library because these frameworks remove the global scope of CSS and encourage you to keep styles alongside their associated components. However, CSS-in-JS is not yet widely adopted (as of 2019), and I still have on my wishlist a static analysis tool for CSS—theoretically, CSS-in-JS should make it possible to implement one for the first time.&lt;/p&gt;

&lt;p&gt;This is also partially solved by using a design system, where you agree on a fixed set of variables for colors, spacing, fonts, etc., but unused classes have a tendency to persist because we don't have an automated way to identify and remove them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers are rightfully hesitant to remove anything that might break the website, so they err on the side of caution and prefer to grow the waste pile.&lt;/strong&gt; Worse, unless you are diligent about promoting and clearly communicating your design system, it may simply get ignored as your co-workers avoid reading your documentation and continue in their old habits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #2: Not reading the documentation
&lt;/h2&gt;

&lt;p&gt;It seems so easy. Just install Bootstrap and you are good to go right? Unfortunately, a CSS framework can often cause more problems than it solves if you don't really understand it, and accidentally go against its principles. No matter if you are following an open-source design system like Bootstrap, Material Design, Foundation, or your company's own home-grown design system.&lt;/p&gt;

&lt;p&gt;One of the best things I ever did for my career was to just set aside 4-8 hours to read the official documentation &lt;em&gt;in its entirety&lt;/em&gt; every time I wanted to use a new programming language or framework. As in, not skimming the docs or only searching for keywords that are relevant to my immediate needs, but actually reading it cover-to-cover like a book.&lt;/p&gt;

&lt;p&gt;For example, before I started using Bootstrap, I set aside 6 hours to read its documentation in its entirety. This has saved me countless hours in implementation later, especially in avoiding grid nesting issues that seem to be endemic, because those who skipped the documentation didn't realize that you're &lt;a href="http://www.helloerik.com/the-subtle-magic-behind-why-the-bootstrap-3-grid-works" rel="noopener noreferrer"&gt;not allowed to nest&lt;/a&gt; Bootstrap containers.&lt;/p&gt;

&lt;p&gt;Diligently reading the documentation is important because &lt;strong&gt;many frameworks require you to un-learn the muscle memory you picked up from previous frameworks&lt;/strong&gt;, and you can't know where the pitfalls are until you've read the whole manual. For example, component inheritance was a common pattern in older front-end frameworks such as Backbone. However, newer frameworks such as React work best when using &lt;a href="https://reactjs.org/docs/composition-vs-inheritance.html" rel="noopener noreferrer"&gt;composition instead of inheritance&lt;/a&gt;, but you won't realize this if you skip the docs because you'll just default to using the inheritance patterns that you're used to.&lt;/p&gt;

&lt;p&gt;More generally, it's dangerous to get trapped by the muscle memory you've developed from old technology, which leads us to the final fatal mistake:&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #1: Not following a systematic plan to learn CSS
&lt;/h2&gt;

&lt;p&gt;Technology is ever-evolving, and the only way to stay relevant is to follow a consistent plan of learning and improving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's dangerous to learn by memorizing knowledge from dogma.&lt;/strong&gt; Some experienced developers have a visceral negative reaction to hearing “inline styles” because they were taught early in their careers the best practice to “never use inline styles”.&lt;/p&gt;

&lt;p&gt;Indeed, “never use inline styles” was a best practice a long time ago when it made HTML hard to read, hard to debug, and hard to change. However, the technology chugs along and eventually upends the assumptions that lead to these “best practices”. New assumptions lead to new best practices.&lt;/p&gt;

&lt;p&gt;Inline styles are only painful when you write them by hand—but if you use a CSS-in-JS library to manage your inline styles for you, these downsides disappear, and you are left only with the advantages of code modularity, automated testing, and simple management that works hand-in-hand with a front-end JavaScript framework such as React.&lt;/p&gt;

&lt;p&gt;If you are stuck with the dogma of “never use inline styles”, you won’t have the curiosity to explore what it means when the original assumptions changed. &lt;strong&gt;It's important to use a systematic, structured plan to learn CSS from the ground up and not just search Google for tutorials that only focus on surface-level practices.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, I tried looking for free online resources that help you learn CSS in a structured, systematic way, and there simply aren't any good resources out there. The existing CSS resources either are too technical and assume you already know how browser C++ rendering engines work (which is not at all approachable), or they present only quick and dirty tricks instead of teaching you foundational principles.&lt;/p&gt;

&lt;p&gt;Because there is no good resource that gives you a solid mental model for how CSS actually works from the ground up, you’re left copy/pasting stuff from Stack Overflow and hoping it works. This leaves lots of people with a patchwork knowledge of CSS, knowing just enough to solve specific bugs that arise, but feeling completely helpless when faced with a hard-to-understand bug that seemingly takes hours to fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frustrated by seeing people repeat the same mistakes with CSS in my years of consulting for software startups, I decided to take matters into my own hands and write my own resource.&lt;/strong&gt; I created a course, &lt;a href="https://www.painlesscss.com/" rel="noopener noreferrer"&gt;&lt;em&gt;Painless CSS&lt;/em&gt;&lt;/a&gt;, to provide a comprehensive, first-principles guide to learning CSS the right way and to give you the real skills you need to write professional-grade CSS.&lt;/p&gt;

&lt;p&gt;The secret is that CSS is actually a straightforward language once you are equipped with the right mental models. I created the &lt;em&gt;Painless CSS&lt;/em&gt; course because I want CSS to finally shed its undeserved reputation and rise from the ashes as the beautiful programming language that it is.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this article, and that it gave you a sense of how to avoid the top 10 most common mistakes I see people make when they write CSS. &lt;strong&gt;There are many other mistakes I see people make with CSS&lt;/strong&gt;—you can learn about them all in detail, and how to fix them in the &lt;em&gt;Painless CSS&lt;/em&gt; course here: &lt;a href="https://www.painlesscss.com" rel="noopener noreferrer"&gt;www.painlesscss.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the meantime, I hope this article was helpful to you and inspired you to take your plan for learning CSS seriously, no matter if you decide to purchase my course or someone else's. It's never been a more exciting time to learn front-end web development, and I wish you the best in your programming journey.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>design</category>
    </item>
  </channel>
</rss>
