Cascade layers - Learn web development

Cascade layers
==============

* Previous
* Overview: Building blocks
* Next

This lesson aims to introduce you to cascade layers, a more advanced feature that builds on the fundamental concepts of the CSS cascade and CSS specificity.

If you are new to CSS, working through this lesson may seem less relevant immediately and a little more academic than some other parts of the course. However, knowing the basics of what cascade layers are should you encounter them in your projects is helpful. The more you work with CSS, understanding cascade layers and knowing how to leverage their power will save you from a lot of pain managing a code base with CSS from different parties, plugins, and development teams.

Cascade layers are most relevant when you're working with CSS from multiple sources when there are conflicting CSS selectors and competing specificities, or when you're considering using `!important`.

|  |  |
| --- | --- |
| Prerequisites: |
 An idea of how CSS works, including cascade and specificity (study
 CSS first steps and Cascade, specificity, and inheritance).
  |
| Objective: | To learn how cascade layers work. |

For each CSS property applied to an element, there can only be one value. You can view all the property values applied to an element by inspecting the element in your browser's developer tools. The tool's "Styles" panel shows all the property values applied to the element being inspected, along with the matched selector and the CSS source file. The selector from the origin with precedence has its values applied to the matching element.

In addition to the applied styles, the Styles panel displays crossed-out values that matched the selected element but were not applied due to the cascade, specificity, or source order. Crossed-out styles may come from the same origin with precedence but with lower specificity, or with matching origin and specificity, but were found earlier in the code base. For any applied property value, there may be several declarations crossed out from many different sources. If you see a style crossed out that has a selector with greater specificity it means the value is lacking in origin or importance.

Often, as the complexity of a site increases, the number of stylesheets increases, which makes the source order of the stylesheets both more important and more complex. Cascade layers simplify maintaining stylesheets across such code bases. Cascade layers are explicit specificity containers providing simpler and greater control over the CSS declarations that ultimately get applied, enabling web developers to prioritize sections of CSS without having to fight specificity.

To understand cascade layers, you must understand the CSS cascade well. The sections below provide a quick recap of the important cascade concepts.

Review of the cascade concept
-----------------------------

The C in CSS stands for "Cascading". It is the method by which styles cascade together. The user agent runs through several clearly defined steps to determine the values assigned to every property for every element. We will briefly list these steps here and then dig deeper into step 4, **Cascade layers**, which is what you came here to learn:

1. **Relevance:** Find all the declaration blocks with a selector match for each element.
2. **Importance:** Sort rules based on whether they are normal or important. Important styles are those that have the `!important` flag set.
3. **Origin:** Within each of the two importance buckets, sort rules by author, user, or user-agent origin.
4. **Cascade layers:** Within each of the six origin importance buckets, sort by cascade layer. The layer order for normal declarations is from the first layer created to the last, followed by unlayered normal styles. This order is inverted for important styles, with unlayered important styles having the lowest precedence.
5. **Specificity:** For competing styles in the origin layer with precedence, sort declarations by specificity.
6. **Scoping proximity**: When two selectors in the origin layer with precedence have the same specificity, the property value within scoped rules with the smallest number of hops up the DOM hierarchy to the scope root wins. See How `@scope` conflicts are resolved for more details and an example.
7. **Order of appearance:** When two selectors in the origin layer with precedence have the same specificity and scope proximity, the property value from the last declared selector with the highest specificity wins.

For each step, only the declarations "still in the running" move on to "compete" in the next step. If only one declaration is in the running, it "wins", and the subsequent steps are moot.

### Origin and cascade

There are three cascade origin types: user-agent stylesheets, user stylesheets, and author stylesheets. The browser sorts each declaration into six origin buckets by origin and importance. There are eight levels of precedence: the six origin buckets, properties that are transitioning, and properties that are animating. The order of precedence goes from normal user-agent styles, which have the lowest precedence, to styles within currently applied animations, to important user-agent styles, and then styles being transitioned, which have the highest precedence:

1. user-agent normal styles
2. user normal styles
3. author normal styles
4. styles being animated
5. author important styles
6. user important styles
7. user-agent important styles
8. styles being transitioned

The "user-agent" is the browser. The "user" is the site visitor. The "author" is you, the developer. Styles declared directly on an element with the `<style>` element are author styles. Not including animating and transitioning styles, user-agent normal styles have the lowest precedence; user-agent important styles have the highest.

### Origin and specificity

For each property, the declaration that "wins" is the one from the origin with precedence based on the weight (normal or important). Ignoring layers for the moment, the value from the origin with the highest precedence gets applied. If the winning origin has more than one property declaration for an element, the specificity of the selectors for those competing property values are compared. Specificity is never compared between selectors from different origins.

In the example below, there are two links. The first has no author styles applied, so only user-agent styles are applied (and your personal user styles, if any). The second has `text-decoration` and `color` set by author styles even though the selector in the author stylesheet has a specificity of `0-0-0`. The reason why author styles "win" is because when there are conflicting styles from different origins, the rules from the origin with precedence are applied, irrespective of the specificity in the origin that doesn't have precedence.

The "competing" selector in the user-agent stylesheet at the time of this writing is `a:any-link`, which has a specificity weight of `0-1-1`. While this is greater than the `0-0-0` selector in the author stylesheet, even if the selector in your current user agent is different, it doesn't matter: the specificity weights from author and user-agent origins are never compared. Learn more about how specificity weight is calculated.

Origin precedence always wins over selector specificity. If an element property is styled with a normal style declaration in multiple origins, the author style sheet will always override the redundant normal properties declared in a user or user-agent stylesheet. If the style is important, the user-agent stylesheet will always win over author and user styles. Cascade origin precedence ensures specificity conflicts between origins never happen.

One last thing to note before moving on: the order of appearance becomes relevant only when competing declarations in the origin of precedence have the same specificity.

Overview of cascade layers
--------------------------

We now understand "cascade origin precedence", but what is "cascade layer precedence"? We will answer that question by addressing what cascade layers are, how they are ordered, and how styles are assigned to cascade layers. We'll cover regular layers, nested layers, and anonymous layers. Let's first discuss what cascade layers are and what issues they solve.

### Cascade layer precedence order

Similar to how we have six levels of priority based on origin and importance, cascade layers enable us to create sub-origin level of priority within any of those origins.

Within each of the six origin buckets, there can be multiple cascade layers. The order of layer creation matters a lot. It is the order of creation that sets the precedence order among layers within an origin.

In normal origin buckets, layers are sorted in the order of each layer's creation. The order of precedence is from the first layer created to the last, followed by unlayered normal styles.

This order is inverted for important styles. All unlayered important styles cascade together into an implicit layer having precedence over all non-transitioning normal styles. The unlayered important styles have lower precedence than any important layered styles. The important styles in earlier declared layers have precedence over important styles in subsequent declared layers within the same origin.

For the rest of this tutorial, we will limit our discussion to author styles, but keep in mind that layers can also exist in user and user-agent stylesheets.

### Issues cascade layers can solve

Large code bases can have styles coming from multiple teams, component libraries, frameworks, and third parties. No matter how many stylesheets are included, all these styles cascade together in a single origin: the *author* style sheet.

Having styles from many sources cascade together, especially from teams that aren't working together, can create problems. Different teams may have different methodologies; one may have a best practice of reducing specificity, while another may have a standard of including an `id` in each selector.

Specificity conflicts can escalate quickly. A web developer may create a "quick fix" by adding an `!important` flag. While this may feel like an easy solution, it often just moves the specificity war from normal to important declarations.

In the same way that cascade origins provide a balance of power between user, user-agents, and author styles, cascade layers provide a structured way to organize and balance concerns within a single origin as if each layer in an origin were a sub-origin. A layer can be created for each team, component, and third party, with style precedence based on layer order.

Rules within a layer cascade together, without competing with style rules outside the layer. Cascade layers enable the prioritizing of entire stylesheets over other stylesheets, without having to worry about specificity between these sub-origins.

Layer precedence always beats selector specificity. Styles in layers with precedence "win" over layers with less precedence. The specificity of a selector in a losing layer is irrelevant. Specificity still matters for competing property values within a layer, but there are no specificity concerns between layers because only the highest-priority layer for each property is considered.

### Issues nested cascade layers can solve

Cascade layers allow the creation of nested layers. Each cascade layer can contain nested layers.

For example, a component library may be imported into a `components` layer. A regular cascade layer will add the component library to the author origin, removing any specificity conflicts with other author styles. Within the `components` layer, a developer can choose to define various themes, each as a separate nested layer. The order of these nested theme layers can be defined based on media queries (see the Layer creation and media queries section below), such as viewport size or orientation. These nested layers provide a way to create themes that don't conflict based on specificity.

