<?xml version="1.0" encoding="utf-8"?>
  <rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    xmlns:georss="http://www.georss.org/georss"
    xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
  >
    <channel>
      <title>Piccalilli - CSS Fundamentals topic archive</title>
      <link>https://piccalil.li/</link>
      <atom:link href="https://piccalil.li/category/css-fundamentals.xml" rel="self" type="application/rss+xml" />
      <description>We are Piccalilli. A publication dedicated to providing high quality educational content to level up your front-end skills.</description>
      <language>en-GB</language>
      <copyright>Piccalilli - CSS Fundamentals topic archive 2026</copyright>
      <docs>https://www.rssboard.org/rss-specification</docs>
      <pubDate>Tue, 07 Apr 2026 01:02:02 GMT</pubDate>
      <lastBuildDate>Tue, 07 Apr 2026 01:02:02 GMT</lastBuildDate>

      
      <item>
        <title>CSS inheritance</title>
        <link>https://piccalil.li/blog/css-inheritance/?ref=css-fundamentals-category-rss-feed</link>
        <dc:creator><![CDATA[Andy Bell]]></dc:creator>
        <pubDate>Mon, 29 Apr 2024 07:55:54 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/css-inheritance/?ref=css-fundamentals-category-rss-feed</guid>
        <description><![CDATA[<p>Just like <a href="https://piccalil.li/blog/a-primer-on-the-cascade-and-specificity">the cascade and specificity</a> — for some reason — developers approach inheritance with fear. There’s no need for that though because inheritance is actually quite straightforward. It’s probably my favourite aspect of CSS too. Let me explain why.</p>
<p>Let’s say you have this CSS:</p>
<pre><code>body {
	color: DarkSlateBlue;
}
</code></pre>
<p>Along with a <a href="https://web.dev/learn/css/inheritance?continue=https%3A%2F%2Fweb.dev%2Flearn%2Fcss%23article-https%3A%2F%2Fweb.dev%2Flearn%2Fcss%2Finheritance#which_properties_are_inherited_by_default">bunch of other properties</a>, <code>color</code> is <strong>inheritable</strong>, which means every bit of text on the page — unless there’s a specific <code>color</code> defined — will now be <code>DarkSlateBlue</code>.</p>
<p>Let’s expand on this some more and bring in some HTML.</p>
<pre><code>&lt;article&gt;
	&lt;h1&gt;I am a heading&lt;/h1&gt;
	&lt;p&gt;I am a paragraph.&lt;/p&gt;
  &lt;h2&gt;Subscribe&lt;/h2&gt;
	&lt;form&gt;
    &lt;label for="email"&gt;Email address&lt;/label&gt;
    &lt;input type="email" id="email" placeholder="hello@test.com"&gt;
    &lt;button&gt;Submit&lt;/button&gt;
	&lt;/form&gt;
&lt;/article&gt;
</code></pre>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/b16276869385bb5396a27013726f0521">Nearly all the text is purple</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<p>Looking at the demo, the headings, paragraph and label have <code>DarkSlateBlue</code> text, but the input (both placeholder and value) and button still have the default colour text. This is because they have specific colours assigned to them in dev tools, like so:</p>
<pre><code>button {
	color: buttontext;
}

input {
	color: fieldtext;
}
</code></pre>
<p>These are system colours that are applied in the user agent stylesheet — default styles applied by the browser. Because these elements have a <code>color</code> value applied, they won’t inherit the colour from <code>body</code>, like the other elements on the page are.</p>
<h2>The <code>inherit</code> keyword</h2>
<p>This keyword is really handy. Not all CSS properties are inheritable, even though <a href="https://web.dev/learn/css/inheritance?continue=https%3A%2F%2Fweb.dev%2Flearn%2Fcss%23article-https%3A%2F%2Fweb.dev%2Flearn%2Fcss%2Finheritance#which_properties_are_inherited_by_default">a lot are</a>. You can use the <code>inherit</code> keyword to inherit those non-inheritable properties.</p>
<pre><code>article {
	display: flex;
}

h1 {
	display: inherit;
}
</code></pre>
<p>With this snippet, the <code>&lt;h1&gt;</code> will now have a <strong>computed <code>display</code> value</strong> of <code>flex</code>.</p>
<p>Back to our little snippet of HTML, though. Let’s make the input and button inherit the <code>DarkSlateBlue</code> colour. Colour is inheritable, but we can use the <code>inherit</code> keyword to force the element to inherit those properties over the default styles assigned by the user agent stylesheet.</p>
<pre><code>input, button {
	color: inherit;
}
</code></pre>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/24a836e51cac1a48eb8d77474784391c">Even more of the colour is inherited</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<div><h2>FYI</h2>
  Don’t worry, we’ll sort that placeholder out later in the article.
</div>
<p>Easy peasy right? Let’s push it a little further and use another inheritable property: <code>font</code>. We’ll set some font values on the body first:</p>
<pre><code>body {
	color: DarkSlateBlue;
  font-family: Tahoma;
  font-size: 2rem;
}
</code></pre>
<p>The magic of inheritance means all the text elements have again, inherited the <code>font-family</code> and all the text is bigger.</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/e889f0f5e1bafa793b8aea5efa4d96e0">Nearly everything now uses Tahoma font</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<p>The reason the text elements like headings are bigger, with no additional sizing authored by us, is because the user agent styles size them with <code>em</code> units, which are a ratio of their parent’s computed <code>font-size</code>. For example, this is the <code>h1</code> font size style in the Chromium user agent style:</p>
<pre><code>h1 {
	font-size: 1.5em;
}
</code></pre>
<p>Because we set the <code>body</code> to have a <code>font-size</code> of <code>2rem</code>, my browser has computed that to <code>24px</code>. The <code>h1</code> has a <code>font-size</code> of <code>1.5em</code> which is <code>24 * 1.5</code>: <code>36px</code>.</p>
<div><h2>FYI</h2>
<p>This is where the fear can step in for developers. It can make them feel like they are not in control of the user interface.</p>
<p>It’s better to create solid rules high up and let the browser do most of the work for you. This results in more resilient interfaces for users that <strong>respect their preferences</strong>. We build for everyone, not ourselves. <a href="https://buildexcellentwebsit.es/">Read more on these principles here</a>.</p>
</div>
<p>Right, back to our little demo. The problem is, our <code>placeholder</code> style is still grey. This is because in the user agent stylesheet, placeholders have a specific colour assigned to them, so they no longer inherit either the <code>body</code> colour <em>or</em> the <code>input</code> colour.</p>
<p>This is the placeholder rule in the Chromium user agent stylesheet.</p>
<pre><code>::-webkit-input-placeholder {
  -webkit-text-security: none;
  color: darkGray;
  pointer-events: none !important;
}
</code></pre>
<p>The <code>color</code> is set to <code>darkGray</code>, so even when the <code>input</code> is inheriting <code>color</code>, it won’t affect the placeholder because it has a more specific style assigned to it. No dramas though because all we need to do is this with a more cross-browser friendly selector:</p>
<pre><code>::placeholder {
	color: inherit;
}
</code></pre>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/7890122b9ce767258da906dccb127d1a">Now everything is inheriting colours and fonts</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<div><h2>FYI</h2>
<p>You should consider using <code>placeholder</code> in the first place, <a href="https://adrianroselli.com/2021/08/sentence-forms-not-mad-libs.html">as Adrian Roselli notes</a>. <a href="https://www.w3.org/WAI/tutorials/forms/instructions/#styling">Eric Eggert helps you make sure it’s accessible</a> if you do need to use them though.</p>
</div>
<h2>Controlling inheritance</h2>
<p>I’m waxing lyrical about how powerful inheritance is, but in the real world, you’re not building simple examples like the above. There’s going to be plenty of times where your element has inherited styles that you don’t want. Let’s look at some options.</p>
<h3>Write more specific styles</h3>
<p>This is my most favoured approach. Just like we covered in <a href="https://piccalil.li/blog/a-primer-on-the-cascade-and-specificity">the cascade and specificity primer</a>: user agent styles are low in the cascade priority, so even writing flat type selectors like so, will do the job for you:</p>
<pre><code>a {
	color: red; /* Very easily overrides the user agent style */
}
</code></pre>
<p>This is how we’ve tackled the problems above and is probably the path of least resistance when authoring your CSS.</p>
<h3>Use keywords</h3>
<p>Let’s run through <code>revert</code>, <code>initial</code> and <code>unset</code> keywords.</p>
<h4><code>revert</code></h4>
<pre><code>.my-element {
	color: revert;
}
</code></pre>
<p>This will set the property to the user agent stylesheet value — AKA the default browser style. So, if <code>.my-element</code> was a <code>&lt;button&gt;</code>, the colour would be set back to <code>buttontext</code>, like we covered earlier.</p>
<h4><code>unset</code></h4>
<pre><code>.my-element {
	color: unset;
}
</code></pre>
<p>This one can be a bit confusing. If the property you are assigning <code>unset</code> to is <a href="https://web.dev/learn/css/inheritance?continue=https%3A%2F%2Fweb.dev%2Flearn%2Fcss%23article-https%3A%2F%2Fweb.dev%2Flearn%2Fcss%2Finheritance#which_properties_are_inherited_by_default">inheritable</a>, then you are effectively doing this:</p>
<pre><code>.my-element {
	color: inherit;
}
</code></pre>
<p>If it’s not an inheritable property though, the property value will be the same as what the next keyword — <code>initial</code> — does.</p>
<h4><code>initial</code></h4>
<pre><code>.my-element {
	color: initial;
}
</code></pre>
<p>This is the nuclear option and I recommend avoiding. This will set the value back to the element’s CSS specification value, which in human terms means, it’s gonna remove the style all together.</p>
<div><h2>FYI</h2>
<p>I tend to avoid <code>initial</code> and <code>unset</code> when authoring CSS. The <code>revert</code> keyword is powerful enough if you embrace inheritance, the cascade and specificity and letting the browser do the hard work for you.</p>
</div>
<h2>Wrapping up</h2>
<p>See, inheritance isn’t scary is it? It’s fantastically powerful and if you embrace it, you <strong>will write less CSS</strong>. You’ll also have a more maintainable codebase <em>and</em> your users will get a better experience overall. Magic.</p>
<p>It’s so different to traditional and native software development where you have to very specifically style every single element. I get why developers who come from that background don’t like CSS. It’s a shift in mental model though; <strong>let go of the need for absolute control and everything becomes easier</strong>. That’s a <a href="https://buildexcellentwebsit.es/">principle for building for the web in general</a> that will improve everything for you. Trust me.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>A primer on the cascade and specificity</title>
        <link>https://piccalil.li/blog/a-primer-on-the-cascade-and-specificity/?ref=css-fundamentals-category-rss-feed</link>
        <dc:creator><![CDATA[Andy Bell]]></dc:creator>
        <pubDate>Thu, 18 Apr 2024 07:55:54 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/a-primer-on-the-cascade-and-specificity/?ref=css-fundamentals-category-rss-feed</guid>
        <description><![CDATA[<p>Almost as inevitable as death and taxes, developers will cite that the cascade and specificity are what makes CSS difficult to work with. Sure, the cascade and specificity are going to cause problems if you don’t account for them in your CSS, but if you have a base-level understanding, I promise, your CSS skills will sky-rocket.</p>
<p>A lot of the time, the cascade and specificity are explained within and inch of their lives in expansive guides or detailed articles. These articles are <em>fantastic</em>, but I think the size and complexity of them can scare developers too, so I’m going to simplify it for you today. In fact, keeping things simple is one of the most effective ways to keep <em>any</em> codebase manageable and maintainable. It’s especially the case with CSS though. Let’s dig in.</p>
<h2>The C in CSS stands for Cascade</h2>
<p>Let’s tackle the elephant in the room first. The Cascade is an algorithm that solves conflicts for you where multiple rules <em>could</em> apply to an HTML element.</p>
<p>Let’s use a really simple example:</p>
<pre><code>.my-element {
	background: goldenrod;
	background: coral;
}
</code></pre>
<p>This element has two background declarations. The cascade has done its thing and determined that <code>.my-element</code> will have a <code>coral</code> background. Why though?</p>
<p>Because the <code>coral</code> declaration comes after the <code>goldenrod</code> one, <code>coral</code> wins. In the vast majority of your standard CSS authoring, remember this and you’re good to go. There are exceptions though, so let’s focus more on those because this first bit was dead easy right?</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/f9e635113d1dd8c40df86f1b990f045c">A square with a coral background</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<h3>The order of importance</h3>
<p>No, this isn’t a weird British Royal Family thing; it’s a simple ruleset to remember because not all properties are equal. What I mean by that is certain CSS property types will be prioritised over others. This list is ordered least to most specific.</p>
<h4>Normal declarations</h4>
<p>This is your <code>background</code>, <code>padding</code>, <code>line-height</code> and <code>margin</code>  properties. Y’know, the stuff you’re slinging into your code most of the day.</p>
<h4>Active animations</h4>
<p>This is when your <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties">animatable properties</a> are being affected by an active <code>@keyframes</code> animation.</p>
<h4>Declarations that utilise <code>!important</code></h4>
<p>Not to be feared but to be admired: the humble <code>!important</code> property does exactly what it says on the tin: it determines an important value. It’s added as part of your declaration value like so:</p>
<pre><code>.my-element {
	background: grey !important;
}
</code></pre>
<p>This will ultimately win (nearly) every time, but treat it as it will win every time and you won’t have problems with it.</p>
<p>The <code>!important</code> property is designed to be honoured by proxy of it being important, so only use it when you feel you absolutely need to. I’ll write more on this if people want me to, but use it wisely and <code>!important</code>  can be <em>really</em> useful and helpful in keeping your codebase simple.</p>
<h3>The order of origin</h3>
<p>This order is taken into account by the cascade from least specific to most specific.</p>
<h4>User agent base styles</h4>
<p>Every major browser ships with a user agent stylesheet. These are default styles that are applied to HTML elements to prevent every element looking the same if there’s no CSS that applies to that HTML.</p>
<div><h2>FYI</h2>
<p>This is one of many reasons why writing semantic HTML is a good idea.</p>
</div>
<h4>Local user styles</h4>
<p>These styles are mostly operating system level stuff such as font size preferences. Local user styles also technically apply to CSS that is authored in browser extensions but my recommendation in more modern times is to presume that these are injected as <code>&lt;style&gt;</code>  which will be more specific than styles authored in CSS files.</p>
<h4>Authored CSS</h4>
<p>Hey champ, this is your stuff that you are writing!</p>
<h4>Authored <code>!important</code></h4>
<p>Yup, just like we covered earlier: those <code>!important</code> values are gonna win over your standard property values.</p>
<h4>Local user styles with <code>!important</code></h4>
<p>Say you absolutely want your font size to be the same on every website. An operating system and browser combo could technically declare that as an <code>!important</code> property and that will beat all of the above.</p>
<h4>User agent <code>!important</code>.</h4>
<p>Finally, if the user agent styles have an <code>!important</code> value, this will ultimately win.</p>
<hr />
<p>That’s it for the cascade, let’s tackle its best friend: specificity.</p>
<h2>Specificity</h2>
<p>Fun fact, because I’m from Yorkshire in the UK, I struggle to say this word, which for someone who teaches CSS, is not ideal. I digress though, but for a reason — to give you a quick breather — so retract those shoulders and breathe out because specificity isn’t hard, trust me.</p>
<p>Let’s go back to <code>.my-element</code> but tweak the CSS. It’s important to note that we’re using <code>&lt;div&gt;</code> element that has a <code>class</code> attribute.</p>
<pre><code>div {
	background: goldenrod;
}

.my-element {
	background: coral;
}
</code></pre>
<p>The winner is <code>coral</code> because <code>.my-element</code> has a <strong>specificity score</strong> of <code>0-1-0</code>, whereas <code>div</code> has a <strong>specificity score</strong> of <code>0-0-1</code>. Let’s dig into scoring some more.</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/2556c5368a5e73ef0b66cfc31965d66d">CSS class wins because it's a more specific selector</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<h3>Specificity scoring</h3>
<p>Each <a href="https://web.dev/learn/css/selectors">selector rule</a> gets a score. The higher the score, the more likely that rule’s CSS is going to apply. The score is in this format: <code>0-0-0</code>, or <code>"hundreds"-"tens"-"singles"</code>. This does expand, but let’s not worry about that right now until we need to. Let’s do a quick fire scoring rundown.</p>
<div><h2>FYI</h2>
<p>Some people write specificity scores as comma seperated, like <code>0,0,0</code>.</p>
</div>
<h4>Universal selector — AKA the wildcard selector</h4>
<pre><code>* {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>0-0-0</code> <strong>— 0 points</strong></p>
<h4>Type selector — AKA element selector</h4>
<pre><code>h1 {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>0-0-1</code> <strong>— 1 point</strong></p>
<h4>Pseudo-element selector</h4>
<pre><code>::before {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>0-0-1</code> <strong>— 1 point</strong></p>
<h4>Class selector</h4>
<pre><code>.my-element {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>0-1-0</code> <strong>— 10 points</strong></p>
<h4>Pseudo-class selector</h4>
<pre><code>:hover {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>0-1-0</code> <strong>— 10 points</strong></p>
<h4>Attribute selector</h4>
<pre><code>[href] {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>0-1-0</code> <strong>— 10 points</strong></p>
<h4>ID selector</h4>
<pre><code>#myElement {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>Score: <code>1-0-0</code> <strong>— 100 points</strong></p>
<h4>Inline style attribute</h4>
<pre><code>&lt;div style="background: blue"&gt;&lt;/div&gt;
</code></pre>
<p>Score: <code>1-0-0-0</code> <strong>— 1,000 points</strong></p>
<h4><code>!important</code> rule</h4>
<pre><code>.my-element {
	background: red !important;
}
</code></pre>
<p>Score: <code>1-0-0-0-0</code> <strong>— 10,000 points</strong></p>
<p>Wait just one minute, <code>!important</code> is a cascade thing, right?! It’s both a cascade and specificity thing. Someone with a name like Chad Smith might cite this as the reason why CSS “sucks” on Twitter. That’s not true though because all you have to do is remember <code>!important</code> applies to the cascade <em>and</em> specificity, just like you need to remember that <a href="https://github.com/denysdovhan/wtfjs?tab=readme-ov-file#comparison-of-three-numbers">JavaScript can’t compare numbers properly</a>. All programming languages have stuff like this to learn and CSS is no different.</p>
<p>Also, do you remember when I said the scoring will expand? This is it. For both inline style attributes and <code>!important</code> rules we stitch on an extra number. For you, dear reader, this is a cue that the CSS you’re writing better be damn important because you’re in the realms of very high specificity.</p>
<h4>Combining selectors equals more points</h4>
<p>Now you know how many points each selector type gives you, let’s combine some to show how this part works.</p>
<pre><code>h1#myElement {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>We’ve got <strong>1 point</strong> because we’re using a type selector (<code>h1</code>) and <strong>100 points</strong> because we’re also using an ID selector (<code>#myElement</code>). Therefore the specificity score here is <code>1-0-1</code> <strong>— 101 points</strong>.</p>
<p>Let’s do one more for fun.</p>
<pre><code>h1.my-element::before {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>We’ve got <strong>2 points</strong> because we’re using <strong>both</strong> a type selector (<code>h1</code>) and a pseudo-element selector <code>::before</code>. We’ve also got <strong>10 points</strong> because we’re using a class selector (<code>.my-element</code>). Therefore the specificity score here is <code>0-1-2</code> <strong>— 12 points</strong>.</p>
<h3><code>:not()</code>, <code>:is()</code> and <code>:where()</code></h3>
<p>Let’s say you have this CSS:</p>
<pre><code>h1:is(.my-element) {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>It has the exact same specificity score as:</p>
<pre><code>h1.my-element {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>This is because with both <code>:is()</code> and <code>:not()</code>, the most <strong>specific selector passed into those pseudo-classes</strong> will be picked, so don’t think about using those as a specificity boost.</p>
<p>With <code>:where()</code>, that pseudo-class and <strong>any selector passed into it has no specificity</strong>. Let’s go back to one of the earlier selectors to demonstrate.</p>
<pre><code>h1#myElement {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>This has a score of <code>1-0-1</code> <strong>— 101 points</strong>. Let’s add <code>:where()</code> into the mix.</p>
<pre><code>h1:where(#myElement) {
	/* Your CSS declarations and properties here */
}
</code></pre>
<p>This now has a score of <code>0-0-1</code> <strong>— 1 point</strong> because the 100 points from the ID selector has now been discarded because it is within a <code>:where()</code> pseudo-class. It’s why you probably spotted its usage in CSS resets because those reset styles are much easier to override thanks to <code>:where()</code>’s low specificity.</p>
<h3>Child and sibling selectors add no specificity</h3>
<p>One quick thing to remember is using child and sibling selectors  (<code>&gt;</code>, <code>~</code> and <code>+</code>) won’t affect your specificity score. For example, these have the same score as each other:</p>
<pre><code>.my-element li {
	/* Your CSS declarations and properties here */
}

.my-element &gt; li { 
	/* Your CSS declarations and properties here */
}
</code></pre>
<h2>Dev tools are your best friend</h2>
<p>If you open up dev tools in your browser and go to the styles tab, it’ll look a bit like this:</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/dev-tools-specificity.jpg" alt="The dev tools CSS panel, showing at the top, .my-element wins. The background rules for div are being discarded because my-element is more specific" /></p>
<p>The stuff that’s less specific in terms of both the cascade and specificity will be lower down the panel. Anything more specific will be higher in the panel. What has been discarded will be crossed out, so by proxy, what isn’t crossed out is applied. That knowledge alone should make your life easier!</p>
<h2>Wrapping up</h2>
<p>I strongly recommend that you get a specificity calculator in your arsenal. My favourite is by the fantastic folks at <a href="https://polypane.app/?ref=piccalilli">Polypane</a>. Their <a href="https://polypane.app/css-specificity-calculator?ref=piccalilli">specificity calculator</a> is super easy to use and does a really good job of breaking it down for you.</p>
<p>There’s also new CSS capabilities that can help, such as <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers">Cascade Layers</a>. I personally haven’t found the need for these (yet), so I’m not qualified to write about them. I’ll <a href="https://ishadeed.com/article/cascade-layers/">let someone who definitely is explain them to you instead</a>.</p>
<p>I’ll finish by saying I find this stuff super boring to write about but it’s really important to understand. I hope this primer will make you feel more comfortable with two of the most fundamental parts of CSS. If you’re looking for quick advice on how to deal with this in the real world, I would say keep your selectors as low scoring as possible. If you get stumped, remember the order of origin and use dev tools! Remember, if it’s crossed out in the CSS panel: something more specific is in play.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>The box model and box sizing</title>
        <link>https://piccalil.li/blog/the-box-model-and-box-sizing/?ref=css-fundamentals-category-rss-feed</link>
        <dc:creator><![CDATA[Andy Bell]]></dc:creator>
        <pubDate>Wed, 20 Mar 2024 09:00:13 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/the-box-model-and-box-sizing/?ref=css-fundamentals-category-rss-feed</guid>
        <description><![CDATA[<p>If there’s ever one really important thing to remember when writing CSS: it’s that <strong>every element is a box</strong>. Regardless of how an element looks visually, it’s still a box.</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/css-fundamentals/simple-box-circle.svg" alt="A dashed box with a circle in it" /></p>
<p>Take the above example: it’s visually a circle because it has <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius"><code>border-radius</code></a> applied to it, but it’s still a box, as far as the browser is concerned.</p>
<p>This is really important to remember when you’re working with CSS, but what’s even more important to remember is understanding how these boxes are both sized and how they interact with their surrounding, sibling boxes.</p>
<h2>Padding, borders and the content box</h2>
<p>The default <code>box-sizing</code> value for all elements is <code>content-box</code>. This means that when we add <code>padding</code> and/or <code>border</code> to an element, those values will be combined with the desired/content-driven <code>width</code> and <code>height</code> of the element.</p>
<p>This is because the <code>width</code> is applied to the <strong>content box</strong> part of the box box model. This can be confusing — especially when you are first starting out with CSS.</p>
<pre><code>.box {
  width: 100px;
  padding: 10px;
  border: 10px solid;
}
</code></pre>
<p><img src="https://piccalil.b-cdn.net/images/blog/css-fundamentals/box-model-parts.svg" alt="Width is applied to the content box, but because padding box and border box values are included, they bleed over the edges" title="The width, padding and border contributing to a 140px computed value even though 100px of width is applied" /></p>
<p>What happens here is your box’s computed width is actually calculated as <code>140px</code>. This is because each side of the border box is <code>10px</code> (<code>20px</code> combined), and each side of the padding box is <code>10px</code> (<code>20px</code> combined). The width of the box only accounts for these <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/inline-size">inline sizes</a>.</p>
<p>This is how the <a href="https://web.dev/learn/css/box-model/">box model</a> works out of the box (pun intended), and it’s often unexpected behaviour for beginners because y’know, if you set a <code>width</code> or <code>height</code>, you expect your element to honour that. It’s completely understandable how this confuses people!</p>
<p>Most of the time though, it’s preferable for this default box model behaviour not to be the case. To get more predictability,  add this little snippet of CSS to your element’s CSS:</p>
<pre><code>.box {
  box-sizing: border-box;
}
</code></pre>
<p>This snippet completely transforms the browser’s calculation of an element’s size. To convert this CSS into plain English, you’re saying: “Take the dimensions that I specified and also account for the padding and border too, instead of adding them to the desired size”.</p>
<p>What you get as a result is a box that’s <code>100px</code> wide, instead of <code>140px</code> wide, just like you specified when you set <code>width</code> to 100px!</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/css-fundamentals/box-sizing-border-box.svg" alt="Combined border box, padding box and content box makes the size of the box, 100px" title="The fixed box with a predictable width. The lighter border shows the computed width when you don’t have box-sizing: border-box." /></p>
<p>The most effective way of showing you this is with a demo. When you toggle the “box sizing” switch to <strong>ON</strong>, <code>box-sizing: border-box</code> is applied to the box element, making the resulting size the same as the desired size. When it’s switched <strong>OFF</strong>, the default browser behaviour takes over.</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/mdgRxRQ">A quick demo showing the impact of box sizing on a box element</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<p>The element has <code>10px</code> of <code>padding</code> and a <code>10px</code> border, which means <code>40px</code> is added to the width because the element has padding <em>and</em> border either side. The demo box has a minimum size of <code>250px</code> to make the text easier to read.</p>
<h2>Globalising box sizing rules</h2>
<p>A lot folks add the <code>box-sizing</code> rule as a global selector to <a href="https://piccalil.li/blog/a-more-modern-css-reset/">a reset</a> — or default normalising styles — so to demonstrate a more complete example, this is how our CSS now looks:</p>
<pre><code>/* Reset rule */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Box component */
.box {
  width: 100px;
  padding: 10px;
  border: 10px solid;
}
</code></pre>
<p>What this reset rule does is instead of just targeting the <code>.box</code> element with <code>box-sizing</code>, it targets every element on the page and any of their <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements">pseudo-elements</a>.</p>
<p>This means that every time you add and element to a page, you can guarantee it will be the size that you think it is with little to no surprises. Of course, in a responsive world, setting specific sizes can be problematic, but even then, you know <code>padding</code> and <code>border</code> are not going to make your elements bigger than you thought they’d be.</p>
<h2>Wrapping up</h2>
<p>I hope this quick run-through of the box model and box sizing has unlocked the concept in your brain. Knowing the fundamentals like this will make you a better CSS developer, I promise. Here's some links:</p>
<ul>
<li><a href="https://web.dev/learn/css/box-model">Box Model - web.dev</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model">The box model - MDN</a></li>
<li><a href="https://www.youtube.com/watch?v=M6coJNLFBWI">The CSS Box Model - Margin, Borders &amp; Padding explained - Kevin Powell</a></li>
<li><a href="https://piccalil.li/blog/international-box-sizing-awareness-day/">Happy international box sizing awareness day</a></li>
</ul>
        
        ]]></description>
        
      </item>
    
    </channel>
  </rss>
