Cascade, specificity, and inheritance - Learn web development

Cascade, specificity, and inheritance
=====================================

* Previous
* Overview: Building blocks
* Next

The aim of this lesson is to develop your understanding of some of the most fundamental concepts of CSS — the cascade, specificity, and inheritance — which control how CSS is applied to HTML and how conflicts between style declarations are resolved.

While working through this lesson may seem less relevant immediately and a little more academic than some other parts of the course, an understanding of these concepts will save you from a lot of pain later on! We encourage you to work through this section carefully and check that you understand the concepts before moving on.

|  |  |
| --- | --- |
| 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 cascade and specificity, and how inheritance works in
 CSS.
  |

Conflicting rules
-----------------

CSS stands for **Cascading Style Sheets**, and that first word *cascading* is incredibly important to understand — the way that the cascade behaves is key to understanding CSS.

At some point, you will be working on a project and you will find that the CSS you thought should be applied to an element is not working. Often, the problem is that you create two rules that apply different values of the same property to the same element. **Cascade** and the closely-related concept of **specificity** are mechanisms that control which rule applies when there is such a conflict. The rule that's styling your element may not be the one you expect, so you need to understand how these mechanisms work.

Also significant here is the concept of **inheritance**, which means that some CSS properties by default inherit values set on the current element's parent element and some don't. This can also cause some behavior that you might not expect.

Let's start by taking a quick look at the key things we are dealing with, then we'll look at each in turn and see how they interact with each other and your CSS. These can seem like a tricky set of concepts to understand. As you get more practice writing CSS, the way it works will become more obvious to you.

### Cascade

Stylesheets **cascade** — at a very simple level, this means that the origin, the cascade layer, and the order of CSS rules matter. When two rules from the same cascade layer apply and both have equal specificity, the one that is defined last in the stylesheet is the one that will be used.

In the below example, we have two rules that could apply to the `<h1>` element. The `<h1>` content ends up being colored blue. This is because both the rules are from the same source, have an identical element selector, and therefore, carry the same specificity, but the last one in the source order wins.

### Specificity

Specificity is the algorithm that the browser uses to decide which property value is applied to an element. If multiple style blocks have different selectors that configure the same property with different values and target the same element, specificity decides the property value that gets applied to the element. Specificity is basically a measure of how specific a selector's selection will be:

* An element selector is less specific; it will select all elements of that type that appear on a page, so it has less weight. Pseudo-element selectors have the same specificity as regular element selectors.
* A class selector is more specific; it will select only the elements on a page that have a specific `class` attribute value, so it has more weight. Attribute selectors and pseudo-classes have the same weight as a class.

Below, we again have two rules that could apply to the `<h1>` element. The `<h1>` content below ends up being colored red because the class selector `main-heading` gives its rule a higher specificity. So even though the rule with the `<h1>` element selector appears further down in the source order, the one with the higher specificity, defined using the class selector, will be applied.

We'll explain the specificity algorithm later on.

### Inheritance

Inheritance also needs to be understood in this context — some CSS property values set on parent elements are inherited by their child elements, and some aren't.

For example, if you set a `color` and `font-family` on an element, every element inside it will also be styled with that color and font, unless you've applied different color and font values directly to them.

Some properties do not inherit — for example, if you set a `width` of 50% on an element, all of its descendants do not get a width of 50% of their parent's width. If this was the case, CSS would be very frustrating to use!

**Note:** On MDN CSS property reference pages, you can find a technical information box called "Formal definition", which lists a number of data points about that property, including whether it is inherited or not. See the color property Formal definition section as an example.

Understanding how the concepts work together
--------------------------------------------

These three concepts (cascade, specificity, and inheritance) together control which CSS applies to what element. In the sections below, we'll see how they work together. It can sometimes seem a little bit complicated, but you will start to remember them as you get more experienced with CSS, and you can always look up the details if you forget! Even experienced developers don't remember all the details.

The following video shows how you can use the Firefox DevTools to inspect a page's cascade, specificity, and more:

Understanding inheritance
-------------------------

We'll start with inheritance. In the example below, we have a `<ul>` element with two levels of unordered lists nested inside it. We have given the outer `<ul>` a border, padding, and font color.

The `color` property is an inherited property. So, the `color` property value is applied to the direct children and also to the indirect children — the immediate child `<li>`s and those inside the first nested list. We have then added the class `special` to the second nested list and applied a different color to it. This then inherits down through its children.

Properties like `width` (as mentioned earlier), `margin`, `padding`, and `border` are not inherited properties. If a border were to be inherited by the children in this list example, every single list and list item would gain a border — probably not an effect we would ever want!

Though every CSS property page lists whether or not the property is inherited, you can often guess the same intuitively if you know what aspect the property value will style.

### Controlling inheritance

CSS provides five special universal property values for controlling inheritance. Every CSS property accepts these values.

`inherit`

Sets the property value applied to a selected element to be the same as that of its parent element. Effectively, this "turns on inheritance".

`initial`

Sets the property value applied to a selected element to the initial value of that property.

`revert`

Resets the property value applied to a selected element to the browser's default styling rather than the defaults applied to that property. This value acts like `unset` in many cases.

`revert-layer`

Resets the property value applied to a selected element to the value established in a previous cascade layer.

`unset`

Resets the property to its natural value, which means that if the property is naturally inherited it acts like `inherit`, otherwise it acts like `initial`.

**Note:** See Origin types for more information on each of these and how they work.

We can look at a list of links and explore how universal values work. The live example below allows you to play with the CSS and see what happens when you make changes. Playing with code really is the best way to better understand HTML and CSS.

For example:

1. The second list item has the class `my-class-1` applied. This sets the color of the `<a>` element nested inside to `inherit`. If you remove the rule, how does it change the color of the link?
2. Do you understand why the third and fourth links are the color that they are? The third link is set to `initial`, which means it uses the initial value of the property (in this case black) and not the browser default for links, which is blue. The fourth is set to `unset` which means that the link text uses the color of the parent element, green.
3. Which of the links will change color if you define a new color for the `<a>` element — for example `a { color: red; }`?
4. After reading the next section on resetting all properties, come back and change the `color` property to `all`. Notice how the second link is on a new line and has a bullet. What properties do you think were inherited?

### Resetting all property values

The CSS shorthand property `all` can be used to apply one of these inheritance values to (almost) all properties at once. Its value can be any one of the inheritance values (`inherit`, `initial`, `revert`, `revert-layer`, or `unset`). It's a convenient way to undo changes made to styles so that you can get back to a known starting point before beginning new changes.

In the below example, we have two blockquotes. The first has styling applied to the blockquote element itself. The second has a class applied to the blockquote, which sets the value of `all` to `unset`.

Try setting the value of `all` to some of the other available values and observe what the difference is.

Understanding the cascade
-------------------------

We now understand that inheritance is why a paragraph nested deep in the structure of your HTML is the same color as the CSS applied to the body. From the introductory lessons, we have an understanding of how to change the CSS applied to something at any point in the document — whether by assigning CSS to an element or by creating a class. We will now look at how cascade defines which CSS rules apply when more than one style block apply the same property, but with different values, to the same element.

There are three factors to consider, listed here in increasing order of importance. Later ones overrule earlier ones:

1. **Source order**
2. **Specificity**
3. **Importance**

We will look at these to see how browsers figure out exactly what CSS should be applied.

### Source order

We have already seen how source order matters to the cascade. If you have more than one rule, all of which have exactly the same weight, then the one that comes last in the CSS will win. You can think of this as: the rule that is nearer the element itself overwrites the earlier ones until the last one wins and gets to style the element.

Source order only matters when the specificity weight of the rules is the same, so let's look at specificity:

### Specificity

You will often run into a situation where you know that a rule comes later in the stylesheet, but an earlier, conflicting rule is applied. This happens because the earlier rule has a **higher specificity** — it is more specific, and therefore, is being chosen by the browser as the one that should style the element.

As we saw earlier in this lesson, a class selector has more weight than an element selector, so the properties defined in the class style block will override those defined in the element style block.

Something to note here is that although we are thinking about selectors and the rules that are applied to the text or component they select, it isn't the entire rule that is overwritten, only the properties that are declared in multiple places.

This behavior helps avoid repetition in your CSS. A common practice is to define generic styles for the basic elements, and then create classes for those that are different. For example, in the stylesheet below, we have defined generic styles for level 2 headings, and then created some classes that change only some of the properties and values. The values defined initially are applied to all headings, then the more specific values are applied to the headings with the classes.