The ability to nest layers is very useful for anybody who works on developing component libraries, frameworks, third-party widgets, and themes.

The ability to create nested layers also removes the worry of having conflicting layer names. We'll cover this in the nested layer section.

>
> "Authors can create layers to represent element defaults, third-party libraries, themes, components, overrides, and other styling concerns—and are able to re-order the cascade of layers in an explicit way, without altering selectors or specificity within each layer, or relying on order of appearance to resolve conflicts across layers."
>
>
> —Cascading and Inheritance specification.
>
>
>

Creating cascade layers
-----------------------

Layers can be created using any one of the following methods:

* The `@layer` statement at-rule, declaring layers using `@layer` followed by the names of one or more layers. This creates named layers without assigning any styles to them.
* The `@layer` block at-rule, in which all styles within a block are added to a named or unnamed layer.
* The `@import` rule with the `layer` keyword or `layer()` function, which assigns the contents of the imported file into that layer.

All three methods create a layer if a layer with that name has not already been initialized. If no layer name is provided in the `@layer` at-rule or `@import` with `layer()`, a new anonymous (unnamed) layer is created.

**Note:** The order of precedence of layers is the order in which they are created. Styles not in a layer, or "unlayered styles", cascade together into a final implicit label.

Let's cover the three ways of creating a layer in a little more detail before discussing nested layers.

### The @layer statement at-rule for named layers

The order of layers is set by the order in which the layers appear in your CSS. Declaring layers using `@layer` followed by the names of one or more layers without assigning any styles is one way to define the layer order.

The `@layer` CSS at-rule is used to declare a cascade layer and to define the order of precedence when there are multiple cascade layers. The following at-rule declares three layers, in the order listed:

```css
@layer theme, layout, utilities;
```

You will often want to have your first line of CSS be this `@layer` declaration (with layer names that make sense for your site, of course) to have full control over layer ordering.

If the above statement is the first line of a site's CSS, the layer order will be `theme`, `layout`, and `utilities`. If some layers were created prior to the above statement, as long as layers with these names don't already exist, these three layers will be created and added to the end of the list of existing layers. However, if a layer with the same name already exists, then the above statement will create only two new layers. For example, if `layout` already existed, only `theme` and `utilities` will be created, but the order of layers, in this case, will be `layout`, `theme`, and `utilities`.

### The @layer block at-rule for named and anonymous layers

Layers can be created using the block `@layer` at-rule. If an `@layer` at-rule is followed by an identifier and a block of styles, the identifier is used to name the layer, and the styles in this at-rule are added to the layer's styles. If a layer with the specified name does not already exist, a new layer will be created. If a layer with the specified name already exists, the styles are added to the previously existing layer. If no name is specified while creating a block of styles using `@layer`, the styles in the at-rule will be added to a new anonymous layer.

In the example below, we've used four block and one inline `@layer` at-rules. This CSS does the following in the order listed:

1. Creates a named `layout` layer
2. Creates an unnamed, anonymous layer
3. Declares a list of three layers and creates only two new layers, `theme` and `utilities`, because `layout` already exists
4. Adds additional styles to the already existing `layout` layer
5. Creates a second unnamed, anonymous layer

```css
/\* file: layers1.css \*/

/\* unlayered styles \*/
body {
  color: #333;
}

/\* creates the first layer: `layout` \*/
@layer layout {
  main {
    display: grid;
  }
}

/\* creates the second layer: an unnamed, anonymous layer \*/
@layer {
  body {
    margin: 0;
  }
}

/\* creates the third and fourth layers: `theme` and `utilities` \*/
@layer theme, layout, utilities;

/\* adds styles to the already existing `layout` layer \*/
@layer layout {
  main {
    color: #000;
  }
}

/\* creates the fifth layer: an unnamed, anonymous layer \*/
@layer {
  body {
    margin: 1vw;
  }
}
```

In the above CSS, we created five layers: `layout`, `<anonymous(01)>`, `theme`, `utilities`, and `<anonymous(02)>` – in that order - with a sixth, implicit layer of unlayered styles contained in the `body` style block. The layer order is the order in which the layers are created, with the implicit layer of unlayered styles always being last. There is no way to change the layer order once created.

We assigned some styles to the layer named `layout`. If a named layer doesn't already exist, then specifying the name in an `@layer` at-rule, with or without assigning styles to the layer, creates the layer; this adds the layer to the end of the series of existing layer names. If the named layer already exists, all styles within the named block get appended to styles in the previously existing layer – specifying styles in a block by reusing an existing layer name does not create a new layer.

Anonymous layers are created by assigning styles to a layer without naming the layer. Styles can be added to an unnamed layer only at the time of its creation.

**Note:** Subsequent use of `@layer` with no layer name creates additional unnamed layers; it does not append styles to a previously existing unnamed layer.

The `@layer` at-rule creates a layer, named or not, or appends styles to a layer if the named layer already exists. We called the first anonymous layer `<anonymous(01)>` and the second `<anonymous(02)>`, this is just so we can explain them. These are actually unnamed layers. There is no way to reference them or add additional styles to them.

All styles declared outside of a layer are joined together in an implicit layer. In the example code above, the first declaration set the `color: #333` property on `body`. This was declared outside of any layer. Normal unlayered declarations take precedence over normal layered declarations even if the unlayered styles have a lower specificity and come first in the order of appearance. This explains why even though the unlayered CSS was declared first in the code block, the implicit layer containing these unlayered styles takes precedence as if it was the last declared layer.

In the line `@layer theme, layout, utilities;`, in which a series of layers were declared, only the `theme` and `utilities` layers were created; `layout` was already created in the first line. Note that this declaration does not change the order of already created layers. There is currently no way to re-order layers once declared.

In the following interactive example, we assign styles to two layers, creating them and naming them in the process. Because they already exist, being created when first used, declaring them on the last line does nothing.

Try moving the last line, `@layer site, page;`, to make it the first line. What happens?

#### Layer creation and media queries

If you define a layer using media or feature queries, and the media is not a match or the feature is not supported, the layer is not created. The example below shows how changing the size of your device or browser may change the layer order. In this example, we create the `site` layer only in wider browsers. We then assign styles to the `page` and `site` layers, in that order.

In wide screens, the `site` layer is declared in the first line, meaning `site` has less precedence than `page`. Otherwise, `site` has precedence over `page` because it is declared later on narrow screens. If that doesn't work, try changing the `50em` in the media query to `10em` or `100em`.

### Importing style sheets into named and anonymous layers with @import

The `@import` rule allows users to import style rules from other style sheets either directly into a CSS file or into a `<style>` element.

When importing stylesheets, the `@import` statement must be defined before any CSS styles within the stylesheet or `<style>` block. The `@import` statement must come first, before any styles, but can be preceded by an `@layer` at-rule that creates one or more layers without assigning any styles to the layers. (`@import` can also be preceded by an `@charset` rule.)

You can import a stylesheet into a named layer, a nested named layer, or an anonymous layer. The following layer imports the style sheets into a `components` layer, a nested `dialog` layer within the `components` layer, and an un-named layer, respectively:

```css
@import url("components-lib.css") layer(components);
@import url("dialog.css") layer(components.dialog);
@import url("marketing.css") layer();
```

You can import more than one CSS file into a single layer. The following declaration imports two separate files into a single `social` layer:

```css
@import url(comments.css) layer(social);
@import url(sm-icons.css) layer(social);
```

You can import styles and create layers based on specific conditions using media queries and feature queries. The following imports a style sheet into an `international` layer only if the browser supports `display: ruby`, and the file being imported is dependent on the width of the screen.

```css
@import url("ruby-narrow.css") layer(international) supports(display: ruby) and
 (width < 32rem);
@import url("ruby-wide.css") layer(international) supports(display: ruby) and
 (width >= 32rem);
```

**Note:** There is no equivalent of the `<link>` method of linking stylesheets. Use `@import` to import a stylesheet into a layer when you can't use `@layer` within the stylesheet.

Overview of nested cascade layers
---------------------------------

Nested layers are layers within a named or an anonymous layer. Each cascade layer, even an anonymous one, can contain nested layers. Layers imported into another layer become nested layers within that layer.

### Advantages of nesting layers

The ability to nest layers enables teams to create cascade layers without worrying about whether other teams will import them into a layer. Similarly, nesting enables you to import third-party style sheets into a layer without worrying if that style sheet itself has layers. Because layers can be nested, you don't have to worry about having conflicting layer names between external and internal style sheets.

### Creating nested cascade layers

Nested layers can be created using the same methods as described for regular layers. For example, they can be created using `@layer` at-rule followed by the names of one or more layers, using a dot notation. Multiple dots and layer names signify multiple nesting.

