Cascading Style Sheets
Tags: css, external, embedded, inline
Published: 2020-12-16 14:59:06

---
title: Cascading Style Sheets
published: true
date: 2020-12-15 12:34:30 UTC
tags: css,external,embedded,inline
canonical_url: https://adactio.com/journal/17692
---

There are three ways—that I know of—to associate styles with markup.

**External CSS**

This is probably the most common. Using a `link` element with a `rel` value of “stylesheet”, you point to a URL using the `href` attribute. That URL is a style sheet that is applied to the current document (“the _rel_ationship of the linked resource it is that is a ‘stylesheet’ for the current document”).

```
<link rel="stylesheet" href="/path/to/styles.css">
```

In theory you could associate a style sheet with a document using an HTTP header, but I don’t think many browsers support this in practice.

You can also pull in external style sheets using the `@import` declaration in CSS itself, as long as the `@import` rule is declared at the start, before any other styles.

```
@import url('/path/to/more-styles.css');
```

When you use `link rel="stylesheet"` to apply styles, it’s a blocking request: the browser will fetch the style sheet before rendering the HTML. It needs to know how the HTML elements will be painted to the screen so there’s no point rendering the HTML until the CSS is parsed.

**Embedded CSS**

You can also place CSS rules inside a `style` element directly in the document. This is usually in the `head` of the document.

```
<style>
element {
    property: value;
}
</style>
```

When you embed CSS in the `head` of a document like this, there is no network request like there would be with external style sheets so there’s no render-blocking behaviour.

You can put any CSS inside the `style` element, which means that you could use embedded CSS to load external CSS using an `@import` statement (as long as that `@import` statement appears right at the start).

```
<style>
@import url('/path/to/more-styles.css');
element {
    property: value;
}
</style>
```

But then you’re back to having a network request.

**Inline CSS**

Using the `style` attribute you can apply CSS rules directly to an element. This is a universal attribute. It can be used on any HTML element. That doesn’t necessarily mean that the styles will work, but your markup is never invalidated by the presence of the `style` attribute.

```
<element style="property: value">
</element>

```

Whereas external CSS and embedded CSS don’t have any effect on specificity, inline styles are positively radioactive with specificity. Any styles applied this way are almost certain to over-ride any external or embedded styles.

You can also apply styles using JavaScript and the Document Object Model.

```
element.style.property = 'value';
```

Using the DOM `style` object this way is equivalent to inline styles. The radioactive specificity applies here too.

Style declarations specified in external style sheets or embedded CSS follow the rules of the cascade. Values can be over-ridden depending on the order they appear in. Combined with the separate-but-related rules for specificity, this can be very powerful. But if you don’t understand how the cascade and specificity work then the results can be unexpected, leading to frustration. In that situation, inline styles look very appealing—there’s no cascade and everything has equal specificity. But using inline styles means foregoing a lot of power—you’d be ditching the C in CSS.

A common technique for web performance is to favour embedded CSS over external CSS in order to avoid the extra network request (at least for the first visit—there are clever techniques for caching an external style sheet once the HTML has already loaded). This is commonly referred to as inlining your CSS. But really it should be called embedding your CSS.

This language mix-up is not a hill I’m going to die on (that hill would be referring to blog posts as blogs) but I thought it was worth pointing out.