Let's now have a look at how the browser will calculate specificity. We already know that an element selector has low specificity and can be overwritten by a class. Essentially a value in points is awarded to different types of selectors, and adding these up gives you the weight of that particular selector, which can then be assessed against other potential matches.

The amount of specificity a selector has is measured using three different values (or components), which can be thought of as ID, CLASS, and ELEMENT columns in the hundreds, tens, and ones place:

* **Identifiers**: Score one in this column for each ID selector contained inside the overall selector.
* **Classes**: Score one in this column for each class selector, attribute selector, or pseudo-class contained inside the overall selector.
* **Elements**: Score one in this column for each element selector or pseudo-element contained inside the overall selector.

**Note:** The universal selector (`*`), combinators (`+`, `>`, `~`, ' '), and specificity adjustment selector (`:where()`) along with its parameters, have no effect on specificity.

The negation (`:not()`), relational selector (`:has()`), the matches-any (`:is()`) pseudo-classes, and CSS nesting themselves don't add to specificity, but their parameters or nested rules do. The specificity weight that each contributes to the specificity algorithm is the specificity weight of the selector in the parameter or nested rule with the greatest weight.

The following table shows a few isolated examples to get you in the mood. Try going through these, and make sure you understand why they have the specificity that we have given them. We've not covered selectors in detail yet, but you can find details of each selector on the MDN selectors reference.

| Selector | Identifiers | Classes | Elements | Total specificity |
| --- | --- | --- | --- | --- |
| `h1` | 0 | 0 | 1 | 0-0-1 |
| `h1 + p::first-letter` | 0 | 0 | 3 | 0-0-3 |
| `li > a[href*="en-US"] > .inline-warning` | 0 | 2 | 2 | 0-2-2 |
| `#identifier` | 1 | 0 | 0 | 1-0-0 |
| `button:not(#mainBtn, .cta`) | 1 | 0 | 1 | 1-0-1 |

Before we move on, let's look at an example in action.

So what's going on here? First of all, we are only interested in the first seven rules of this example, and as you'll notice, we have included their specificity values in a comment before each one.

* The first two selectors are competing over the styling of the link's background color. The second one wins and makes the background color blue because it has an extra ID selector in the chain: its specificity is 2-0-1 vs. 1-0-1.
* Selectors 3 and 4 are competing over the styling of the link's text color. The second one wins and makes the text white because although it has one less element selector, the missing selector is swapped out for a class selector, which has more weight than infinity element selectors. The winning specificity is 1-1-3 vs. 1-0-4.
* Selectors 5–7 are competing over the styling of the link's border when hovered. Selector 6 clearly loses to selector 5 with a specificity of 0-2-3 vs. 0-2-4; it has one fewer element selectors in the chain. Selector 7, however, beats both selectors 5 and 6 because it has the same number of sub-selectors in the chain as selector 5, but an element has been swapped out for a class selector. So the winning specificity is 0-3-3 vs. 0-2-3 and 0-2-4.

**Note:** Each selector type has its own level of specificity that cannot be overwritten by selectors with a lower specificity level. For example, a *million* **class** selectors combined would not be able to overwrite the specificity of *one* **id** selector.

The best way to evaluate specificity is to score the specificity levels individually starting from the highest and moving on to the lowest when necessary. Only when there is a tie between selector scores within a specificity column do you need to evaluate the next column down; otherwise, you can disregard the lower specificity selectors since they can never overwrite the higher specificity selectors.

### Inline styles

Inline styles, that is, the style declaration inside a `style` attribute, take precedence over all normal styles, no matter the specificity. Such declarations don't have selectors, but their specificity can be construed as 1-0-0-0; always more than any other specificity weight no matter how many IDs are in the selectors.

### !important

There is a special piece of CSS that you can use to overrule all of the above calculations, even inline styles - the `!important` flag. However, you should be very careful while using it. This flag is used to make an individual property and value pair the most specific rule, thereby overriding the normal rules of the cascade, including normal inline styles.

**Note:** It is useful to know that the `!important` flag exists so that you know what it is when you come across it in other people's code. **However, we strongly recommend that you never use it unless you absolutely have to.** The `!important` flag changes the way the cascade normally works, so it can make debugging CSS problems really hard to work out, especially in a large stylesheet.

Take a look at this example where we have two paragraphs, one of which has an ID.

Let's walk through this to see what's happening — try removing some of the properties to see what happens if you are finding it hard to understand:

1. You'll see that the third rule's `color` and `padding` values have been applied, but the `background-color` hasn't. Why? Really, all three should surely apply because rules later in the source order generally override earlier rules.
2. However, the rules above it win because class selectors have higher specificity than element selectors.
3. Both elements have a `class` of `better`, but the 2nd one has an `id` of `winning` too. Since IDs have an *even higher* specificity than classes (you can only have one element with each unique ID on a page, but many elements with the same class — ID selectors are *very specific* in what they target), the red background color and the 1px black border should both be applied to the 2nd element, with the first element getting the gray background color, and no border, as specified by the class.
4. The 2nd element *does* get the red background color, but no border. Why? Because of the `!important` flag in the second rule. Adding the `!important` flag after `border: none` means that this declaration will win over the `border` value in the previous rule, even though the ID selector has higher specificity.