If you nest a block `@layer` at-rule inside another block `@layer` at-rule, with or without a name, the nested block becomes a nested layer. Similarly, when a style sheet is imported with an `@import` declaration containing the `layer` keyword or `layer()` function, the styles get assigned to that named or anonymous layer. If the `@import` statement contains layers, those layers become nested layers within that anonymous or named layer.

Let's look at the following example:

```css
@import url("components-lib.css") layer(components);
@import url("narrowtheme.css") layer(components.narrow);
```

In the first line, we import `components-lib.css` into the `components` layer. If that file contains any layers, named or not, those layers become nested layers within the `components` layer.

The second line imports `narrowtheme.css` into the `narrow` layer, which is a sub-layer of `components`. The nested `components.narrow` gets created as the last layer within the `components` layer, unless `components-lib.css` already contains a `narrow` layer, in which case, the contents of `narrowtheme.css` would be appended to the `components.narrow` nested layer. Additional nested named layers can be added to the `components` layer using the pattern `components.<layerName>`. As mentioned before, unnamed layers can be created but they cannot be accessed subsequently.

Let's look at another example, where we import `layers1.css` into a named layer using the following statement:

```css
@import url(layers1.css) layer(example);
```

This will create a single layer named `example` containing some declarations and five nested layers - `example.layout`, `example.<anonymous(01)>`, `example.theme`, `example.utilities`, and `example.<anonymous(02)>`.

To add styles to a named nested layer, use the dot notation:

```css
@layer example.layout {
  main {
    width: 50vw;
  }
}
```

Determining the precedence based on the order of layers
-------------------------------------------------------

The order of layers determines their order of precedence. Therefore, the order of layers is very important. In the same way as the cascade sorts by origin and importance, the cascade sorts each CSS declaration by origin layer and importance.

### Precedence order of regular cascade layers

```css
@import url(A.css) layer(firstLayer);
@import url(B.css) layer(secondLayer);
@import url(C.css);
```

The above code creates two named layers (C.css styles get appended to the implicit layer of unlayered styles). Let us assume that the three files (`A.css`, `B.css`, and `C.css`) do not contain any additional layers within them. The following list shows where styles declared inside and outside of these files will be sorted from least (1) precedence to highest (10).

1. `firstLayer` normal styles (`A.css`)
2. `secondLayer` normal styles (`B.css`)
3. unlayered normal styles (`C.css`)
4. inline normal styles
5. animating styles
6. unlayered important styles (`C.css`)
7. `secondLayer` important styles (`B.css`)
8. `firstLayer` important styles (`A.css`)
9. inline important styles
10. transitioning styles

Normal styles declared inside layers receive the lowest priority and are sorted by the order in which the layers were created. Normal styles in the first created layer have the lowest precedence, and normal styles in the layer created last have the highest precedence among the layers. In other words, normal styles declared within `firstLayer` will be overridden by any subsequent stylings on the list if any conflicts exist.

Next up are any styles declared outside of layers. The styles in `C.css` were not imported into a layer and will override any conflicting styles from `firstLayer` and `secondLayer`. Styles not declared in a layer always have higher precedence than styles that *are* declared inside a layer (with the exception of important styles).

Inline styles are declared using the `style` attribute. Normal styles declared in this way will take precedence over normal styles found in the unlayered and layered style sheets (`firstLayer – A.css`, `secondLayer – B.css`, and `C.css`).

Animating styles have higher precedence than all normal styles, including inline normal styles.

Important styles, that is, property values that include the `!important` flag, take precedence over any styles previously mentioned in our list. They are sorted in reverse order of normal styles. Any important styles declared outside of a layer have less precedence than those declared within a layer. Important styles found within layers are also sorted in order of layer creation. For important styles, the last created layer has the lowest precedence, and the first created layer has the highest precedence among declared layers.

Inline important styles again have higher precedence than important styles declared elsewhere.

Transitioning styles have the highest precedence. When a normal property value is being transitioned, it takes precedence over all other property value declarations, even inline important styles; but only while transitioning.

In this example, there are two inline layers `A` and `B` without styles, a block of unlayered styles, and two blocks of styles in named layers `A` and `B`.

The inline styles added on the `h1` element using the `style` attribute, set a normal `color` and an important `background-color`. Normal inline styles override all layered and unlayered normal styles. Important inline styles override all layered and unlayered normal and important author styles. There is no way for author styles to override important inline styles.

The normal `text-decoration` and important `box-shadow` are not part of the `style` inline styles and can therefore be overridden. For normal non-inline styles, unlayered styles have precedence. For important styles, layer order matters too. While normal unlayered styles override all normal styles set in a layer, with important styles, the precedence order is reversed; unlayered important styles have lower precedence than layered styles.

The two styles declared only within layers are `font-style`, with normal importance, and `font-weight` with an `!important` flag. For normal styles, the `B` layer, declared last, overrides styles in the earlier declared layer `A`. For normal styles, later layers have precedence over earlier layers. The order of precedence is reversed for important styles. For the important `font-weight` declarations, layer `A`, being declared first, has precedence over the last declared layer `B`.

You can reverse the layer order by changing the first line from `@layer A, B;` to `@layer B, A;`. Try that. Which styles get changed by this, and which stay the same? Why?

The order of layers is set by the order in which the layers appear in your CSS. In our first line, we declared layers without assigning any styles using `@layer` followed by the names of our layers, ending with a semi-colon. Had we omitted this line, the results would have been the same. Why? We assigned style rules in named `@layer` blocks in the order A then B. The two layers were created in that first line. Had they not been, these rule blocks would have created them, in that order.

We included that first line for two reasons: first so you could easily edit the line and switch the order, and second because often you'll find declaring the order layer up front to be the best practice for your layer order management.

To summarize:

* The order of precedence of layers is the order in which the layers are created.
* Once created, there is no way to change the layer order.
* Layer precedence for normal styles is the order in which the layers are created.
* Unlayered normal styles have precedence over normal layered styles.
* Layer precedence for important styles is reversed, with earlier created layers having precedence.
* All layered important styles have precedence over unlayered important (and normal) styles.
* Normal inline styles take precedence over all normal styles, layered or not.
* Important inline styles take precedence over all other styles, with the exception of styles being transitioned.
* There is no way for author styles to override important inline styles (other than transitioning them, which is temporary).
### Precedence order of nested cascade layers

The cascade precedence order for nested layers is similar to that of regular layers, but contained within the layer. The precedence order is based on the order of nested layer creation. Non-nested styles in a layer have precedence over nested normal styles, with the precedence order reversed for important styles. Specificity weight between nested layers does not matter, though it does matter for conflicting styles within a nested layer.

The following creates and adds styles to the `components` layer and `components.narrow` nested layer and creates and appends styles to a new `components.wide` layer:

```css
@import url("components-lib.css") layer(components);
@import url("narrowtheme.css") layer(components.narrow);

@layer components {
  :root {
    --theme: red;
    font-family: serif !important;
  }
}
@layer components.narrow {
  :root {
    --theme: blue;
    font-family: sans-serif !important;
  }
}
@layer components.wide {
  :root {
    --theme: purple;
    font-family: cursive !important;
  }
}
```

Because unlayered normal styles have precedence over layered normal styles, and within a layer, non-nested styles have precedence over normal nested styles, `red` wins over the other `theme` colors.

With important styles, layered styles take precedence over unlayered styles, with important styles in earlier declared layers having precedence over later declared layers. In this example, the order of nested layer creation is `components.narrow`, then `components.wide`, so important styles in `components.narrow` have precedence over important styles in `components.wide`, meaning `sans-serif` wins.

Test your skills!
-----------------

You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: The Cascade, Task 2.

Summary
-------

If you understood most of this article, then well done — you're now familiar with the fundamental mechanics of CSS cascade layers. Next up, we'll look at the box model in detail.

* Previous
* Overview: Building blocks
* Next


Sizing items in CSS - Learn web development

Sizing items in CSS
===================

* Previous
* Overview: Building blocks
* Next

In the various lessons so far, you have come across a number of ways to size items on a web page using CSS. Understanding how big the different features in your design will be is important. So, in this lesson we will summarize the various ways elements get a size via CSS and define a few terms about sizing that will help you in the future.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, HTML basics (study
 Introduction to HTML), and an idea of how CSS works (study
 CSS first steps.)
  |
| Objective: | To understand the different ways we can size things in CSS. |

The natural or intrinsic size of things
---------------------------------------

HTML Elements have a natural size, set before they are affected by any CSS. A straightforward example is an image. An image file contains sizing information, described as its **intrinsic size**. This size is determined by the image *itself*, not by any formatting we happen to apply.

If you place an image on a page and do not change its height or width, either by using attributes on the `<img>` tag or else by CSS, it will be displayed using that intrinsic size. We have given the image in the example below a border so that you can see the extent of its size as defined in its file.

An empty `<div>`, on the other hand, has no size of its own. If you add a `<div>` to your HTML with no content, then give it a border as we did with the image, you will see a line on the page. This is the collapsed border on the element — there is no content to hold it open. In our example below, that border stretches to the width of the container, because it is a block level element, a behavior that should be starting to become familiar to you. It has no height (or size in the block dimension) because there is no content.

In the example above, try adding some text inside the empty element. The border now contains that text because the height of the element is defined by the content. Therefore the size of this `<div>` in the block dimension comes from the size of the content. Again, this is the intrinsic size of the element — its size is defined by its content.

Setting a specific size
-----------------------

We can, of course, give elements in our design a specific size. When a size is given to an element (the content of which then needs to fit into that size) we refer to it as an **extrinsic size**. Take our `<div>` from the example above — we can give it specific `width` and `height` values, and it will now have that size no matter what content is placed into it. As we discovered in our previous lesson on overflow, a set height can cause content to overflow if there is more content than the element has space to fit inside it.

Due to this problem of overflow, fixing the height of elements with lengths or percentages is something we need to do very carefully on the web.

### Using percentages

In many ways, percentages act like length units, and as we discussed in the lesson on values and units, they can often be used interchangeably with lengths. When using a percentage you need to be aware what it is a percentage *of*. In the case of a box inside another container, if you give the child box a percentage width it will be a percentage of the width of the parent container.

This is because percentages resolve against the size of the containing block. With no percentage applied, our `<div>` would take up 100% of the available space, as it is a block level element. If we give it a percentage width, this becomes a percentage of the space it would normally fill.

### Percentage margins and padding

If you set `margins` and `padding` as a percentage, you may notice some strange behavior. In the below example we have a box. We have given the inner box a `margin` of 10% and a `padding` of 10%. The padding and margin on the top and bottom of the box are the same size as the padding and margin on the left and right.

You might expect for example the percentage top and bottom margins to be a percentage of the element's height, and the percentage left and right margins to be a percentage of the element's width. However, this is not the case!

When you use margin and padding set in percentages, the value is calculated from the **inline size** of the containing block — therefore the width when working in a horizontal language. In our example, all of the margins and padding are 10% of the width. This means you can have equal-sized margins and padding all around the box. This is a fact worth remembering if you do use percentages in this way.

min- and max- sizes
-------------------

In addition to giving things a fixed size, we can ask CSS to give an element a minimum or a maximum size. If you have a box that might contain a variable amount of content, and you always want it to be *at least* a certain height, you could set the `min-height` property on it. The box will always be at least this height, but will then grow taller if there is more content than the box has space for at its minimum height.

In the example below you can see two boxes, both with a defined `min-height` of 150 pixels. The box on the left is 150 pixels tall; the box on the right has content that needs more room, and so it has grown taller than 150 pixels.

This is very useful for dealing with variable amounts of content while avoiding overflow.

A common use of `max-width` is to cause images to scale down if there is not enough space to display them at their intrinsic width while making sure they don't become larger than that width.

As an example, if you were to set `width: 100%` on an image, and its intrinsic width was smaller than its container, the image would be forced to stretch and become larger, causing it to look pixelated.

If you instead use `max-width: 100%`, and its intrinsic width is smaller than its container, the image will not be forced to stretch and become larger, thus preventing pixelation.

In the example below, we have used the same image three times. The first image has been given `width: 100%` and is in a container which is larger than it, therefore it stretches to the container width. The second image has `max-width: 100%` set on it and therefore does not stretch to fill the container. The third box contains the same image again, also with `max-width: 100%` set; in this case you can see how it has scaled down to fit into the box.

This technique is used to make images *responsive*, so that when viewed on a smaller device they scale down appropriately. You should, however, not use this technique to load really large images and then scale them down in the browser. Images should be appropriately sized to be no larger than they need to be for the largest size they are displayed in the design. Downloading overly large images will cause your site to become slow, and it can cost users more money if they are on a metered connection.

**Note:** Find out more about responsive image techniques.

Viewport units
--------------

The viewport — which is the visible area of your page in the browser you are using to view a site — also has a size. In CSS we have units which relate to the size of the viewport — the `vw` unit for viewport width, and `vh` for viewport height. Using these units you can size something relative to the viewport of the user.

`1vh` is equal to 1% of the viewport height, and `1vw` is equal to 1% of the viewport width. You can use these units to size boxes, but also text. In the example below we have a box which is sized as 20vh and 20vw. The box contains a letter `A`, which has been given a `font-size` of 10vh.

**If you change the `vh` and `vw` values this will change the size of the box or font; changing the viewport size will also change their sizes because they are sized relative to the viewport. To see the example change when you change the viewport size you will need to load the example in a new browser window that you can resize (as the embedded `<iframe>` that contains the example shown above is its viewport). Open the example, resize the browser window, and observe what happens to the size of the box and text.**

Sizing things according to the viewport can be useful in your designs. For example, if you want a full-page hero section to show before the rest of your content, making that part of your page 100vh high will push the rest of the content below the viewport, meaning that it will only appear once the document is scrolled.

Test your skills!
-----------------

You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: Sizing.

Summary
-------

This lesson has given you a rundown of some key issues that you might run into when sizing things on the web. When you move onto CSS Layout, sizing will become very important in mastering the different layout methods, so it is worth understanding the concepts here before moving on.

In the next article, we'll take a look at how images, media, and form elements are treated in CSS.

* Previous
* Overview: Building blocks
* Next


Pseudo-classes and pseudo-elements - Learn web development

Pseudo-classes and pseudo-elements
==================================

* Previous
* Overview: Building blocks
* Next

The next set of selectors we will look at are referred to as **pseudo-classes** and **pseudo-elements**. There are a large number of these, and they often serve quite specific purposes. Once you know how to use them, you can look at the list to see if there is something which works for the task you are trying to achieve. Once again the relevant MDN page for each selector is helpful in explaining browser support.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, HTML basics (study
 Introduction to HTML), and an idea of how CSS works (study
 CSS first steps).
  |
| Objective: | To learn about the pseudo-class and pseudo-element selectors. |

What is a pseudo-class?
-----------------------

A pseudo-class is a selector that selects elements that are in a specific state, e.g. they are the first element of their type, or they are being hovered over by the mouse pointer. They tend to act as if you had applied a class to some part of your document, often helping you cut down on excess classes in your markup, and giving you more flexible, maintainable code.

Pseudo-classes are keywords that start with a colon. For example, `:hover` is a pseudo-class.

### Simple pseudo-class example

Let's look at a simple example. If we wanted to make the first paragraph in an article larger and bold, we could add a class to that paragraph and then add CSS to that class, as shown in the first example below:

However, this could be annoying to maintain — what if a new paragraph got added to the top of the document? We'd need to move the class over to the new paragraph. Instead of adding the class, we could use the `:first-child` pseudo-class selector — this will *always* target the first child element in the article, and we will no longer need to edit the HTML (this may not always be possible anyway, maybe due to it being generated by a CMS).

All pseudo-classes behave in this same kind of way. They target some bit of your document that is in a certain state, behaving as if you had added a class into your HTML. Take a look at some other examples on MDN:

* `:last-child`
* `:only-child`
* `:invalid`

**Note:** It is valid to write pseudo-classes and elements without any element selector preceding them. In the example above, you could write `:first-child` and the rule would apply to *any* element that is the first child of an `<article>` element, not just a paragraph first child — `:first-child` is equivalent to `*:first-child`. However, usually you want more control than that, so you need to be more specific.

### User-action pseudo classes

Some pseudo-classes only apply when the user interacts with the document in some way. These **user-action** pseudo-classes, sometimes referred to as **dynamic pseudo-classes**, act as if a class had been added to the element when the user interacts with it. Examples include:

* `:hover` — mentioned above; this only applies if the user moves their pointer over an element, typically a link.
* `:focus` — only applies if the user focuses the element by clicking or using keyboard controls.

What is a pseudo-element?
-------------------------

Pseudo-elements behave in a similar way. However, they act as if you had added a whole new HTML element into the markup, rather than applying a class to existing elements.

Pseudo-elements start with a double colon `::`. `::before` is an example of a pseudo-element.

**Note:** Some early pseudo-elements used the single colon syntax, so you may sometimes see this in code or examples. Modern browsers support the early pseudo-elements with single- or double-colon syntax for backwards compatibility.