**Note:** The only way to override an important declaration is to include another important declaration with the *same specificity* later in the source order, or one with higher specificity, or to include an important declaration in a prior cascade layer (we haven't covered cascade layers yet).

One situation in which you may have to use the `!important` flag is when you are working on a CMS where you can't edit the core CSS modules, and you really want to override an inline style or an important declaration that can't be overridden in any other way. But really, don't use it if you can avoid it.

The effect of CSS location
--------------------------

Finally, it is important to note that the precedence of a CSS declaration depends on what stylesheet and cascade layer it is specified in.

It is possible for users to set custom stylesheets to override the developer's styles. For example, a visually impaired user might want to set the font size on all web pages they visit to be double the normal size to allow for easier reading.

It is also possible to declare developer styles in cascade layers: you can make non-layered styles override styles declared in layers or you can make styles declared in later layers override styles from earlier declared layers. For example, as a developer you may not be able to edit a third-party stylesheet, but you can import the external stylesheet into a cascade layer so that all of your styles easily override the imported styles without worrying about third-party selector specificity.

### Order of overriding declarations

Conflicting declarations will be applied in the following order, with later ones overriding earlier ones:

1. Declarations in user agent style sheets (e.g., the browser's default styles, used when no other styling is set).
2. Normal declarations in user style sheets (custom styles set by a user).
3. Normal declarations in author style sheets (these are the styles set by us, the web developers).
4. Important declarations in author style sheets.
5. Important declarations in user style sheets.
6. Important declarations in user agent style sheets.

**Note:** The order of precedence is inverted for styles flagged with `!important`. It makes sense for web developers' stylesheets to override user stylesheets, so the design can be kept as intended; however, sometimes users have good reasons to override web developer styles, as mentioned above, and this can be achieved by using `!important` in their rules.

### Order of cascade layers

Even though cascade layers is an advanced topic and you might not use this feature right away, it's important to understand how layers cascade.

When you declare CSS in cascade layers, the order of precedence is determined by the order in which the layers are declared. CSS styles declared outside of any layer are combined together, in the order in which those styles are declared, into an unnamed layer, as if it were the last declared layer. With competing normal (not important) styles, later layers take precedence over earlier defined layers. For styles flagged with `!important`, however, the order is reversed, with important styles in earlier layers taking precedence over important styles declared in subsequent layers or outside of any layer. Inline styles take precedence over all author styles, no matter the layer.

When you have multiple style blocks in different layers providing competing values for a property on a single element, the order in which the layers are declared determines the precedence. Specificity between layers doesn't matter, but specificity within a single layer still does.

Let's discuss a few things from the above example to understand what's happening. Two layers have been declared, `firstLayer` and `secondLayer`, in that order. Even though the specificity in `secondLayer` is the highest, no properties from that declaration are used. Why? Because non-layered normal styles take precedence over layered normal styles, no matter the specificity, and important layered styles take precedence over important styles declared in later layers, again, no matter the specificity.

If you change the first line of CSS in this example to read `@layer secondLayer, firstLayer;`, you will change the layer declaration order, and all the important styles from `firstLayer` will be changed to their respective values in `secondLayer`.

### Scoping proximity

Another advanced topic that you might not use right away but may need to understand in the future is `@scope`. This is an at-rule that enables you to create a block of rules that will only apply to a specific subsection of the HTML on your page. For example, you can specify styles that will only apply to `<img>` elements when they're nested inside elements that have a `feature` class:

```css
@scope (.feature) {
  img {
    border: 2px solid black;
    display: block;
  }
}
```

**Scoping proximity** is the mechanism that resolves conflicts between scoped elements. Scoping proximity states that when two scopes have conflicting styles, the style with the smallest number of hops up the DOM tree hierarchy to the scope root wins. See How `@scope` conflicts are resolved for more details and an example.

**Note:** Scoping proximity overrules source order but is itself overridden by other, higher-priority criteria such as importance, layers, and specificity.

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.

Summary
-------

If you understood most of this article, then well done — you've started getting familiar with the fundamental mechanics of CSS. Next up, we'll take a deeper look at Cascade Layers.

If you didn't fully understand the cascade, specificity, and inheritance, then don't worry! This is definitely the most complicated thing we've covered so far in the course and is something that even professional web developers sometimes find tricky. We'd advise that you return to this article a few times as you continue through the course, and keep thinking about it.

Refer back here if you start to come across strange issues with styles not applying as expected. It could be a specificity issue.

* Previous
* Overview: Building blocks
* Next


Test your skills: Images and form elements - Learn web development

Test your skills: Images and form elements
==========================================

The aim of this skill test is to assess whether you understand how special elements like images, media and form elements are treated in CSS.

**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, you have an image that is overflowing the box. We want the image to scale down to fit inside the box without any extra white space, but we do not mind if some part of the image is cropped.

Your final result should look like the image below:

![An image in a box](/en-US/docs/Learn/CSS/Building_blocks/Images_tasks/mdn-images-object-fit.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.

Task 2
------

In this task, you have a simple form. Your task is to make the following changes:

* Use attribute selectors to target the search field and button inside `.myform`.
* Make the form field and button use the same text size as the rest of the form.
* Give the form field and button 10 px of padding.
* Give the button a background of `rebeccapurple`, white foreground, no border and rounded corners of 5px.

Your final result should look like the image below:

![A single line form](/en-US/docs/Learn/CSS/Building_blocks/Images_tasks/mdn-images-form.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.


Overflowing content - Learn web development

Overflowing content
===================

* Previous
* Overview: Building blocks
* Next

Overflow is what happens when there is too much content to fit in an element box. In this guide, you will learn what overflow is and how to manage it.

|  |  |
| --- | --- |
| 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 overflow and how to manage it. |

What is overflow?
-----------------

Everything in CSS is a box. You can constrain the size of these boxes by assigning values of `width` and `height` (or `inline-size` and `block-size`). **Overflow happens when there is too much content to fit in a box.** CSS provides various tools to manage overflow. As you go further with CSS layout and writing CSS, you will encounter more overflow situations.

CSS tries to avoid "data loss"
------------------------------

Let's consider two examples that demonstrate the default behavior of CSS when there is overflow.

The first example is a box that has been restricted by setting a `height`. Then we add content that exceeds the allocated space. The content overflows the box and falls into the paragraph below.

The second example is a word in a box. The box has been made too small for the word and so it breaks out of the box.

You might wonder why CSS works in such a messy way, displaying content outside of its intended container. Why not hide overflowing content? Why not scale the size of the container to fit all the content?

Wherever possible, CSS does not hide content. This would cause data loss. The problem with data loss is that you might not notice. Website visitors may not notice. If the submit button on a form disappears and no one can complete the form, this could be a big problem! Instead, CSS overflows in visible ways. You are more likely to see there is a problem. At worst, a site visitor will let you know that content is overlapping.

If you restrict a box with a `width` or a `height`, CSS trusts you to know what you are doing. CSS assumes that you are managing the potential for overflow. In general, restricting the block dimension is problematic when the box contains text. There may be more text than you expected when designing the site, or the text may be larger (for example, if the user has increased their font size).

The next two lessons explain different approaches to control sizing in ways that are less prone to overflow. However, if you need a fixed size, you can also control how the overflow behaves. Let's read on!

The overflow property
---------------------

The `overflow` property helps you manage an element's content overflow. Using this property, you can convey to a browser how it should handle overflow content. The default value of the `<overflow>` value type is `visible`. With this default setting, one can see content when it overflows.

To crop content when it overflows, you can set `overflow: hidden`. This does exactly what it says: it hides overflow. Beware that this can make some content invisible. You should only do this if hiding content won't cause problems.

Instead, perhaps you would like to add scrollbars when content overflows? Using `overflow: scroll`, browsers with visible scrollbars will always display them—even if there is not enough content to overflow. This offers the advantage of keeping the layout consistent, instead of scrollbars appearing or disappearing, depending upon the amount of content in the container.

**Remove some content from the box below. Notice how the scrollbars remain, even if there is no need for scrolling.**

In the example above, we only need to scroll on the `y` axis, however we get scrollbars in both axes. To just scroll on the `y` axis, you could use the `overflow-y` property, setting `overflow-y: scroll`.

You can also enable scrolling along the x-axis by using `overflow-x`, although this is not a recommended way to accommodate long words! If you have a long word in a small box, consider using the `word-break` or `overflow-wrap` property. In addition, some of the methods discussed in Sizing items in CSS may help you create boxes that scale better with varying amounts of content.

As with `scroll`, you get a scrollbar in the scrolling dimension whether or not there is enough content to cause a scrollbar.

**Note:** You can specify x- and y-axis scrolling using the `overflow` property, passing two values. If two keywords are specified, the first applies to `overflow-x` and the second applies to `overflow-y`. Otherwise, both `overflow-x` and `overflow-y` are set to the same value. For example, `overflow: scroll hidden` would set `overflow-x` to `scroll` and `overflow-y` to `hidden`.

If you only want scrollbars to appear when there is more content than can fit in the box, use `overflow: auto`. This allows the browser to determine if it should display scrollbars.

**In the example below, remove content until it fits into the box. You should see the scrollbars disappear.**

Overflow establishes a Block Formatting Context
-----------------------------------------------

When you use the `<overflow>` values `scroll` and `auto`, you create a **Block Formatting Context** (BFC). This means that the content of an element box with these `overflow` values acquires a self-contained layout. Content outside such an element box cannot poke into the element box, and nothing from the element box can poke into the surrounding layout. This enables scrolling behavior, as all box content needs to be contained and not overlap to create a consistent scrolling experience.

Unwanted overflow in web design
-------------------------------

Modern layout methods (described in CSS layout) manage overflow. They largely work without assumptions or dependencies for how much content there will be on a web page.

This was not always the norm. In the past, some sites were built with fixed-height containers to align box bottoms. These boxes may otherwise have had no relationship to each other. This was fragile. If you encounter a box where content is overlaying other content on the page in legacy applications, you will now recognize that this happens with overflow. Ideally, you will refactor the layout to not rely on fixed-height containers.

When developing a site, always keep overflow in mind. Test designs with large and small amounts of content. Increase and decrease font sizes by at least two increments. Ensure your CSS is robust. Changing overflow values to hide content or to add scrollbars is reserved for a few select use cases (for example, where you intend to have a scrolling box).

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: Overflow.

Summary
-------

This lesson introduced the concept of overflow. You should understand that default CSS avoids making overflowing content invisible. You have discovered that you can manage potential overflow, and also, that you should test work to make sure it does not accidentally cause problematic overflow.

In the next article, we'll take a look at the most common values and units in CSS.

* Previous
* Overview: Building blocks
* Next


Styling tables - Learn web development

Styling tables
==============

* Previous
* Overview: Building blocks
* Next

Styling an HTML table isn't the most glamorous job in the world, but sometimes we all have to do it. This article provides a guide to making HTML tables look good, with some specific table styling techniques highlighted.

|  |  |
| --- | --- |
| Prerequisites: |
 HTML basics (study
 Introduction to HTML), knowledge of
 HTML tables, and an idea of
 how CSS works (study CSS first steps.)
  |
| Objective: | To learn how to effectively style HTML tables. |

A typical HTML table
--------------------

Let's start by looking at a typical HTML table. Well, I say typical — most HTML table examples are about shoes, or the weather, or employees; we decided to make things more interesting by making it about famous punk bands from the UK. The markup looks like so:

```html
<table>
  <caption>
    A summary of the UK's most famous punk bands
  </caption>
  <thead>
    <tr>
      <th scope="col">Band</th>
      <th scope="col">Year formed</th>
      <th scope="col">No. of Albums</th>
      <th scope="col">Most famous song</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Buzzcocks</th>
      <td>1976</td>
      <td>9</td>
      <td>Ever fallen in love (with someone you shouldn't've)</td>
    </tr>
    <tr>
      <th scope="row">The Clash</th>
      <td>1976</td>
      <td>6</td>
      <td>London Calling</td>
    </tr>

    <!-- several other great bands -->

    <tr>
      <th scope="row">The Stranglers</th>
      <td>1974</td>
      <td>17</td>
      <td>No More Heroes</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th scope="row" colspan="2">Total albums</th>
      <td colspan="2">77</td>
    </tr>
  </tfoot>
</table>
```

The table is nicely marked up, easily stylable, and accessible, thanks to features such as `scope`, `<caption>`, `<thead>`, `<tbody>`, etc. Unfortunately, it doesn't look good when rendered on the screen (see it live at punk-bands-unstyled.html):

![an unstyled table showing a summary of Uk's famous punk bands](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/table-unstyled.png)

With only the default browser styling it looks cramped, hard to read, and boring. We need to use some CSS to fix this up.

Styling our table
-----------------

Let's work through styling our table example together.

1. To start with, make a local copy of the sample markup, download both images (noise and leopardskin), and put the three resulting files in a working directory somewhere on your local computer.
2. Next, create a new file called `style.css` and save it in the same directory as your other files.
3. Link the CSS to the HTML by placing the following line of HTML inside your `<head>`:

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

### Spacing and layout

The first thing we need to do is sort out the spacing/layout — default table styling is so cramped! To do this, add the following CSS to your `style.css` file:

```css
/\* spacing \*/

table {
  table-layout: fixed;
  width: 100%;
  border-collapse: collapse;
  border: 3px solid purple;
}

thead th:nth-child(1) {
  width: 30%;
}

thead th:nth-child(2) {
  width: 20%;
}

thead th:nth-child(3) {
  width: 15%;
}

thead th:nth-child(4) {
  width: 35%;
}

th,
td {
  padding: 20px;
}
```

The most important parts to note are as follows:

* A `table-layout` value of `fixed` is generally a good idea to set on your table, as it makes the table behave a bit more predictably by default. Normally, table columns tend to be sized according to how much content they contain, which produces some strange results. With `table-layout: fixed`, you can size your columns according to the width of their headings, and then deal with their content as appropriate. This is why we've selected the four different headings with the `thead th:nth-child(n)` (`:nth-child`) selector ("Select the n-th child that is a `<th>` element in a sequence, inside a `<thead>` element") and given them set percentage widths. The entire column width follows the width of its heading, making for a nice way to size your table columns. Chris Coyier discusses this technique in more detail in Fixed Table Layouts.
 We've coupled this with a `width` of 100%, meaning that the table will fill any container it is put in, and be nicely responsive (although it would still need some more work to get it looking good on narrow screen widths).
* A `border-collapse` value of `collapse` is standard best practice for any table styling effort. By default, when you set borders on table elements, they will all have spacing between them, as the below image illustrates:
 ![a 2 by 2 table with default spacing between the borders showing no border collapse](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/no-border-collapse.png) This doesn't look very nice (although it might be the look you want, who knows?). With `border-collapse: collapse;` set, the borders collapse down into one, which looks much better:
 ![a 2 by 2 table with border-collapse property set to collapse showing borders collapse into one](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/border-collapse.png)
* We've put a `border` around the whole table, which is needed because we'll be putting some borders round the table header and footer later on — it looks really odd and disjointed when you don't have a border round the whole outside of the table and end up with gaps.
* We've set some `padding` on the `<th>` and `<td>` elements — this gives the data items some space to breathe, making the table look a lot more legible.

At this point, our table already looks a lot better:

![a semi-styled table with spacing to make the data more legible and showing a summary of Uk's famous punk bands](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/table-with-spacing.png)

### Some simple typography

Now we'll get our text sorted out a bit.

First of all, we've found a font on Google Fonts that is suitable for a table about punk bands. You can go there and find a different one if you like; you'll just have to replace our provided `<link>` element and custom `font-family` declaration with the ones Google Fonts gives you.

First, add the following `<link>` element into your HTML head, just above your existing `<link>` element:

```html
<link
 href="https://fonts.googleapis.com/css?family=Rock+Salt"
 rel="stylesheet"
 type="text/css" />
```

Now add the following CSS into your `style.css` file, below the previous addition:

```css
/\* typography \*/

html {
  font-family: "helvetica neue", helvetica, arial, sans-serif;
}

thead th,
tfoot th {
  font-family: "Rock Salt", cursive;
}

th {
  letter-spacing: 2px;
}

td {
  letter-spacing: 1px;
}

tbody td {
  text-align: center;
}

tfoot th {
  text-align: right;
}
```

There is nothing really specific to tables here; we are generally tweaking the font styling to make things easier to read:

* We have set a global sans-serif font stack; this is purely a stylistic choice. We've also set our custom font on the headings inside the `<thead>` and `<tfoot>` elements, for a nice grungy, punky look.
* We've set some `letter-spacing` on the headings and cells, as we feel it aids readability. Again, mostly a stylistic choice.
* We've center-aligned the text in the table cells inside the `<tbody>` so that they line up with the headings. By default, cells are given a `text-align` value of `left`, and headings are given a value of `center`, but generally it looks better to have the alignments set the same for both. The default bold weight on the heading fonts is enough to differentiate their look.
* We've right-aligned the heading inside the `<tfoot>` so that it is visually associated better with its data point.

The result looks a bit neater:

![a styled table with a global sans-serif font stack and good spacing to make the data more legible and showing a summary of Uk's famous punk bands](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/table-with-typography.png)

### Graphics and colors

Now onto graphics and colors! Because the table is full of punk and attitude, we need to give it some bright imposing styling to suit it. Don't worry, you don't have to make your tables this loud — you can opt for something more subtle and tasteful.

Start by adding the following CSS to your `style.css` file, again at the bottom:

```css
/\* graphics and colors \*/

thead,
tfoot {
  background: url(leopardskin.jpg);
  color: white;
  text-shadow: 1px 1px 1px black;
}

thead th,
tfoot th,
tfoot td {
  background: linear-gradient(to bottom, rgb(0 0 0 / 10%), rgb(0 0 0 / 50%));
  border: 3px solid purple;
}
```

Again, there's nothing specific to tables here, but it is worthwhile to note a few things.

We've added a `background-image` to the `<thead>` and `<tfoot>`, and changed the `color` of all the text inside the header and footer to white (and given it a `text-shadow`) so it is readable. You should always make sure your text contrasts well with your background, so it is readable.

We've also added a linear gradient to the `<th>` and `<td>` elements inside the header and footer for a nice bit of texture, as well as giving those elements a bright purple border. It is useful to have multiple nested elements available so you can layer styles on top of one another. Yes, we could have put both the background image and the linear gradient on the `<thead>` and `<tfoot>` elements using multiple background images, but we decided to do it separately for the benefit of older browsers that don't support multiple background images or linear gradients.

#### Zebra striping

We wanted to dedicate a separate section to showing you how to implement **zebra stripes** — alternating rows of color that make the different data rows in your table easier to parse and read. Add the following CSS to the bottom of your `style.css` file:

```css
/\* zebra striping \*/

tbody tr:nth-child(odd) {
  background-color: #ff33cc;
}

tbody tr:nth-child(even) {
  background-color: #e495e4;
}

tbody tr {
  background-image: url(noise.png);
}

table {
  background-color: #ff33cc;
}
```

* Earlier on you saw the `:nth-child` selector being used to select specific child elements. It can also be given a formula as a parameter, so it will select a sequence of elements. The formula `2n+1` would select all the odd numbered children (1, 3, 5, etc.) and the formula `2n` would select all the even numbered children (2, 4, 6, etc.) We've used the `odd` and `even` keywords in our code, which do exactly the same things as the aforementioned formulae. In this case we are giving the odd and even rows different (lurid) colors.
* We've also added a repeating background tile to all the body rows, which is just a bit of noise (a semi-transparent `.png` with a bit of visual distortion on it) to provide some texture.
* Lastly, we've given the entire table a solid background color so that browsers that don't support the `:nth-child` selector still have a background for their body rows.

This color explosion results in the following look:

![a well styled table with a repeating background in the body rows and the entire table a solid background to make the data showing a summary of Uk's famous punk bands more appealing](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/table-with-color.png)

Now, this may be a bit over the top and not to your taste, but the point we are trying to make here is that tables don't have to be boring and academic.

### Styling the caption

There is one last thing to do with our table — style the caption. To do this, add the following to the bottom of your `style.css` file:

```css
/\* caption \*/

caption {
  font-family: "Rock Salt", cursive;
  padding: 20px;
  font-style: italic;
  caption-side: bottom;
  color: #666;
  text-align: right;
  letter-spacing: 1px;
}
```

There is nothing remarkable here, except for the `caption-side` property, which has been given a value of `bottom`. This causes the caption to be positioned on the bottom of the table, which along with the other declarations gives us this final look (see it live at punk-bands-complete.html):

![a white background below the styled table containing a caption of what the table is about. "a summary of Uk's famous punk bands" in this case](/en-US/docs/Learn/CSS/Building_blocks/Styling_tables/table-with-caption.png)

Table styling quick tips
------------------------

Before moving on, we thought we'd provide you with a quick list of the most useful points illustrated above:

* Make your table markup as simple as possible, and keep things flexible, e.g. by using percentages, so the design is more responsive.
* Use `table-layout``: fixed` to create a more predictable table layout that allows you to easily set column widths by setting `width` on their headings (`<th>`).
* Use `border-collapse``: collapse` to make table elements borders collapse into each other, producing a neater and easier to control look.
* Use `<thead>`, `<tbody>`, and `<tfoot>` to break up your table into logical chunks and provide extra places to apply CSS to, so it is easier to layer styles on top of one another if required.
* Use zebra striping to make alternative rows easier to read.
* Use `text-align` to line up your `<th>` and `<td>` text, to make things neater and easier to follow.
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: Tables.

Summary
-------

With styling tables now behind us, we need something else to occupy our time. The next article explores debugging CSS — how to solve problems such as layouts not looking like they should, or properties not applying when you think they should. This includes information on using browser DevTools to find solutions to your problems.

* Previous
* Overview: Building blocks
* Next


Test your skills: Sizing - Learn web development

Test your skills: Sizing
========================

The aim of this skill test is to assess whether you understand the different ways of sizing items in CSS.

**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, you have two boxes. The first should be sized so that the height will be at least 100 pixels tall, even if there is less content that would cause it to grow to that height. However, the content should not overflow if there is more content than fits in 100 pixels. Test this box by removing the content from the HTML to make sure you still get a 100 pixel tall box even with no content.

The second box should be fixed at 100 pixels tall, so that content will overflow if there is too much.

![Two boxes one with overflowing content](/en-US/docs/Learn/CSS/Building_blocks/Sizing_tasks/mdn-sizing-height-min-height.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.

Task 2
------

In this task, you have a box, which contains another box. Your task is to make the inner box 60% of the width of the outer box. The value of the `box-sizing` property is set to `border-box`, which means that the total width includes any padding and border. You should also give the inner box padding of 10% using the width (or inline size) as the size from which that percentage is calculated.

Your final result should look like the image below:

![A box with another box nested inside](/en-US/docs/Learn/CSS/Building_blocks/Sizing_tasks/mdn-sizing-percentages.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.

Task 3
------

In this task, you have two images in boxes. One image is smaller than the box, the other is larger and breaking out of the box. If you imagine that the box is responsive and therefore could grow and shrink, which property would you apply to the image so that the large image shrinks down into the box but the small image does not stretch.

Your final result should look like the images below:

![Two boxes with images in](/en-US/docs/Learn/CSS/Building_blocks/Sizing_tasks/mdn-sizing-max-width.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.


Handling different text directions - Learn web development

Handling different text directions
==================================

* Previous
* Overview: Building blocks
* Next

Many of the properties and values that we have encountered so far in our CSS learning have been tied to the physical dimensions of our screen. We create borders on the top, right, bottom, and left of a box, for example. These physical dimensions map very neatly to content that is viewed horizontally, and by default the web tends to support left-to-right languages (e.g. English or French) better than right-to-left languages (such as Arabic).

In recent years however, CSS has evolved in order to better support different directionality of content, including right-to-left but also top-to-bottom content (such as Japanese) — these different directionalities are called **writing modes**. As you progress in your study and begin to work with layout, an understanding of writing modes will be very helpful to you, therefore we will introduce them now.

|  |  |
| --- | --- |
| 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 importance of writing modes to modern CSS. |

What are writing modes?
-----------------------

A writing mode in CSS refers to whether the text is running horizontally or vertically. The `writing-mode` property lets us switch from one writing mode to another. You don't need to be working in a language which uses a vertical writing mode to want to do this — you could also change the writing mode of parts of your layout for creative purposes.

In the example below we have a heading displayed using `writing-mode: vertical-rl`. The text now runs vertically. Vertical text is common in graphic design, and can be a way to add a more interesting look and feel to your web design.

The three possible values for the `writing-mode` property are:

* `horizontal-tb`: Top-to-bottom block flow direction. Sentences run horizontally.
* `vertical-rl`: Right-to-left block flow direction. Sentences run vertically.
* `vertical-lr`: Left-to-right block flow direction. Sentences run vertically.

So the `writing-mode` property is in reality setting the direction in which block-level elements are displayed on the page — either from top-to-bottom, right-to-left, or left-to-right. This then dictates the direction text flows in sentences.

Writing modes and block and inline layout
-----------------------------------------

We have already discussed block and inline layout, and the fact that some things display as block elements and others as inline elements. As we have seen described above, block and inline is tied to the writing mode of the document, and not the physical screen. Blocks are only displayed from the top to the bottom of the page if you are using a writing mode that displays text horizontally, such as English.

If we look at an example this will become clearer. In this next example I have two boxes that contain a heading and a paragraph. The first uses `writing-mode: horizontal-tb`, a writing mode that is written horizontally and from the top of the page to the bottom. The second uses `writing-mode: vertical-rl`; this is a writing mode that is written vertically and from right to left.

When we switch the writing mode, we are changing which direction is block and which is inline. In a `horizontal-tb` writing mode the block direction runs from top to bottom; in a `vertical-rl` writing mode the block direction runs right-to-left horizontally. So the **block dimension** is always the direction blocks are displayed on the page in the writing mode in use. The **inline dimension** is always the direction a sentence flows.

This figure shows the two dimensions when in a horizontal writing mode.
 ![Showing the block and inline axis for a horizontal writing mode.](/en-US/docs/Learn/CSS/Building_blocks/Handling_different_text_directions/horizontal-tb.png)

This figure shows the two dimensions in a vertical writing mode.

![Showing the block and inline axis for a vertical writing mode.](/en-US/docs/Learn/CSS/Building_blocks/Handling_different_text_directions/vertical.png)

Once you start to look at CSS layout, and in particular the newer layout methods, this idea of block and inline becomes very important. We will revisit it later on.

### Direction

In addition to writing mode we also have text direction. As mentioned above, some languages such as Arabic are written horizontally, but right-to-left. This is not something you are likely to use in a creative sense — if you want to line something up on the right there are other ways to do so — however it is important to understand this as part of the nature of CSS. The web is not just for languages that are displayed left-to-right!

Due to the fact that writing mode and direction of text can change, newer CSS layout methods do not refer to left and right, and top and bottom. Instead they will talk about *start* and *end* along with this idea of inline and block. Don't worry too much about that right now, but keep these ideas in mind as you start to look at layout; you will find it really helpful in your understanding of CSS.

Logical properties and values
-----------------------------

The reason to talk about writing modes and direction at this point in your learning is that we have already looked at a lot of properties that are tied to the physical dimensions of the screen, and these make more sense when in a horizontal writing mode.

Let's take a look at our two boxes again — one with a `horizontal-tb` writing mode and one with `vertical-rl`. I have given both of these boxes a `width`. You can see that when the box is in the vertical writing mode, it still has a width, and this is causing the text to overflow.

What we really want in this scenario is to essentially swap height with width in accordance to the writing mode. When we're in a vertical writing mode we want the box to expand in the block dimension just like it does in the horizontal mode.

To make this easier, CSS has recently developed a set of mapped properties. These essentially replace physical properties — things like `width` and `height` — with **logical**, or **flow relative** versions.

The property mapped to `width` when in a horizontal writing mode is called `inline-size` — it refers to the size in the inline dimension. The property for `height` is named `block-size` and is the size in the block dimension. You can see how this works in the example below where we have replaced `width` with `inline-size`.

### Logical margin, border, and padding properties

In the last two lessons we have learned about the CSS box model, and CSS borders. In the margin, border, and padding properties you will find many instances of physical properties, for example `margin-top`, `padding-left`, and `border-bottom`. In the same way that we have mappings for width and height there are mappings for these properties.

The `margin-top` property is mapped to `margin-block-start` — this will always refer to the margin at the start of the block dimension.

The `padding-left` property maps to `padding-inline-start`, the padding that is applied to the start of the inline direction. This will be where sentences start in that writing mode. The `border-bottom` property maps to `border-block-end`, which is the border at the end of the block dimension.

You can see a comparison between physical and logical properties below.

**If you change the writing mode of the boxes by switching the `writing-mode` property on `.box` to `vertical-rl`, you will see how the physical properties stay tied to their physical direction, whereas the logical properties switch with the writing mode.**

**You can also see that the h2 has a black `border-bottom`. Can you work out how to make that bottom border always go below the text in both writing modes?**

There are a huge number of properties when you consider all of the individual border longhands, and you can see all of the mapped properties on the MDN page for Logical Properties and Values.

### Logical values

We have so far looked at logical property names. There are also some properties that take physical values of `top`, `right`, `bottom`, and `left`. These values also have mappings, to logical values — `block-start`, `inline-end`, `block-end`, and `inline-start`.

For example, you can float an image left to cause text to wrap round the image. You could replace `left` with `inline-start` as shown in the example below.

**Change the writing mode on this example to `vertical-rl` to see what happens to the image. Change `inline-start` to `inline-end` to change the float.**

Here we are also using logical margin values to ensure the margin is in the correct place no matter what the writing mode is.

### Should you use physical or logical properties?

The logical properties and values are newer than their physical equivalents, and therefore have only recently been implemented in browsers. You can check any property page on MDN to see how far back the browser support goes. If you are not using multiple writing modes, then for now you might prefer to use the physical versions. However, ultimately we expect that people will transition to the logical versions for most things, as they make a lot of sense once you also start dealing with layout methods such as flexbox and grid.

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: Writing modes and logical properties.

Summary
-------

The concepts explained in this lesson are becoming increasingly important in CSS. An understanding of the block and inline direction — and how text flow changes with a change in writing mode — will be very useful going forward. It will help you in understanding CSS even if you never use a writing mode other than a horizontal one.

In the next article, we'll take a good look at overflow in CSS.

* Previous
* Overview: Building blocks
* Next


Creating fancy letterheaded paper - Learn web development

Creating fancy letterheaded paper
=================================

* Previous
* Overview: Building blocks
* Next

If you want to make the right impression, writing a letter on nice letterheaded paper can be a really good start. In this assessment we'll challenge you to create an online template to achieve such a look.

|  |  |
| --- | --- |
| Prerequisites: |
 Before attempting this assessment you should have already worked through
 all the articles in this module.
  |
| Objective: |
 To test comprehension of CSS box model, and other box-related features
 such as implementing backgrounds.
  |

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

To get this assessment started, you should:

* Make local copies of the HTML and CSS — save them as `index.html` and `style.css` in a new directory.
* Save local copies of the top, bottom and logo images in the same directory as your code files.

 Alternatively, you could use an online editor such as CodePen, JSFiddle, or Glitch.
 You could paste the HTML and fill in the CSS into one of these online editors.

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

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

You have been given the files needed to create a letterheaded paper template. You just need to put the files together. To get there, you need to:

### The main letter

* Apply the CSS to the HTML.
* Add a background declaration to the letter that:
    + Fixes the top image to the top of the letter
    + Fixes the bottom image to the bottom of the letter
    + Adds a semi-transparent gradient over the top of both of the previous backgrounds that gives the letter a bit of texture. Make it slightly dark right near the top and bottom, but completely transparent for a large part of the center.
* Add another background declaration that just adds the top image to the top of the letter, as a fallback for browsers that don't support the previous declaration.
* Add a white background color to the letter.
* Add a 1mm top and bottom solid border to the letter, in a color that is in keeping with the rest of the color scheme.
### The logo

* To the h1, add the logo as a background image.
* Add a filter to the logo to give it a subtle drop shadow.
* Now comment out the filter and implement the drop shadow in a different (slightly more cross-browser compatible) way, which still follows the shape of the round image.
Hints and tips
--------------

* Remember that you can create a fallback for older browsers by putting the fallback version of a declaration first, followed by the version that works across newer browsers only. Older browsers will apply the first declaration and ignore the second one, whereas newer browsers will apply the first one, then override it with the second one.
* Feel free to create your own graphics for the assessment if you wish.
Example
-------

The following screenshot shows an example of what the finished design could look like:

![Full A4 page composed of at the top left two triangular shapes, first one is green, second one is red, at the top right darker red trapezoid shape. Below the green triangular, a red circle filled with a green star with white text on it: Awesome company. At the bottom left of the page, darker red trapezoid shape, follow by the two triangular shapes: the red one, then the green one. Above the green triangular shape, black text displaying a postal address.](/en-US/docs/Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper/letterhead.png)

* Previous
* Overview: Building blocks
* Next


Test your skills: The box model - Learn web development

Test your skills: The box model
===============================

The aim of this skill test is to assess whether you understand the CSS box model.

**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, there are two boxes below, one is using the standard box model, the other the alternate box model. Change the width of the second box by adding declarations to the `.alternate` class, so that it matches the visual width of the first box.

Your final result should look like the image below:

![Two boxes of the same size](/en-US/docs/Learn/CSS/Building_blocks/Box_Model_Tasks/mdn-box-model1.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.

Task 2
------

In this task, add to the box:

* A 5px, black, dotted border.
* A top margin of 20px.
* A right margin of 1em.
* A bottom margin of 40px.
* A left margin of 2em.
* Padding on all sides of 1em.

Your final result should look like the image below:

![A box with a dotted border](/en-US/docs/Learn/CSS/Building_blocks/Box_Model_Tasks/mdn-box-model2.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.

Task 3
------

In this task, the inline element has a margin, padding and border. However, the lines above and below are overlapping it. What can you add to your CSS to cause the size of the margin, padding, and border to be respected by the other lines, while still keeping the element inline?

Your final result should look like the image below:

![An inline box with space between it and the text around it.](/en-US/docs/Learn/CSS/Building_blocks/Box_Model_Tasks/mdn-box-model3.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.


The box model - Learn web development

The box model
=============

* Previous
* Overview: Building blocks
* Next

Everything in CSS has a box around it, and understanding these boxes is key to being able to create more complex layouts with CSS, or to align items with other items. In this lesson, we will take a look at the CSS *Box Model*. You'll get an understanding of how it works and the terminology that relates to it.

|  |  |
| --- | --- |
| 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 CSS Box Model, what makes up the box model and how to
 switch to the alternate model.
  |

Block and inline boxes
----------------------

In CSS we have several types of boxes that generally fit into the categories of **block boxes** and **inline boxes**. The type refers to how the box behaves in terms of page flow and in relation to other boxes on the page. Boxes have an **inner display type** and an **outer display type**.

In general, you can set various values for the display type using the `display` property, which can have various values.

Outer display type
------------------

If a box has an outer display type of `block`, then:

* The box will break onto a new line.
* The `width` and `height` properties are respected.
* Padding, margin and border will cause other elements to be pushed away from the box.
* If `width` is not specified, the box will extend in the inline direction to fill the space available in its container. In most cases, the box will become as wide as its container, filling up 100% of the space available.

Some HTML elements, such as `<h1>` and `<p>`, use `block` as their outer display type by default.

If a box has an outer display type of `inline`, then:

* The box will not break onto a new line.
* The `width` and `height` properties will not apply.
* Top and bottom padding, margins, and borders will apply but will not cause other inline boxes to move away from the box.
* Left and right padding, margins, and borders will apply and will cause other inline boxes to move away from the box.

Some HTML elements, such as `<a>`, `<span>`, `<em>` and `<strong>` use `inline` as their outer display type by default.

Inner display type
------------------

Boxes also have an *inner* display type, which dictates how elements inside that box are laid out.

Block and inline layout is the default way things behave on the web. By default and without any other instruction, the elements inside a box are also laid out in **normal flow** and behave as block or inline boxes.

You can change the inner display type for example by setting `display: flex;`. The element will still use the outer display type `block` but this changes the inner display type to `flex`. Any direct children of this box will become flex items and behave according to the Flexbox specification.

When you move on to learn about CSS Layout in more detail, you will encounter `flex`, and various other inner values that your boxes can have, for example `grid`.

**Note:** To read more about the values of display, and how boxes work in block and inline layout, take a look at the MDN guide Block and Inline Layout.

Examples of different display types
-----------------------------------

The example below has three different HTML elements, all of which have an outer display type of `block`.

* A paragraph with a border added in CSS. The browser renders this as a block box. The paragraph starts on a new line and extends the entire available width.
* A list, which is laid out using `display: flex`. This establishes flex layout for the children of the container, which are flex items. The list itself is a block box and — like the paragraph — expands to the full container width and breaks onto a new line.
* A block-level paragraph, inside which are two `<span>` elements. These elements would normally be `inline`, however, one of the elements has a class of "block" which gets set to `display: block`.

In the next example, we can see how `inline` elements behave.

* The `<span>` elements in the first paragraph are inline by default and so do not force line breaks.
* The `<ul>` element that is set to `display: inline-flex` creates an inline box containing some flex items.
* The two paragraphs are both set to `display: inline`. The inline flex container and paragraphs all run together on one line rather than breaking onto new lines (as they would do if they were displaying as block-level elements).

**To toggle between the display modes, you can change `display: inline` to `display: block` or `display: inline-flex` to `display: flex`.**

The key thing to remember for now is: Changing the value of the `display` property can change whether the outer display type of a box is block or inline. This changes the way it displays alongside other elements in the layout.

What is the CSS box model?
--------------------------

The CSS box model as a whole applies to block boxes and defines how the different parts of a box — margin, border, padding, and content — work together to create a box that you can see on a page. Inline boxes use just *some* of the behavior defined in the box model.

To add complexity, there is a standard and an alternate box model. By default, browsers use the standard box model.

### Parts of a box

Making up a block box in CSS we have the:

* **Content box**: The area where your content is displayed; size it using properties like `inline-size` and `block-size` or `width` and `height`.
* **Padding box**: The padding sits around the content as white space; size it using `padding` and related properties.
* **Border box**: The border box wraps the content and any padding; size it using `border` and related properties.
* **Margin box**: The margin is the outermost layer, wrapping the content, padding, and border as whitespace between this box and other elements; size it using `margin` and related properties.

The below diagram shows these layers:

![Diagram of the box model](/en-US/docs/Learn/CSS/Building_blocks/The_box_model/box-model.png)

### The standard CSS box model

In the standard box model, if you set `inline-size` and `block-size` (or `width` and `height`) property values on a box, these values define the `inline-size` and `block-size` (`width` and `height` in horizontal languages) of the *content box*. Any padding and borders are then added to those dimensions to get the total size taken up by the box (see the image below).

If we assume that a box has the following CSS:

```css
.box {
  width: 350px;
  height: 150px;
  margin: 10px;
  padding: 25px;
  border: 5px solid black;
}
```

The *actual* space taken up by the box will be 410px wide (350 + 25 + 25 + 5 + 5) and 210px high (150 + 25 + 25 + 5 + 5).

![Showing the size of the box when the standard box model is being used.](/en-US/docs/Learn/CSS/Building_blocks/The_box_model/standard-box-model.png)

**Note:** The margin is not counted towards the actual size of the box — sure, it affects the total space that the box will take up on the page, but only the space outside the box. The box's area stops at the border — it does not extend into the margin.

### The alternative CSS box model

In the alternative box model, any width is the width of the visible box on the page. The content area width is that width minus the width for the padding and border (see image below). No need to add up the border and padding to get the real size of the box.

To turn on the alternative model for an element, set `box-sizing: border-box` on it:

```css
.box {
  box-sizing: border-box;
}
```

If we assume the box has the same CSS as above:

```css
.box {
  width: 350px;
  inline-size: 350px;
  height: 150px;
  block-size: 150px;
  margin: 10px;
  padding: 25px;
  border: 5px solid black;
}
```

Now, the *actual* space taken up by the box will be 350px in the inline direction and 150px in the block direction.

![Showing the size of the box when the alternate box model is being used.](/en-US/docs/Learn/CSS/Building_blocks/The_box_model/alternate-box-model.png)

To use the alternative box model for all of your elements (which is a common choice among developers), set the `box-sizing` property on the `<html>` element and set all other elements to inherit that value:

```css
html {
  box-sizing: border-box;
}

\*,
\*::before,
\*::after {
  box-sizing: inherit;
}
```

To understand the underlying idea, you can read the CSS Tricks article on box-sizing.

Playing with box models
-----------------------

In the example below, you can see two boxes. Both have a class of `.box`, which gives them the same `width`, `height`, `margin`, `border`, and `padding`. The only difference is that the second box has been set to use the alternative box model.

**Can you change the size of the second box (by adding CSS to the `.alternate` class) to make it match the first box in width and height?**

**Note:** You can find a solution for this task here.

### Use browser DevTools to view the box model

Your browser developer tools can make understanding the box model far easier. If you inspect an element in Firefox's DevTools, you can see the size of the element plus its margin, padding, and border. Inspecting an element in this way is a great way to find out if your box is really the size you think it is!

![Inspecting the box model of an element using Firefox DevTools](/en-US/docs/Learn/CSS/Building_blocks/The_box_model/box-model-devtools.png)

Margins, padding, and borders
-----------------------------

You've already seen the `margin`, `padding`, and `border` properties at work in the example above. The properties used in that example are **shorthands** and allow us to set all four sides of the box at once. These shorthands also have equivalent longhand properties, which allow control over the different sides of the box individually.

Let's explore these properties in more detail.

### Margin

The margin is an invisible space around your box. It pushes other elements away from the box. Margins can have positive or negative values. Setting a negative margin on one side of your box can cause it to overlap other things on the page. Whether you are using the standard or alternative box model, the margin is always added after the size of the visible box has been calculated.

We can control all margins of an element at once using the `margin` property, or each side individually using the equivalent longhand properties:

* `margin-top`
* `margin-right`
* `margin-bottom`
* `margin-left`

**In the example below, try changing the margin values to see how the box is pushed around due to the margin creating or removing space (if it is a negative margin) between this element and the containing element.**

#### Margin collapsing

Depending on whether two elements whose margins touch have positive or negative margins, the results will be different:

* Two positive margins will combine to become one margin. Its size will be equal to the largest individual margin.
* Two negative margins will collapse and the smallest (furthest from zero) value will be used.
* If one margin is negative, its value will be *subtracted* from the total.

In the example below, we have two paragraphs. The top paragraph has a `margin-bottom` of 50 pixels, the other has a `margin-top` of 30 pixels. The margins have collapsed together so the actual margin between the boxes is 50 pixels and not the total of the two margins.

**You can test this by setting the `margin-top` of paragraph two to 0. The visible margin between the two paragraphs will not change — it retains the 50 pixels set in the `margin-bottom` of paragraph one. If you set it to -10px, you'll see that the overall margin becomes 40px — it subtracts from the 50px.**

A number of rules dictate when margins do and do not collapse. For further information see the detailed page on mastering margin collapsing. The main thing to remember is that margin collapsing is a thing that happens if you are creating space with margins and don't get the space you expect.

### Borders

The border is drawn between the margin and the padding of a box. If you are using the standard box model, the size of the border is added to the `width` and `height` of the content box. If you are using the alternative box model, then the bigger the border is, the smaller the content box is, as the border takes up some of that available `width` and `height` of the element box.

For styling borders, there are a large number of properties — there are four borders, and each border has a style, width, and color that we might want to manipulate.

You can set the width, style, or color of all four borders at once using the `border` property.

To set the properties of each side individually, use:

* `border-top`
* `border-right`
* `border-bottom`
* `border-left`

To set the width, style, or color of all sides, use:

* `border-width`
* `border-style`
* `border-color`

To set the width, style, or color of a single side, use one of the more granular longhand properties:

* `border-top-width`
* `border-top-style`
* `border-top-color`
* `border-right-width`
* `border-right-style`
* `border-right-color`
* `border-bottom-width`
* `border-bottom-style`
* `border-bottom-color`
* `border-left-width`
* `border-left-style`
* `border-left-color`

In the example below, we have used various shorthands and longhands to create borders. Play around with the different properties to check that you understand how they work. The MDN pages for the border properties give you information about the different available border styles.

### Padding

The padding sits between the border and the content area and is used to push the content away from the border. Unlike margins, you cannot have a negative padding. Any background applied to your element will display behind the padding.

The `padding` property controls the padding on all sides of an element. To control each side individually, use these longhand properties:

* `padding-top`
* `padding-right`
* `padding-bottom`
* `padding-left`

In the example below, you can change the values for padding on the class `.box` to see that this changes where the text begins in relation to the box. You can also change the padding on the class `.container` to create space between the container and the box. You can change the padding on any element to create space between its border and whatever is inside the element.

The box model and inline boxes
------------------------------

All of the above fully applies to block boxes. Some of the properties can apply to inline boxes too, such as those created by a `<span>` element.

In the example below, we have a `<span>` inside a paragraph. We have applied a `width`, `height`, `margin`, `border`, and `padding` to it. You can see that the width and height are ignored. The top and bottom margin, padding, and border are respected but don't change the relationship of other content to our inline box. The padding and border overlap other words in the paragraph. The left and right padding, margins, and borders move other content away from the box.

Using display: inline-block
---------------------------

`display: inline-block` is a special value of `display`, which provides a middle ground between `inline` and `block`. Use it if you do not want an item to break onto a new line, but do want it to respect `width` and `height` and avoid the overlapping seen above.

An element with `display: inline-block` does a subset of the block things we already know about:

* The `width` and `height` properties are respected.
* `padding`, `margin`, and `border` will cause other elements to be pushed away from the box.

It does not, however, break onto a new line, and will only become larger than its content if you explicitly add `width` and `height` properties.

**In this next example, we have added `display: inline-block` to our `<span>` element. Try changing this to `display: block` or removing the line completely to see the difference in display models.**

Where this can be useful is when you want to give a link a larger hit area by adding `padding`. `<a>` is an inline element like `<span>`; you can use `display: inline-block` to allow padding to be set on it, making it easier for a user to click the link.

You see this fairly frequently in navigation bars. The navigation below is displayed in a row using flexbox and we have added padding to the `<a>` element as we want to be able to change the `background-color` when the `<a>` is hovered. The padding appears to overlap the border on the `<ul>` element. This is because the `<a>` is an inline element.

**Add `display: inline-block` to the rule with the `.links-list a` selector, and you will see how it fixes this issue by causing the padding to be respected by other elements.**

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 box model.

Summary
-------

That's most of what you need to understand about the box model. You may want to return to this lesson in the future if you ever find yourself confused about how big boxes are in your layout.

In the next article, we'll take a look at how backgrounds and borders can be used to make your plain boxes look more interesting.

* Previous
* Overview: Building blocks
* Next


Test your skills: Overflow - Learn web development

Test your skills: Overflow
==========================

The aim of this skill test is to assess whether you understand overflow in CSS and how to manage it.

**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, the content is overflowing the box because it has a fixed height. Keep the height but cause the box to have scrollbars only if there is enough text to cause an overflow. Test by removing some of the text from the HTML, that if there is only a small amount of text that does not overflow, no scrollbar appears.

![A small box with a border and a vertical scrollbar.](/en-US/docs/Learn/CSS/Building_blocks/Overflow_Tasks/mdn-overflow1.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.

Task 2
------

In this task, there is an image in the box that is bigger than the dimensions of the box so that it overflows visibly. Change it so that any image outside of the box is hidden.

Your final result should look like the image below:

![A box with an image which fills the box but does not spill out the edges.](/en-US/docs/Learn/CSS/Building_blocks/Overflow_Tasks/mdn-overflow2.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.


Fundamental CSS comprehension - Learn web development

Fundamental CSS comprehension
=============================

* Previous
* Overview: Building blocks
* Next

You've covered a lot in this module, so it must feel good to have reached the end! The final step before you move on is to attempt the assessment for the module — this involves a number of related exercises that must be completed in order to create the final design — a business card/gamer card/social media profile.

|  |  |
| --- | --- |
| Prerequisites: |
 Before attempting this assessment you should have already worked through
 all the articles in this module.
  |
| Objective: | To test comprehension of fundamental CSS theory, syntax and mechanics. |

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

To get this assessment started, you should:

* Go and grab the HTML file for the exercise, and the associated image file, and save them in a new directory on your local computer. If you want to use your own image file and fill your own name in, you are welcome to — just make sure the image is square.
* Grab the CSS resources text file — this contains a set of raw selectors and rulesets that you'll need to study and combine to answer part of this assessment.

 Alternatively, you could use an online editor such as CodePen, JSFiddle, or Glitch.
 You could paste the HTML and fill in the CSS into one of these online editors, and use this URL to point the `<img>` element to the image file.

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

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

You have been provided with some raw HTML and an image, and need to write the necessary CSS to style this into a nifty little online business card, which can perhaps double as a gamer card or social media profile. The following sections describe what you need to do.

Basic setup:

* First of all, create a new file in the same directory as your HTML and image files. Call it something really imaginative like `style.css`.
* Link your CSS to your HTML file via a `<link>` element.
* The first two rulesets in the CSS resource file are yours, for FREE! After you've finished rejoicing at your good fortune, copy and paste them into the top of your new CSS file. Use them as a test to make sure your CSS is properly applied to your HTML.
* Above the two rules, add a CSS comment with some text inside it to indicate that this is a set of general styles for the overall page. "General page styles" would do. Also add three more comments at the bottom of the CSS file to indicate styles specific to the setup of the card container, styles specific to the header and footer, and styles specific to the main business card contents. From now on, subsequent styles added to the stylesheet should be organized in an appropriate place.

Taking care of the selectors and rulesets provided in the CSS resource file:

* Next up, we'd like you to look at the four selectors, and calculate the specificity for each one. Write these down somewhere where they can be found later on, such as in a comment at the top of your CSS.
* Now it's time to put the right selector on the right rule set! You've got four pairs of selector and ruleset to match in your CSS resources. Do this now, and add them to your CSS file. You need to:
    + Give the main card container a fixed width/height, solid background color, border, and border-radius (rounded corners!), amongst other things.
    + Give the header a background gradient that goes from darker to lighter, plus rounded corners that fit in with the rounded corners set on the main card container.
    + Give the footer a background gradient that goes from lighter to darker, plus rounded corners that fit in with the rounded corners set on the main card container.
    + Float the image to the right so that it sticks to the right-hand side of the main business card contents, and give it a max-height of 100% (a clever trick that ensures that it will grow/shrink to stay the same height as its parent container, regardless of what height it becomes.)
* Beware! There are two errors in the provided rulesets. Using any technique that you know, track these down and fix them before moving on.

New rulesets you need to write:

* Write a ruleset that targets both the card header, and card footer, giving them both a computed total height of 50px (including a content height of 30px and padding of 10px on all sides.) But express it in `em`s.
* The default margin applied to the `<h2>` and `<p>` elements by the browser will interfere with our design, so write a rule that targets all these elements and sets their margin to 0.
* To stop the image from spilling out of the main business card content (the `<article>` element), we need to give it a specific height. Set the `<article>`'s height to 120px, but expressed in `em`s. Also give it a background color of semi-transparent black, resulting in a slightly darker shade that lets the background red color shine through a bit too.
* Write a ruleset that gives the `<h2>` an effective font size of 20px (but expressed in `em`s) and an appropriate line height to place it in the center of the header's content box. Recall from earlier that the content box height should be 30px — this gives you all the numbers you need to calculate the line height.
* Write a ruleset that gives the `<p>` inside the footer an effective font size of 15px (but expressed in `em`s) and an appropriate line height to place it in the center of the footer's content box. Recall from earlier that the content box height should be 30px — this gives you all the numbers you need to calculate the line height.
* As a last little touch, give the paragraph inside the `<article>` an appropriate padding value so that its left edge lines up with the `<h2>` and footer paragraph, and set its color to be fairly light so it is easy to read.

**Note:** Bear in mind that the second ruleset sets `font-size: 10px;` on the `<html>` element — this means that for any descendants of `<html>`, an em will be equal to 10px rather than 16px as it is by default. (This is of course, provided the descendants in question don't have any ancestors sitting in between them and `<html>` in the hierarchy that have a different `font-size` set on them. This could affect the values you need, although in this simple example this is not an issue.)

Other things to think about:

* You'll get bonus marks if you write your CSS for maximum readability, with a separate declaration on each line.
* You should include `.card` at the start of the selector chain in all your rules, so that these rules wouldn't interfere with the styling of any other elements if the business card were to be put on a page with a load of other content.
Hints and tips
--------------

* You don't need to edit the HTML in any way, except to apply the CSS to your HTML.
* When trying to work out the `em` value you need to represent a certain pixel length, think about what base font size the root (`<html>`) element has, and what it needs to be multiplied by to get the desired value. That'll give you your em value, at least in a simple case like this.
Example
-------

The following screenshot shows an example of what the finished design should look like:

![A view of the finished business card, show a reader header and footer, and a darker center panel containing the main details and image.](/en-US/docs/Learn/CSS/Building_blocks/Fundamental_CSS_comprehension/business-card.png)

* Previous
* Overview: Building blocks
* Next