For example, if you wanted to select the first line of a paragraph you could wrap it in a `<span>` element and use an element selector; however, that would fail if the number of words you had wrapped were longer or shorter than the parent element's width. As we tend not to know how many words will fit on a line — as that will change if the screen width or font-size changes — it is impossible to robustly do this by adding HTML.

The `::first-line` pseudo-element selector will do this for you reliably — if the number of words increases or decreases it will still only select the first line.

It acts as if a `<span>` was magically wrapped around that first formatted line, and updated each time the line length changed.

You can see that this selects the first line of both paragraphs.

Combining pseudo-classes and pseudo-elements
--------------------------------------------

If you wanted to make the first line of the first paragraph bold you could chain the `:first-child` and `::first-line` selectors together. Try editing the previous live example so it uses the following CSS. We are saying that we want to select the first line, of the first `<p>` element, which is inside an `<article>` element.

```css
article p:first-child::first-line {
  font-size: 120%;
  font-weight: bold;
}
```

Generating content with ::before and ::after
--------------------------------------------

There are a couple of special pseudo-elements, which are used along with the `content` property to insert content into your document using CSS.

You could use these to insert a string of text, such as in the live example below. Try changing the text value of the `content` property and see it change in the output. You could also change the `::before` pseudo-element to `::after` and see the text inserted at the end of the element instead of the beginning.

Inserting strings of text from CSS isn't really something we do very often on the web however, as that text is inaccessible to some screen readers and might be hard for someone to find and edit in the future.

A more valid use of these pseudo-elements is to insert an icon, for example the little arrow added in the example below, which is a visual indicator that we wouldn't want read out by a screen reader:

These pseudo-elements are also frequently used to insert an empty string, which can then be styled just like any element on the page.

In this next example, we have added an empty string using the `::before` pseudo-element. We have set this to `display: block` in order that we can style it with a width and height. We then use CSS to style it just like any element. You can play around with the CSS and change how it looks and behaves.

The use of the `::before` and `::after` pseudo-elements along with the `content` property is referred to as "Generated Content" in CSS, and you will often see this technique being used for various tasks. A great example is the site CSS Arrow Please, which helps you to generate an arrow with CSS. Look at the CSS as you create your arrow and you will see the `::before` and `::after` pseudo-elements in use. Whenever you see these selectors, look at the `content` property to see what is being added to the HTML element.

Summary
-------

In this article we've introduced CSS pseudo-classes and pseudo-elements, which are special types of selectors.

Pseudo-classes enable you to target an element when it's in a particular state, as if you had added a class for that state to the DOM. Pseudo-elements act as if you had added a whole new element to the DOM, and enable you to style that. The `::before` and `::after` pseudo-elements enable you to insert content into the document using CSS.

In the next article, we'll learn about combinators.

See also
--------

* Pseudo-classes reference
* Pseudo-elements reference
* Previous
* Overview: Building blocks
* Next


Type, class, and ID selectors - Learn web development

Type, class, and ID selectors
=============================

* Previous
* Overview: Building blocks
* Next

In this lesson, we examine some of the simplest selectors, which you will probably use most frequently in your work.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, HTML basics (study
 Introduction to HTML), and an idea of how CSS works (study
 CSS first steps.)
  |
| Objective: |
 To learn about the different CSS selectors we can use to apply CSS to a
 document.
  |

Type selectors
--------------

A **type selector** is sometimes referred to as a *tag name selector* or *element selector* because it selects an HTML tag/element in your document. Type selectors are not case-sensitive. In the example below, we have used the `span`, `em` and `strong` selectors.

**Try adding a CSS rule to select the `<h1>` element and change its color to blue.**

The universal selector
----------------------

The universal selector is indicated by an asterisk (`*`). It selects everything in the document (or inside the parent element if it is being chained together with another element and a descendant combinator). In the following example, we use the universal selector to remove the margins on all elements. Instead of the default styling added by the browser — which spaces out headings and paragraphs with margins — everything is close together.

This kind of behavior can sometimes be seen in "reset stylesheets", which strip out all of the browser styling. Since the universal selector makes global changes, we use it for very specific situations, such as the one described below.

### Using the universal selector to make your selectors easier to read

One use of the universal selector is to make selectors easier to read and more obvious in terms of what they are doing. For example, if we wanted to select any descendant elements of an `<article>` element that are the first child of their parent, including direct children, and make them bold, we could use the `:first-child` pseudo-class. We will learn more about this in the lesson on pseudo-classes and pseudo-elements, as a descendant selector along with the `<article>` element selector:

```css
article :first-child {
  font-weight: bold;
}
```

However, this selector could be confused with `article:first-child`, which will select any `<article>` element that is the first child of another element.

To avoid this confusion, we can add the universal selector to the `:first-child` pseudo-class, so it is more obvious what the selector is doing. It is selecting *any* element which is the first-child of an `<article>` element, or the first-child of any descendant element of `<article>`:

```css
article \*:first-child {
  font-weight: bold;
}
```

Although both do the same thing, the readability is significantly improved.

Class selectors
---------------

The case-sensitive class selector starts with a dot (`.`) character. It will select everything in the document with that class applied to it. In the live example below we have created a class called `highlight`, and have applied it to several places in my document. All of the elements that have the class applied are highlighted.

### Targeting classes on particular elements

You can create a selector that will target specific elements with the class applied. In this next example, we will highlight a `<span>` with a class of `highlight` differently to an `<h1>` heading with a class of `highlight`. We do this by using the type selector for the element we want to target, with the class appended using a dot, with no white space in between.

This approach reduces the scope of a rule. The rule will only apply to that particular element and class combination. You would need to add another selector if you decided the rule should apply to other elements too.

### Target an element if it has more than one class applied

You can apply multiple classes to an element and target them individually, or only select the element when all of the classes in the selector are present. This can be helpful when building up components that can be combined in different ways on your site.

In the example below, we have a `<div>` that contains a note. The grey border is applied when the box has a class of `notebox`. If it also has a class of `warning` or `danger`, we change the `border-color`.

We can tell the browser that we only want to match the element if it has two classes applied by chaining them together with no white space between them. You'll see that the last `<div>` doesn't get any styling applied, as it only has the `danger` class; it needs `notebox` as well to get anything applied.

ID selectors
------------

The case-sensitive ID selector begins with a `#` rather than a dot character, but is used in the same way as a class selector. However, an ID can be used only once per page, and elements can only have a single `id` value applied to them. It can select an element that has the `id` set on it, and you can precede the ID with a type selector to only target the element if both the element and ID match. You can see both of these uses in the following example:

**Warning:** Using the same ID multiple times in a document may appear to work for styling purposes, but don't do this. It results in invalid code, and will cause strange behavior in many places.

**Note:** The ID selector has high `specificity`. This means styles applied based on matching an ID selector will overrule styles applied based on other selector, including class and type selectors. Because an ID can only occur once on a page and because of the high specificity of ID selectors, it is preferable to add a class to an element instead of an ID. If using the ID is the only way to target the element — perhaps because you do not have access to the markup and cannot edit it — consider using the ID within an attribute selector, such as `p[id="header"]`. Learn specificity.

Summary
-------

That wraps up Type, class, and ID selectors. We'll continue exploring selectors by looking at attribute selectors.

* Previous
* Overview: Building blocks
* Next


Combinators - Learn web development

Combinators
===========

* Previous
* Overview: Building blocks
* Next

The final selectors we will look at are called combinators, because they combine other selectors in a way that gives them a useful relationship to each other and the location of content in the document.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, HTML basics (study
 Introduction to HTML), and an idea of how CSS works (study
 CSS first steps.)
  |
| Objective: |
 To learn about the different combinator selectors that can be used in
 CSS.
  |

Descendant combinator
---------------------

The **descendant combinator** — typically represented by a single space (" ") character — combines two selectors such that elements matched by the second selector are selected if they have an ancestor (parent, parent's parent, parent's parent's parent, etc.) element matching the first selector. Selectors that utilize a descendant combinator are called *descendant selectors*.

```css
body article p
```

In the example below, we are matching only the `<p>` element which is inside an element with a class of `.box`.

Child combinator
----------------

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

```css
article > p
```

In this next example, we have an unordered list, nested inside of which is an ordered list. The child combinator selects only those `<li>` elements which are direct children of a `<ul>`, and styles them with a top border.

If you remove the `>` that designates this as a child combinator, you end up with a descendant selector and all `<li>` elements will get a red border.

Next-sibling combinator
-----------------------

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

```css
p + img
```

A common use case is to do something with a paragraph that follows a heading, as in the example below. In that example, we are looking for any paragraph which shares a parent element with an `<h1>`, and immediately follows that `<h1>`.

If you insert some other element such as a `<h2>` in between the `<h1>` and the `<p>`, you will find that the paragraph is no longer matched by the selector and so does not get the background and foreground color applied when the element is adjacent.

Subsequent-sibling combinator
-----------------------------

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

```css
p ~ img
```

In the example below we are selecting all `<p>` elements that come after the `<h1>`, and even though there is a `<div>` in the document as well, the `<p>` that comes after it is selected.

Creating complex selectors with nesting
---------------------------------------

The CSS nesting module allows you to write nested rules that use combinators to create complex selectors.

```css
p {
  ~ img {
  }
}
/\* This is parsed by the browser as \*/
p ~ img {
}
```

The `&` nesting selector can also be used to create complex selectors.

```css
p {
  & img {
  }
}
/\* This is parsed by the browser as \*/
p img {
}
```

**Note:** In the example above, the `&` nesting selector is not required, but adding it helps to explicitly show that CSS nesting is being used.

Using combinators
-----------------

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

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

Take care, however, when creating big lists of selectors that select very specific parts of your document. It will be hard to reuse the CSS rules since you have made the selector very specific to the location of that element in the markup.

It is often better to create a simple class and apply that to the element in question. That said, your knowledge of combinators will be very useful if you need to style something in your document and are unable to access the HTML, perhaps due to it being generated by a CMS.

Test your skills!
-----------------

You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: Selectors.

Summary
-------

This is the last section in our lessons on selectors. Next, we'll move on to another important part of CSS — the cascade, specificity, and inheritance.

* Previous
* Overview: Building blocks
* Next


Test your skills: Selectors - Learn web development

Test your skills: Selectors
===========================

The aim of this skill test is to assess whether you understand CSS selectors.

**Note:** You can try solutions in the interactive editors on this page or in an online editor such as CodePen, JSFiddle, or Glitch.

If you get stuck, you can reach out to us in one of our communication channels.

Task 1
------

In this task, use CSS to do the following things, without changing the HTML:

* Make `<h1>` headings blue.
* Give `<h2>` headings a blue background and white text.
* Cause text wrapped in a `<span>` to have a font-size of 200%.

Your final result should look like the image below:

![Text with the CSS applied for the solution to task 1.](/en-US/docs/Learn/CSS/Building_blocks/Selectors/Selectors_Tasks/selectors1.jpg)

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

Task 2
------

In this task, we want you to make the following changes to the look of the content in this example, without changing the HTML:

* Give the element with an id of `special` a yellow background.
* Give the element with a class of `alert` a 1px grey border.
* If the element with a class of `alert` also has a class of `stop`, make the background red.
* If the element with a class of `alert` also has a class of `go`, make the background green.

Your final result should look like the image below:

![Text with the CSS applied for the solution to task 2.](/en-US/docs/Learn/CSS/Building_blocks/Selectors/Selectors_Tasks/selectors2.jpg)

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

Task 3
------

In this task, we want you to make the following changes without adding to the HTML:

* Style links, making the link-state orange, visited links green, and remove the underline on hover.
* Make the first element inside the container font-size: 150% and the first line of that element red.
* Stripe every other row in the table by selecting these rows and giving them a background color of #333 and foreground of white.

Your final result should look like the image below:

![Text with the CSS applied for the solution to task 3.](/en-US/docs/Learn/CSS/Building_blocks/Selectors/Selectors_Tasks/selectors3.jpg)

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

Task 4
------

In this task, we want you to do the following:

* Make any paragraph that directly follows an `<h2>` element red.
* Remove the bullets and add a 1px grey bottom border only to list items that are a direct child of the ul with a class of `list`.

Your final result should look like the image below:

![Text with the CSS applied for the solution to task 4.](/en-US/docs/Learn/CSS/Building_blocks/Selectors/Selectors_Tasks/selectors4.jpg)

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

Task 5
------

In this task, add CSS using attribute selectors to do the following:

* Target the `<a>` element with a `title` attribute and make the border pink (`border-color: pink`).
* Target the `<a>` element with an `href` attribute that contains the word `contact` somewhere in its value and make the border orange (`border-color: orange`).
* Target the `<a>` element with an `href` value starting with `https` and give it a green border (`border-color: green`).

Your final result should look like the image below:

![Four links with different color borders.](/en-US/docs/Learn/CSS/Building_blocks/Selectors/Selectors_Tasks/selectors-attribute.png)

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.


Attribute selectors - Learn web development

Attribute selectors
===================

* Previous
* Overview: Building blocks
* Next

As you know from your study of HTML, elements can have attributes that give further detail about the element being marked up. In CSS you can use attribute selectors to target elements with certain attributes. This lesson will show you how to use these very useful selectors.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, HTML basics (study
 Introduction to HTML), and an idea of how CSS works (study
 CSS first steps.)
  |
| Objective: | To learn what attribute selectors are and how to use them. |

Presence and value selectors
----------------------------

These selectors enable the selection of an element based on the presence of an attribute alone (for example `href`), or on various different matches against the value of the attribute.

| Selector | Example | Description |
| --- | --- | --- |
| `[*attr*]` | `a[title]` |
 Matches elements with an *attr* attribute (whose name is the
 value in square brackets).
  |
| `[*attr*=*value*]` | `a[href="https://example.com"]` |
 Matches elements with an *attr* attribute whose value is exactly
 *value* — the string inside the quotes.
  |
| `[*attr*~=*value*]` | `p[class~="special"]` |
Matches elements with an *attr* attribute whose value is
 exactly *value*, or contains *value* in its (space
 separated) list of values.
  |
| `[*attr*|=*value*]` | `div[lang|="zh"]` |
 Matches elements with an *attr* attribute whose value is exactly
 *value* or begins with *value* immediately followed by a
 hyphen.
  |

In the example below you can see these selectors being used.

* By using `li[class]` we can match any list item with a class attribute. This matches all of the list items except the first one.
* `li[class="a"]` matches a selector with a class of `a`, but not a selector with a class of `a` with another space-separated class as part of the value. It selects the second list item.
* `li[class~="a"]` will match a class of `a` but also a value that contains the class of `a` as part of a whitespace-separated list. It selects the second and third list items.

Substring matching selectors
----------------------------

These selectors allow for more advanced matching of substrings inside the value of your attribute. For example, if you had classes of `box-warning` and `box-error` and wanted to match everything that started with the string "box-", you could use `[class^="box-"]` to select them both (or `[class|="box"]` as described in section above).

| Selector | Example | Description |
| --- | --- | --- |
| `[attr^=value]` | `li[class^="box-"]` | Matches elements with an *attr* attribute, whose value begins with *value*. |
| `[attr$=value]` | `li[class$="-box"]` | Matches elements with an *attr* attribute whose value ends with *value*. |
| `[attr*=value]` | `li[class*="box"]` | Matches elements with an *attr* attribute whose value contains *value* anywhere within the string. |

(Aside: It may help to note that `^` and `$` have long been used as *anchors* in so-called *regular expressions* to mean *begins with* and *ends with* respectively.)

The next example shows usage of these selectors:

* `li[class^="a"]` matches any attribute value which starts with `a`, so matches the first two list items.
* `li[class$="a"]` matches any attribute value that ends with `a`, so matches the first and third list item.
* `li[class*="a"]` matches any attribute value where `a` appears anywhere in the string, so it matches all of our list items.

Case-sensitivity
----------------

If you want to match attribute values case-insensitively you can use the value `i` before the closing bracket. This flag tells the browser to match ASCII characters case-insensitively. Without the flag the values will be matched according to the case-sensitivity of the document language — in HTML's case it will be case sensitive.

In the example below, the first selector will match a value that begins with `a` — it only matches the first list item because the other two list items start with an uppercase A. The second selector uses the case-insensitive flag and so matches all of the list items.

**Note:** There is also a newer value `s`, which will force case-sensitive matching in contexts where matching is normally case-insensitive, however this is less well supported in browsers and isn't very useful in an HTML context.

Summary
-------

Now that we are done with attribute selectors, you can continue on to the next article and read about pseudo-class and pseudo-element selectors.

* Previous
* Overview: Building blocks
* Next


Getting started with CSS - Learn web development

Getting started with CSS
========================

* Previous
* Overview: First steps
* Next

In this article, we will take a simple HTML document and apply CSS to it, learning some practical things about the language along the way.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, and HTML basics (study
 Introduction to HTML.)
  |
| Objective: |
 To understand the basics of linking a CSS document to an HTML file, and
 be able to do simple text formatting with CSS.
  |

Starting with some HTML
-----------------------

Our starting point is an HTML document. You can copy the code from below if you want to work on your own computer. Save the code below as `index.html` in a folder on your machine.

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Getting started with CSS</title>
  </head>

  <body>
    <h1>I am a level one heading</h1>

    <p>
      This is a paragraph of text. In the text is a
      <span>span element</span> and also a
      <a href="https://example.com">link</a>.
    </p>

    <p>
      This is the second paragraph. It contains an <em>emphasized</em> element.
    </p>

    <ul>
      <li>Item <span>one</span></li>
      <li>Item two</li>
      <li>Item <em>three</em></li>
    </ul>
  </body>
</html>
```

**Note:** If you are reading this on a device or an environment where you can't easily create files, then don't worry — live code editors are provided below to allow you to write example code right here in the page.

Adding CSS to our document
--------------------------

The very first thing we need to do is to tell the HTML document that we have some CSS rules we want it to use. There are three different ways to apply CSS to an HTML document that you'll commonly come across, however, for now, we will look at the most usual and useful way of doing so — linking CSS from the head of your document.

Create a file in the same folder as your HTML document and save it as `styles.css`. The `.css` extension shows that this is a CSS file.

To link `styles.css` to `index.html`, add the following line somewhere inside the `<head>` of the HTML document:

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

This `<link>` element tells the browser that we have a stylesheet, using the `rel` attribute, and the location of that stylesheet as the value of the `href` attribute. You can test that the CSS works by adding a rule to `styles.css`. Using your code editor, add the following to your CSS file:

```css
h1 {
  color: red;
}
```

Save your HTML and CSS files and reload the page in a web browser. The level one heading at the top of the document should now be red. If that happens, congratulations — you have successfully applied some CSS to an HTML document. If that doesn't happen, carefully check that you've typed everything correctly.

You can continue to work in `styles.css` locally, or you can use our interactive editor below to continue with this tutorial. The interactive editor acts as if the CSS in the first panel is linked to the HTML document, just as we have with our document above.

Styling HTML elements
---------------------

By making our heading red, we have already demonstrated that we can target and style an HTML element. We do this by targeting an *element selector* — this is a selector that directly matches an HTML element name. To target all paragraphs in the document, you would use the selector `p`. To turn all paragraphs green, you would use:

```css
p {
  color: green;
}
```

You can target multiple selectors at the same time by separating the selectors with a comma. If you want all paragraphs and all list items to be green, your rule would look like this:

```css
p,
li {
  color: green;
}
```

Try this out in the interactive editor below (edit the code boxes) or in your local CSS document.

Changing the default behavior of elements
-----------------------------------------

When we look at a well-marked up HTML document, even something as simple as our example, we can see how the browser is making the HTML readable by adding some default styling. Headings are large and bold and our list has bullets. This happens because browsers have internal stylesheets containing default styles, which they apply to all pages by default; without them all of the text would run together in a clump and we would have to style everything from scratch. All modern browsers display HTML content by default in pretty much the same way.

However, you will often want something other than the choice the browser has made. This can be done by choosing the HTML element that you want to change and using a CSS rule to change the way it looks. A good example is `<ul>`, an unordered list. It has list bullets. If you don't want those bullets, you can remove them like so:

```css
li {
  list-style-type: none;
}
```

Try adding this to your CSS now.

The `list-style-type` property is a good property to look at on MDN to see which values are supported. Take a look at the page for `list-style-type` and you will find an interactive example at the top of the page to try some different values in, then all allowable values are detailed further down the page.

Looking at that page you will discover that in addition to removing the list bullets, you can change them — try changing them to square bullets by using a value of `square`.

Adding a class
--------------

So far, we have styled elements based on their HTML element names. This works as long as you want all of the elements of that type in your document to look the same. To select a subset of the elements without changing the others, you can add a class to your HTML element and target that class in your CSS.

1. In your HTML document, add a class attribute to the second list item. Your list will now look like this:

```html
<ul>
  <li>Item one</li>
  <li class="special">Item two</li>
  <li>Item <em>three</em></li>
</ul>
```

2. In your CSS, you can target the class of `special` by creating a selector that starts with a full stop character. Add the following to your CSS file:

```css
.special {
  color: orange;
  font-weight: bold;
}
```

3. Save and refresh to see what the result is.

You can apply the class of `special` to any element on your page that you want to have the same look as this list item. For example, you might want the `<span>` in the paragraph to also be orange and bold. Try adding a `class` of `special` to it, then reload your page and see what happens.

Sometimes you will see rules with a selector that lists the HTML element selector along with the class:

```css
li.special {
  color: orange;
  font-weight: bold;
}
```

This syntax means "target any `li` element that has a class of special". If you were to do this, then you would no longer be able to apply the class to a `<span>` or another element by adding the class to it; you would have to add that element to the list of selectors:

```css
li.special,
span.special {
  color: orange;
  font-weight: bold;
}
```

As you can imagine, some classes might be applied to many elements and you don't want to have to keep editing your CSS every time something new needs to take on that style. Therefore, it is sometimes best to bypass the element and refer to the class, unless you know that you want to create some special rules for one element alone, and perhaps want to make sure they are not applied to other things.

Styling things based on their location in a document
----------------------------------------------------

There are times when you will want something to look different based on where it is in the document. There are a number of selectors that can help you here, but for now we will look at just a couple. In our document, there are two `<em>` elements — one inside a paragraph and the other inside a list item. To select only an `<em>` that is nested inside an `<li>` element, you can use a selector called the **descendant combinator**, which takes the form of a space between two other selectors.

Add the following rule to your stylesheet:

```css
li em {
  color: rebeccapurple;
}
```

This selector will select any `<em>` element that is inside (a descendant of) an `<li>`. So in your example document, you should find that the `<em>` in the third list item is now purple, but the one inside the paragraph is unchanged.

Something else you might like to try is styling a paragraph when it comes directly after a heading at the same hierarchy level in the HTML. To do so, place a `+` (an **next-sibling combinator**) between the selectors.

Try adding this rule to your stylesheet as well:

```css
h1 + p {
  font-size: 200%;
}
```

The live example below includes the two rules above. Try adding a rule to make a span red if it is inside a paragraph. You will know if you have it right because the span in the first paragraph will be red, but the one in the first list item will not change color.

**Note:** As you can see, CSS gives us several ways to target elements, and we've only scratched the surface so far! We will be taking a proper look at all of these selectors and many more in our Selectors articles later on in the course.

Styling things based on state
-----------------------------

The final type of styling we shall take a look at in this tutorial is the ability to style things based on their state. A straightforward example of this is when styling links. When we style a link, we need to target the `<a>` (anchor) element. This has different states depending on whether it is unvisited, visited, being hovered over, focused via the keyboard, or in the process of being clicked (activated). You can use CSS to target these different states — the CSS below styles unvisited links pink and visited links green.

```css
a:link {
  color: pink;
}

a:visited {
  color: green;
}
```

You can change the way the link looks when the user hovers over it, for example by removing the underline, which is achieved by the next rule:

```css
a:hover {
  text-decoration: none;
}
```

In the live example below, you can play with different values for the various states of a link. We have added the rules above to it, and now realize that the pink color is quite light and hard to read — why not change that to a better color? Can you make the links bold?

We have removed the underline on our link on hover. You could remove the underline from all states of a link. It is worth remembering however that in a real site, you want to ensure that visitors know that a link is a link. Leaving the underline in place can be an important clue for people to realize that some text inside a paragraph can be clicked on — this is the behavior they are used to. As with everything in CSS, there is the potential to make the document less accessible with your changes — we will aim to highlight potential pitfalls in appropriate places.

**Note:** you will often see mention of accessibility in these lessons and across MDN. When we talk about accessibility we are referring to the requirement for our webpages to be understandable and usable by everyone.

Your visitor may well be on a computer with a mouse or trackpad, or a phone with a touchscreen. Or they might be using a screen reader, which reads out the content of the document, or they may need to use much larger text, or be navigating the site using the keyboard only.

A plain HTML document is generally accessible to everyone — as you start to style that document it is important that you don't make it less accessible.

Combining selectors and combinators
-----------------------------------

It is worth noting that you can combine multiple selectors and combinators together. For example:

```css
/\* selects any <span> that is inside a <p>, which is inside an <article> \*/
article p span {
}

/\* selects any <p> that comes directly after a <ul>, which comes directly after an <h1> \*/
h1 + ul + p {
}
```

You can combine multiple types together, too. Try adding the following into your code:

```css
body h1 + p .special {
  color: yellow;
  background-color: black;
  padding: 5px;
}
```

This will style any element with a class of `special`, which is inside a `<p>`, which comes just after an `<h1>`, which is inside a `<body>`. Phew!

In the original HTML we provided, the only element styled is `<span class="special">`.

Don't worry if this seems complicated at the moment — you'll soon start to get the hang of it as you write more CSS.

Summary
-------

In this article, we have taken a look at a number of ways in which you can style a document using CSS. We will be developing this knowledge as we move through the rest of the lessons. However, you now already know enough to style text, apply CSS based on different ways of targeting elements in the document, and look up properties and values in the MDN documentation.

In the next lesson, we'll be taking a look at how CSS is structured.

* Previous
* Overview: First steps
* Next


How CSS works - Learn web development

How CSS works
=============

* Previous
* Overview: First steps
* Next

We have learned the basics of CSS, what it is for and how to write simple stylesheets. In this lesson we will take a look at how a browser takes CSS and HTML and turns that into a webpage.

|  |  |
| --- | --- |
| Prerequisites: | Basic software installed, basic knowledge of
 working with files, and HTML basics (study
 Introduction to HTML.)
  |
| Objective: |
 To understand the basics of how CSS and HTML are parsed by the browser,
 and what happens when a browser encounters CSS it does not understand.
  |

How does CSS actually work?
---------------------------

When a browser displays a document, it must combine the document's content with its style information. It processes the document in a number of stages, which we've listed below. Bear in mind that this is a very simplified version of what happens when a browser loads a webpage, and that different browsers will handle the process in different ways. But this is roughly what happens.

1. The browser loads the HTML (e.g. receives it from the network).
2. It converts the HTML into a DOM (*Document Object Model*). The DOM represents the document in the computer's memory. The DOM is explained in a bit more detail in the next section.
3. The browser then fetches most of the resources that are linked to by the HTML document, such as embedded images, videos, and even linked CSS! JavaScript is handled a bit later on in the process, and we won't talk about it here to keep things simpler.
4. The browser parses the fetched CSS, and sorts the different rules by their selector types into different "buckets", e.g. element, class, ID, and so on. Based on the selectors it finds, it works out which rules should be applied to which nodes in the DOM, and attaches style to them as required (this intermediate step is called a render tree).
5. The render tree is laid out in the structure it should appear in after the rules have been applied to it.
6. The visual display of the page is shown on the screen (this stage is called painting).

The following diagram also offers a simple view of the process.

![Rendering process overview](/en-US/docs/Learn/CSS/First_steps/How_CSS_works/rendering.svg)

About the DOM
-------------

A DOM has a tree-like structure. Each element, attribute, and piece of text in the markup language becomes a DOM node in the tree structure. The nodes are defined by their relationship to other DOM nodes. Some elements are parents of child nodes, and child nodes have siblings.

Understanding the DOM helps you design, debug and maintain your CSS because the DOM is where your CSS and the document's content meet up. When you start working with browser DevTools you will be navigating the DOM as you select items in order to see which rules apply.

A real DOM representation
-------------------------

Rather than a long, boring explanation, let's look at an example to see how a real HTML snippet is converted into a DOM.

Take the following HTML code:

```html
<p>
  Let's use:
  <span>Cascading</span>
  <span>Style</span>
  <span>Sheets</span>
</p>
```

In the DOM, the node corresponding to our `<p>` element is a parent. Its children are a text node and the three nodes corresponding to our `<span>` elements. The `SPAN` nodes are also parents, with text nodes as their children:
```

P
├─ "Let's use:"
├─ SPAN
|  └─ "Cascading"
├─ SPAN
|  └─ "Style"
└─ SPAN
    └─ "Sheets"
```

This is how a browser interprets the previous HTML snippet — it renders the above DOM tree and then outputs it in the browser like so:
```

p {
  margin: 0;
}
```

Applying CSS to the DOM
-----------------------

Let's say we add some CSS to our document, to style it. Again, the HTML is as follows:

```html
<p>
  Let's use:
  <span>Cascading</span>
  <span>Style</span>
  <span>Sheets</span>
</p>
```

Let's suppose we apply the following CSS to it:

```css
span {
  border: 1px solid black;
  background-color: lime;
}
```

The browser parses the HTML and creates a DOM from it. Next, it parses the CSS. Since the only rule available in the CSS has a `span` selector, the browser sorts the CSS very quickly! It applies that rule to each one of the three `<span>`s, then paints the final visual representation to the screen.

The updated output is as follows:

In our Debugging CSS article in the next module we will be using browser DevTools to debug CSS problems, and will learn more about how the browser interprets CSS.

What happens if a browser encounters CSS it doesn't understand?
---------------------------------------------------------------

The "Browser support information" section in the "What is CSS" article mentioned that browsers do not necessarily implement new CSS features at the same time. In addition, many people are not using the latest version of a browser. Given that CSS is being developed all the time, and is therefore ahead of what browsers can recognize, you might wonder what happens if a browser encounters a CSS selector or declaration it doesn't recognize.

The answer is that it does nothing, and just moves on to the next bit of CSS!

If a browser is parsing your rules, and encounters a property or value that it doesn't understand, it ignores it and moves on to the next declaration. It will do this if you have made an error and misspelled a property or value, or if the property or value is just too new and the browser doesn't yet support it.

Similarly, if a browser encounters a selector that it doesn't understand, it will just ignore the whole rule and move on to the next one.

In the example below I have used the British English spelling for color, which makes that property invalid as it is not recognized. So my paragraph has not been colored blue. All of the other CSS have been applied however; only the invalid line is ignored.

```html
<p>I want this text to be large, bold and blue.</p>
```

```css
p {
  font-weight: bold;
  colour: blue; /\* incorrect spelling of the color property \*/
  font-size: 200%;
}
```

This behavior is very useful. It means that you can use new CSS as an enhancement, knowing that no error will occur if it is not understood — the browser will either get the new feature or not. This enables basic fallback styling.

This works particularly well when you want to use a value that is quite new and not supported everywhere. For example, some older browsers do not support `calc()` as a value. I might give a fallback width for a box in pixels, then go on to give a width with a `calc()` value of `100% - 50px`. Old browsers will use the pixel version, ignoring the line about `calc()` as they don't understand it. New browsers will interpret the line using pixels, but then override it with the line using `calc()` as that line appears later in the cascade.

```css
.box {
  width: 500px;
  width: calc(100% - 50px);
}
```

We will look at many more ways to support various browsers in later lessons.

Summary
-------

You've nearly finished this module — we only have one more thing to do. In the Styling a biography page assessment you'll use your new knowledge to restyle an example, testing out some CSS in the process.

* Previous
* Overview: First steps
* Next


Styling a biography page - Learn web development

Styling a biography page
========================

* Previous
* Overview: First steps

With the things you have learned in the last few lessons you should find that you can format simple text documents using CSS to add your own style to them. This assessment gives you a chance to do that.

|  |  |
| --- | --- |
| Prerequisites: |
 Before attempting this assessment you should have already worked through
 all the articles in this module, and also have an understanding of HTML
 basics (study
 Introduction to HTML).
  |
| Objective: | To have a play with some CSS and test your new-found knowledge. |

Starting point
--------------

You can work in the live editor below, or you can download the starting point file to work with in your own editor. This is a single page containing both the HTML and the starting point CSS (in the head of the document). If you prefer you could move this CSS to a separate file and link to it when you create the example on your local computer.

**Note:** You can try solutions in the interactive editors on this page or in an online editor such as CodePen, JSFiddle, or Glitch.

If you get stuck, you can reach out to us in one of our communication channels.

Project brief
-------------

The following live example shows a biography, which has been styled using CSS. The CSS properties that are used are as follows — each one links to its property page on MDN, which will give you more examples of its use.

* `font-family`
* `color`
* `border-bottom`
* `font-weight`
* `font-size`
* `font-style`
* `text-decoration`

In the interactive editor you will find some CSS already in place. This selects parts of the document using element selectors, classes, and pseudo-classes. Make the following changes to this CSS:

1. Make the level one heading pink, using the CSS color keyword `hotpink`.
2. Give the heading a 10px dotted `border-bottom` which uses the CSS color keyword `purple`.
3. Make the level 2 heading italic.
4. Give the `ul` used for the contact details a `background-color` of `#eeeeee`, and a 5px solid purple `border`. Use some `padding` to push the content away from the border.
5. Make the links `green` on hover.
Hints and tips
--------------

* Use the W3C CSS Validator to catch unintended mistakes in your CSS — mistakes you might have otherwise missed — so that you can fix them.
* Afterwards try looking up some properties not mentioned on this page in the MDN CSS reference and get adventurous!
* Remember that there is no wrong answer here — at this stage in your learning you can afford to have a bit of fun.
Example
-------

You should end up with something like this image.

![Screenshot of how the example should look after completing the assessment.](/en-US/docs/Learn/CSS/First_steps/Styling_a_biography_page/learn-css-basics-assessment.png)

* Previous
* Overview: First steps