Styling lists - Learn web development

Styling lists
=============

* Previous
* Overview: Styling text
* Next

Lists behave like any other text for the most part, but there are some CSS properties specific to lists that you need to know about, as well as some best practices to consider. This article explains all.

|  |  |
| --- | --- |
| Prerequisites: |
 HTML basics (study
 Introduction to HTML), CSS basics (study
 Introduction to CSS),
 CSS text and font fundamentals.
  |
| Objective: |
 To become familiar with the best practices and properties related to
 styling lists.
  |

A simple list example
---------------------

To begin with, let's look at a simple list example. Throughout this article, we'll look at unordered, ordered, and description lists — all have styling features that are similar, as well as some that are particular to themselves. The unstyled example is available on GitHub (check out the source code too.)

The HTML for our list example looks like so:

```html
<h2>Shopping (unordered) list</h2>

<p>
  Paragraph for reference, paragraph for reference, paragraph for reference,
  paragraph for reference, paragraph for reference, paragraph for reference.
</p>

<ul>
  <li>Hummus</li>
  <li>Pita</li>
  <li>Green salad</li>
  <li>Halloumi</li>
</ul>

<h2>Recipe (ordered) list</h2>

<p>
  Paragraph for reference, paragraph for reference, paragraph for reference,
  paragraph for reference, paragraph for reference, paragraph for reference.
</p>

<ol>
  <li>Toast pita, leave to cool, then slice down the edge.</li>
  <li>
    Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
  </li>
  <li>Wash and chop the salad.</li>
  <li>Fill pita with salad, hummus, and fried halloumi.</li>
</ol>

<h2>Ingredient description list</h2>

<p>
  Paragraph for reference, paragraph for reference, paragraph for reference,
  paragraph for reference, paragraph for reference, paragraph for reference.
</p>

<dl>
  <dt>Hummus</dt>
  <dd>
    A thick dip/sauce generally made from chick peas blended with tahini, lemon
    juice, salt, garlic, and other ingredients.
  </dd>
  <dt>Pita</dt>
  <dd>A soft, slightly leavened flatbread.</dd>
  <dt>Halloumi</dt>
  <dd>
    A semi-hard, unripened, brined cheese with a higher-than-usual melting
    point, usually made from goat/sheep milk.
  </dd>
  <dt>Green salad</dt>
  <dd>That green healthy stuff that many of us just use to garnish kebabs.</dd>
</dl>
```

If you go to the live example now and investigate the list elements using browser developer tools, you'll notice a couple of styling defaults:

* The `<ul>` and `<ol>` elements have a top and bottom `margin` of `16px` (`1em`) and a `padding-left` of `40px` (`2.5em`). If the directionality attribute `dir` is set to right-to-left (`rtl`) for `ul` and `ol` elements, in that case `padding-right` comes into effect and its default value is `40px` (`2.5em`) .
* The list items (`<li>` elements) have no set defaults for spacing.
* The `<dl>` element has a top and bottom `margin` of `16px` (`1em`), but no padding set.
* The `<dd>` elements have `margin-left` of `40px` (`2.5em`).
* The `<p>` elements we've included for reference have a top and bottom `margin` of `16px` (`1em`) — the same as the different list types.
Handling list spacing
---------------------

When styling lists, you need to adjust their styles so they keep the same vertical spacing as their surrounding elements (such as paragraphs and images; sometimes called vertical rhythm), and the same horizontal spacing as each other (you can see the finished styled example on GitHub, and find the source code too).

The CSS used for the text styling and spacing is as follows:

```css
/\* General styles \*/

html {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 10px;
}

h2 {
  font-size: 2rem;
}

ul,
ol,
dl,
p {
  font-size: 1.5rem;
}

li,
p {
  line-height: 1.5;
}

/\* Description list styles \*/

dd,
dt {
  line-height: 1.5;
}

dt {
  font-weight: bold;
}
```

* The first rule sets a sitewide font and a baseline font size of 10px. These are inherited by everything on the page.
* Rules 2 and 3 set relative font sizes for the headings, different list types (the children of the list elements inherit these), and paragraphs. This means that each paragraph and list will have the same font size and top and bottom spacing, helping to keep the vertical rhythm consistent.
* Rule 4 sets the same `line-height` on the paragraphs and list items — so the paragraphs and each individual list item will have the same spacing between lines. This will also help to keep the vertical rhythm consistent.
* Rules 5 and 6 apply to the description list. We set the same `line-height` on the description list terms and descriptions as we did with the paragraphs and list items. Again, consistency is good! We also make the description terms have bold font, so they visually stand out easier.
List-specific styles
--------------------

Now that we've looked at general spacing techniques for lists, let's explore some list-specific properties. There are three properties you should know about to start with, which can be set on `<ul>` or `<ol>` elements:

* `list-style-type`: Sets the type of bullets to use for the list, for example, square or circle bullets for an unordered list, or numbers, letters, or roman numerals for an ordered list.
* `list-style-position`: Sets whether the bullets, at the start of each item, appear inside or outside the lists.
* `list-style-image`: Allows you to use a custom image for the bullet, rather than a simple square or circle.
### Bullet styles

As mentioned above, the `list-style-type` property allows you to set what type of bullet to use for the bullet points. In our example, we've set the ordered list to use uppercase roman numerals with:

```css
ol {
  list-style-type: upper-roman;
}
```

This gives us the following look:

![an ordered list with the bullet points set to appear outside the list item text.](/en-US/docs/Learn/CSS/Styling_text/Styling_lists/outer-bullets.png)

You can find a lot more options by checking out the `list-style-type` reference page.

### Bullet position

The `list-style-position` property sets whether the bullets appear inside the list items, or outside them before the start of each item. The default value is `outside`, which causes the bullets to sit outside the list items, as seen above.

If you set the value to `inside`, the bullets will sit inside the lines:

```css
ol {
  list-style-type: upper-roman;
  list-style-position: inside;
}
```

![an ordered list with the bullet points set to appear inside the list item text.](/en-US/docs/Learn/CSS/Styling_text/Styling_lists/inner-bullets.png)

### Using a custom bullet image

The `list-style-image` property allows you to use a custom image for your bullet. The syntax is pretty simple:

```css
ul {
  list-style-image: url(star.svg);
}
```

However, this property is a bit limited in terms of controlling the position, size, etc. of the bullets. You are better off using the `background` family of properties, which you've learned in the Backgrounds and borders article. For now, here's a taster!

In our finished example, we have styled the unordered list like so (on top of what you've already seen above):

```css
ul {
  padding-left: 2rem;
  list-style-type: none;
}

ul li {
  padding-left: 2rem;
  background-image: url(star.svg);
  background-position: 0 0;
  background-size: 1.6rem 1.6rem;
  background-repeat: no-repeat;
}
```

Here we've done the following:

* Set the `padding-left` of the `<ul>` down from the default `40px` to `20px`, then set the same amount on the list items. This is so that, overall, the list items are still lined up with the ordered list items and the description list descriptions, but the list items have some padding for the background images to sit inside. If we didn't do this, the background images would overlap with the list item text, which would look messy.
* Set the `list-style-type` to `none`, so that no bullet appears by default. We're going to use `background` properties to handle the bullets instead.
* Inserted a bullet onto each unordered list item. The relevant properties are as follows:
    + `background-image`: This references the path to the image file you want to use as the bullet.
    + `background-position`: This defines where in the background of the selected element the image will appear — in this case we are saying `0 0`, which means the bullet will appear in the very top left of each list item.
    + `background-size`: This sets the size of the background image. We ideally want the bullets to be the same size as the list items (or very slightly smaller or larger). We are using a size of `1.6rem` (`16px`), which fits very nicely with the `20px` padding we've allowed for the bullet to sit inside — 16px plus 4px of space between the bullet and the list item text works well.
    + `background-repeat`: By default, background images repeat until they fill up the available background space. We only want one copy of the image inserted in each case, so we set this to a value of `no-repeat`.

This gives us the following result:

![an unordered list with the bullet points set as little star images](/en-US/docs/Learn/CSS/Styling_text/Styling_lists/list_formatting.png)

### list-style shorthand

The three properties mentioned above can all be set using a single shorthand property, `list-style`. For example, the following CSS:

```css
ul {
  list-style-type: square;
  list-style-image: url(example.png);
  list-style-position: inside;
}
```

Could be replaced by this:

```css
ul {
  list-style: square url(example.png) inside;
}
```

The values can be listed in any order, and you can use one, two, or all three (the default values used for the properties that are not included are `disc`, `none`, and `outside`). If both a `type` and an `image` are specified, the type is used as a fallback if the image can't be loaded for some reason.

Controlling list counting
-------------------------

Sometimes you might want to count differently on an ordered list — e.g., starting from a number other than 1, or counting backwards, or counting in steps of more than 1. HTML and CSS have some tools to help you here.

### start

The `start` attribute allows you to start the list counting from a number other than 1. The following example:

```html
<ol start="4">
  <li>Toast pita, leave to cool, then slice down the edge.</li>
  <li>
    Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
  </li>
  <li>Wash and chop the salad.</li>
  <li>Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
```

Gives you this output:

### reversed

The `reversed` attribute will start the list counting down instead of up. The following example:

```html
<ol start="4" reversed>
  <li>Toast pita, leave to cool, then slice down the edge.</li>
  <li>
    Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
  </li>
  <li>Wash and chop the salad.</li>
  <li>Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
```

Gives you this output:

**Note:** If there are more list items in a reversed list than the value of the `start` attribute, the count will continue to zero and then into negative values.

### value

The `value` attribute allows you to set your list items to specific numerical values. The following example:

```html
<ol>
  <li value="2">Toast pita, leave to cool, then slice down the edge.</li>
  <li value="4">
    Fry the halloumi in a shallow, non-stick pan, until browned on both sides.
  </li>
  <li value="6">Wash and chop the salad.</li>
  <li value="8">Fill pita with salad, hummus, and fried halloumi.</li>
</ol>
```

Gives you this output:

**Note:** Even if you are using a non-number `list-style-type`, you still need to use the equivalent numerical values in the `value` attribute.

Active learning: Styling a nested list
--------------------------------------

In this active learning session, we want you to take what you've learned above and have a go at styling a nested list. We've provided you with the HTML, and we want you to:

1. Give the unordered list square bullets.
2. Give the unordered list items and the ordered list items a line-height of 1.5 of their font-size.
3. Give the ordered list lower alphabetical bullets.
4. Feel free to play with the list example as much as you like, experimenting with bullet types, spacing, or whatever else you can find.

If you make a mistake, you can always reset it using the *Reset* button. If you get really stuck, press the *Show solution* button to see a potential answer.
```

<div
 class="body-wrapper"
 style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;">
  <h2>HTML Input</h2>
  <textarea
 id="code"
 class="html-input"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">
<ul>
  <li>First, light the candle.</li>
  <li>Next, open the box.</li>
  <li>Finally, place the three magic items in the box, in this exact order, to complete the spell:
    <ol>
      <li>The book of spells</li>
      <li>The shiny rod</li>
      <li>The goblin statue</li>
    </ol>
  </li>
</ul>
  </textarea>

  <h2>CSS Input</h2>
  <textarea
 id="code"
 class="css-input"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"></textarea>

  <h2>Output</h2>
  <div
 class="output"
 style="width: 90%;height: 12em;padding: 10px;border: 1px solid #0095dd;overflow: auto;"></div>
  <div class="controls">
    <input
 id="reset"
 type="button"
 value="Reset"
 style="margin: 10px 10px 0 0;" />
    <input
 id="solution"
 type="button"
 value="Show solution"
 style="margin: 10px 0 0 10px;" />
  </div>
</div>
```

```
const htmlInput = document.querySelector(".html-input");
const cssInput = document.querySelector(".css-input");
const reset = document.getElementById("reset");
const htmlCode = htmlInput.value;
const cssCode = cssInput.value;
const output = document.querySelector(".output");
const solution = document.getElementById("solution");

const styleElem = document.createElement("style");
const headElem = document.querySelector("head");
headElem.appendChild(styleElem);

function drawOutput() {
  output.innerHTML = htmlInput.value;
  styleElem.textContent = cssInput.value;
}

reset.addEventListener("click", () => {
  htmlInput.value = htmlCode;
  cssInput.value = cssCode;
  drawOutput();
});

solution.addEventListener("click", () => {
  htmlInput.value = htmlCode;
  cssInput.value = `ul {
 list-style-type: square;
}

ul li,
ol li {
 line-height: 1.5;
}

ol {
 list-style-type: lower-alpha;
}`;
  drawOutput();
});

htmlInput.addEventListener("input", drawOutput);
cssInput.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

Summary
-------

Lists are relatively easy to get the hang of styling once you know a few associated basic principles and specific properties. In the next article, we'll move on to link styling techniques.

See also
--------

CSS counters provide advanced tools for customizing list counting and styling, but they are quite complex. We recommend looking into these if you want to stretch yourself. See:

* `@counter-style`
* `counter-increment`
* `counter-reset`
* Previous
* Overview: Styling text
* Next


Styling links - Learn web development

Styling links
=============

* Previous
* Overview: Styling text
* Next

When styling links, it's important to understand how to make use of pseudo-classes to style their states effectively. It's also important to know how to style links for use in common interface features whose content varies, such as navigation menus and tabs. We'll look at both these topics in this article.

|  |  |
| --- | --- |
| Prerequisites: |
 HTML basics (study
 Introduction to HTML), CSS basics (study
 Introduction to CSS),
 CSS text and font fundamentals.
  |
| Objective: |
 To learn how to style link states, and how to use links effectively in
 common UI features like navigation menus.
  |

Let's look at some links
------------------------

We looked at how links are implemented in your HTML according to best practices in Creating hyperlinks. In this article we'll build on this knowledge, showing you the best practices for styling them.

### Link states

The first thing to understand is the concept of link states — different states that links can exist in. These can be styled using different pseudo-classes:

* **Link**: A link that has a destination (i.e., not just a named anchor), styled using the `:link` pseudo class.
* **Visited**: A link that has already been visited (exists in the browser's history), styled using the `:visited` pseudo class.
* **Hover**: A link that is hovered over by a user's mouse pointer, styled using the `:hover` pseudo class.
* **Focus**: A link that is focused (e.g., moved to by a keyboard user using the
 `Tab`
 key or something similar, or programmatically focused using `HTMLElement.focus()`) — this is styled using the `:focus` pseudo class.
* **Active**: A link that is activated (e.g., clicked on), styled using the `:active` pseudo class.
### Default styles

The example below illustrates what a link will look and behave like by default; though the CSS is enlarging and centering the text to make it stand out more. You can compare the look and behavior of the default stylings in the example with the look and behavior of other links on this page which have more CSS styles applied. Default links have the following properties:

* Links are underlined.
* Unvisited links are blue.
* Visited links are purple.
* Hovering a link makes the mouse pointer change to a little hand icon.
* Focused links have an outline around them — you should be able to focus on the links on this page with the keyboard by pressing the tab key. (On Mac, you'll need to use
 `option`
 +
 `tab`
 , or enable the Full Keyboard Access: All controls option by pressing
 `Ctrl`
 +
 `F7`
 .)
* Active links are red. Try holding down the mouse button on the link as you click it.

```html
<p><a href="#">A simple link</a></p>
```

```css
p {
  font-size: 2rem;
  text-align: center;
}
```

**Note:** All the link examples on this page link to the top of their window. The empty fragment (`href="#"`) is used to create simple examples and ensure the live examples, which are each contained in an `<iframe>`, don't break.

Interestingly enough, these default styles are nearly the same as they were back in the early days of browsers in the mid-1990s. This is because users know and have come to expect this behavior — if links were styled differently, it would confuse a lot of people. This doesn't mean that you shouldn't style links at all. It just means that you shouldn't stray too far from the expected behavior. You should at least:

* Use underlining for links, but not for other things. If you don't want to underline links, at least highlight them in some other way.
* Make them react in some way when hovered/focused, and in a slightly different way when activated.

The default styles can be turned off/changed using the following CSS properties:

* `color` for the text color.
* `cursor` for the mouse pointer style — you shouldn't turn this off unless you've got a very good reason.
* `outline` for the text outline. An outline is similar to a border. The only difference is that a border takes up space in the box and an outline doesn't; it just sits over the top of the background. The outline is a useful accessibility aid, so should not be removed without adding another method of indicating the focused link.

**Note:** You are not just limited to the above properties to style your links — you are free to use any properties you like.

### Styling some links

Now that we've looked at the default states in some detail, let's look at a typical set of link styles.

To start off with, we'll write out our empty rulesets:

```css
a {
}

a:link {
}

a:visited {
}

a:focus {
}

a:hover {
}

a:active {
}
```

This order is important because link styles build on one another. For example, the styles in the first rule will apply to all the subsequent ones. When a link is activated, it's usually also hovered over. If you put these in the wrong order, and you're changing the same properties in each ruleset, things won't work as you expect. To remember the order, you could try using a mnemonic like **L**o**V**e **F**ears **HA**te.

Now let's add some more information to get this styled properly:

```css
body {
  width: 300px;
  margin: 0 auto;
  font-size: 1.2rem;
  font-family: sans-serif;
}

p {
  line-height: 1.4;
}

a {
  outline-color: transparent;
}

a:link {
  color: #6900ff;
}

a:visited {
  color: #a5c300;
}

a:focus {
  text-decoration: none;
  background: #bae498;
}

a:hover {
  text-decoration: none;
  background: #cdfeaa;
}

a:active {
  background: #6900ff;
  color: #cdfeaa;
}
```

We'll also provide some sample HTML to apply the CSS to:

```html
<p>
  There are several browsers available, such as <a href="#">Mozilla Firefox</a>,
  <a href="#">Google Chrome</a>, and <a href="#">Microsoft Edge</a>.
</p>
```

Putting the two together gives us this result:

So what did we do here? This certainly looks different to the default styling, but it still provides a familiar enough experience for users to know what's going on:

* The first two rules are not that interesting to this discussion.
* The third rule uses the `a` selector to get rid of the focus outline (which varies across browsers anyway).
* Next, we use the `a:link` and `a:visited` selectors to set a couple of color variations on unvisited and visited links, so they are distinct.
* The next two rules use `a:focus` and `a:hover` to set focused and hovered links to have no underline and different background colors.
* Finally, `a:active` is used to give the links an inverted color scheme while they are being activated, to make it clear something important is happening!
### Active learning: Style your own links

In this active learning session, we'd like you to take our empty set of rules and add your own declarations to make the links look really cool. Use your imagination, go wild. We are sure you can come up with something cooler and just as functional as our example above.

If you make a mistake, you can always reset it using the *Reset* button. If you get really stuck, press the *Show solution* button to insert the example we showed above.
```

<div
 class="body-wrapper"
 style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;">
  <h2>HTML Input</h2>
  <textarea
 id="code"
 class="html-input"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">
<p>There are several browsers available, such as <a href="#">Mozilla
 Firefox</a>, <a href="#">Google Chrome</a>, and
<a href="#">Microsoft Edge</a>.</p>
  </textarea>

  <h2>CSS Input</h2>
  <textarea
 id="code"
 class="css-input"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">
a {

}

a:link {

}

a:visited {

}

a:focus {

}

a:hover {

}

a:active {

}
  </textarea>

  <h2>Output</h2>
  <div
 class="output"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"></div>
  <div class="controls">
    <input
 id="reset"
 type="button"
 value="Reset"
 style="margin: 10px 10px 0 0;" />
    <input
 id="solution"
 type="button"
 value="Show solution"
 style="margin: 10px 0 0 10px;" />
  </div>
</div>
```

```
const htmlInput = document.querySelector(".html-input");
const cssInput = document.querySelector(".css-input");
const reset = document.getElementById("reset");
const htmlCode = htmlInput.value;
const cssCode = cssInput.value;
const output = document.querySelector(".output");
const solution = document.getElementById("solution");

const styleElem = document.createElement("style");
const headElem = document.querySelector("head");
headElem.appendChild(styleElem);

function drawOutput() {
  output.innerHTML = htmlInput.value;
  styleElem.textContent = cssInput.value;
}

reset.addEventListener("click", () => {
  htmlInput.value = htmlCode;
  cssInput.value = cssCode;
  drawOutput();
});

solution.addEventListener("click", () => {
  htmlInput.value = htmlCode;
  cssInput.value = `p {
 font-size: 1.2rem;
 font-family: sans-serif;
 line-height: 1.4;
}

a {
 outline-color: transparent;
 text-decoration: none;
 padding: 2px 1px 0;
}

a:link {
 color: #265301;
}

a:visited {
 color: #437A16;
}

a:focus {
 border-bottom: 1px solid;
 background: #BAE498;
}

a:hover {
 border-bottom: 1px solid;
 background: #CDFEAA;
}

a:active {
 background: #265301;
 color: #CDFEAA;
}`;
  drawOutput();
});

htmlInput.addEventListener("input", drawOutput);
cssInput.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

Including icons on links
------------------------

A common practice is to include icons on links to provide more of an indicator as to what kind of content the link points to. Let's look at a really simple example that adds an icon to external links (links that lead to other sites). Such an icon usually looks like a little arrow pointing out of a box. For this example, we'll use this great example from icons8.com.

Let's look at some HTML and CSS that will give us the effect we want. First, some simple HTML to style:

```html
<p>
  For more information on the weather, visit our <a href="#">weather page</a>,
  look at <a href="https://en.wikipedia.org/">weather on Wikipedia</a>, or check
  out
  <a href="https://www.nationalgeographic.org/topics/resource-library-weather/">
    weather on National Geographic</a>.
</p>
```

Next, the CSS:

```css
body {
  width: 300px;
  margin: 0 auto;
  font-family: sans-serif;
}

p {
  line-height: 1.4;
}

a {
  outline-color: transparent;
  text-decoration: none;
  padding: 2px 1px 0;
}

a:link {
  color: blue;
}

a:visited {
  color: purple;
}

a:focus,
a:hover {
  border-bottom: 1px solid;
}

a:active {
  color: red;
}

a[href^="http"] {
  background: url("external-link-52.png") no-repeat 100% 0;
  background-size: 16px 16px;
  padding-right: 19px;
}
```

So what's going on here? We'll skip over most of the CSS, as it's just the same information you've looked at before. The last rule, however, is interesting: we're inserting a custom background image on external links in a similar manner to how we handled custom bullets on list items in the last article. This time, however, we're using the `background` shorthand instead of the individual properties. We set the path to the image we want to insert, specify `no-repeat` so we only get one copy inserted, and then specify the position as 100% of the way to the right of the text content, and 0 pixels from the top.

We also use `background-size` to specify the size we want the background image to be shown at. It's useful to have a larger icon and then resize it like this as needed for responsive web design purposes. This does, however, only work with IE 9 and later. So if you need to support older browsers, you'll just have to resize the image and insert it as is.

Finally, we set some `padding-right` on the links to make space for the background image to appear in, so we aren't overlapping it with the text.

A final word: how did we select just external links? Well, if you are writing your HTML links properly, you should only be using absolute URLs for external links — it is more efficient to use relative links to link to other parts of your own site (as with the first link). The text "http" should therefore only appear in external links (like the second and third ones), and we can select this with an attribute selector: `a[href^="http"]` selects `<a>` elements, but only if they have an `href` attribute with a value that begins with "http".

So that's it. Try revisiting the active learning section above and trying this new technique out!

**Note:** The `href` values look strange — we've used dummy links here that don't really go anywhere. The reason for this is that if we used real links, you would be able to load an external site in the `<iframe>` the live example is embedded in, thereby losing the example.

**Note:** Don't worry if you are not familiar with backgrounds and responsive web design yet; these are explained in other places.

Styling links as buttons
------------------------

The tools you've explored so far in this article can also be used in other ways. For example, states like hover can be used to style many different elements, not just links — you might want to style the hover state of paragraphs, list items, or other things.

In addition, links are quite commonly styled to look and behave like buttons in certain circumstances. A website navigation menu can be marked up as a set of links, and this can be styled to look like a set of control buttons or tabs that provide the user with access to other parts of the site. Let's explore how.

First, some HTML:

```html
<nav class="container">
  <a href="#">Home</a>
  <a href="#">Pizza</a>
  <a href="#">Music</a>
  <a href="#">Wombats</a>
  <a href="#">Finland</a>
</nav>
```

And now our CSS:

```css
body,
html {
  margin: 0;
  font-family: sans-serif;
}

.container {
  display: flex;
  gap: 0.625%;
}

a {
  flex: 1;
  text-decoration: none;
  outline-color: transparent;
  text-align: center;
  line-height: 3;
  color: black;
}

a:link,
a:visited,
a:focus {
  background: palegoldenrod;
  color: black;
}

a:hover {
  background: orange;
}

a:active {
  background: darkred;
  color: white;
}
```

This gives us the following result:

The HTML defines a `<nav>` element with a `"container"` class. The `<nav>` contains our links.

The CSS includes the styling for the container and the links it contains.

* The second rule says:
    + The container is a flexbox. The items it contains — the links, in this case — will be *flex items*.
    + The gap between the flex items will be `0.625%` of the container's width.
* The third rule styles the links:
    + The first declaration, `flex: 1`, means that the widths of the items will be adjusted so they use all the available space in the container.
    + Next, we turn off the default `text-decoration` and `outline` — we don't want those spoiling our look.
    + The last three declarations are to center the text inside each link, set the `line-height` to 3 to give the buttons some height (which also has the advantage of centering the text vertically), and set the text color to black.
Summary
-------

We hope this article has provided you with all you'll need to know about links — for now! The final article in our Styling text module details how to use custom fonts on your websites (or web fonts, as they are better known).

* Previous
* Overview: Styling text
* Next


Fundamental text and font styling - Learn web development

Fundamental text and font styling
=================================

* Overview: Styling text
* Next

In this article we'll start you on your journey towards mastering text styling with CSS. Here we'll go through all the basic fundamentals of text/font styling in detail, including setting font weight, family and style, font shorthand, text alignment and other effects, and line and letter spacing.

|  |  |
| --- | --- |
| Prerequisites: |
 HTML basics (study
 Introduction to HTML), CSS basics (study
 Introduction to CSS).
  |
| Objective: |
 To learn the fundamental properties and techniques needed to style text
 on web pages.
  |

What is involved in styling text in CSS?
----------------------------------------

Text inside an element is laid out inside the element's content box. It starts at the top left of the content area (or the top right, in the case of RTL language content), and flows towards the end of the line. Once it reaches the end, it goes down to the next line and flows to the end again. This pattern repeats until all the content has been placed in the box. Text content effectively behaves like a series of inline elements, being laid out on lines adjacent to one another, and not creating line breaks until the end of the line is reached, or unless you force a line break manually using the `<br>` element.

**Note:** If the above paragraph leaves you feeling confused, then no matter — go back and review our Box model article to brush up on the box model theory before carrying on.

The CSS properties used to style text generally fall into two categories, which we'll look at separately in this article:

* **Font styles**: Properties that affect a text's font, e.g., which font gets applied, its size, and whether it's bold, italic, etc.
* **Text layout styles**: Properties that affect the spacing and other layout features of the text, allowing manipulation of, for example, the space between lines and letters, and how the text is aligned within the content box.

**Note:** Bear in mind that the text inside an element is all affected as one single entity. You can't select and style subsections of text unless you wrap them in an appropriate element (such as a `<span>` or `<strong>`), or use a text-specific pseudo-element like ::first-letter (selects the first letter of an element's text), ::first-line (selects the first line of an element's text), or ::selection (selects the text currently highlighted by the cursor).

Fonts
-----

Let's move straight on to look at properties for styling fonts. In this example, we'll apply some CSS properties to the following HTML sample:

```html
<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

You can find the finished example on GitHub (see also the source code).

### Color

The `color` property sets the color of the foreground content of the selected elements, which is usually the text, but can also include a couple of other things, such as an underline or overline placed on text using the `text-decoration` property.

`color` can accept any CSS color unit, for example:

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

This will cause the paragraphs to become red, rather than the standard browser default of black, like so:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

### Font families

To set a different font for your text, you use the `font-family` property — this allows you to specify a font (or list of fonts) for the browser to apply to the selected elements. The browser will only apply a font if it is available on the machine the website is being accessed on; if not, it will just use a browser default font. A simple example looks like so:

```css
p {
  font-family: Arial;
}
```

This would make all paragraphs on a page adopt the arial font, which is found on any computer.

#### Web safe fonts

Speaking of font availability, there are only a certain number of fonts that are generally available across all systems and can therefore be used without much worry. These are the so-called **web safe fonts**.

Most of the time, as web developers we want to have more specific control over the fonts used to display our text content. The problem is to find a way to know which font is available on the computer used to see our web pages. There is no way to know this in every case, but the web safe fonts are known to be available on nearly all instances of the most used operating systems (Windows, macOS, the most common Linux distributions, Android, and iOS).

The list of actual web safe fonts will change as operating systems evolve, but it's reasonable to consider the following fonts web safe, at least for now (many of them have been popularized thanks to the Microsoft *Core fonts for the Web* initiative in the late 90s and early 2000s):

| Name | Generic type | Notes |
| --- | --- | --- |
| Arial | sans-serif |
 It's often considered best practice to also add *Helvetica* as a
 preferred alternative to *Arial* as, although their font faces
 are almost identical, *Helvetica* is considered to have a nicer
 shape, even if *Arial* is more broadly available.
  |
| Courier New | monospace |
 Some OSes have an alternative (possibly older) version of the
 *Courier New* font called *Courier*. It's considered best
 practice to use both with *Courier New* as the preferred
 alternative.
  |
| Georgia | serif |  |
| Times New Roman | serif |
 Some OSes have an alternative (possibly older) version of the
 *Times New Roman* font called *Times*. It's considered
 best practice to use both with *Times New Roman* as the preferred
 alternative.
  |
| Trebuchet MS | sans-serif |
 You should be careful with using this font — it isn't widely available
 on mobile OSes.
  |
| Verdana | sans-serif |  |

**Note:** Among various resources, the cssfontstack.com website maintains a list of web safe fonts available on Windows and macOS operating systems, which can help you make your decision about what you consider safe for your usage.

**Note:** There is a way to download a custom font along with a webpage, to allow you to customize your font usage in any way you want: **web fonts**. This is a little bit more complex, and we will discuss it in a separate article later on in the module.

#### Default fonts

CSS defines five generic names for fonts: `serif`, `sans-serif`, `monospace`, `cursive`, and `fantasy`. These are very generic and the exact font face used from these generic names can vary between each browser and each operating system that they are displayed on. It represents a *worst case scenario* where the browser will try its best to provide a font that looks appropriate. `serif`, `sans-serif`, and `monospace` are quite predictable and should provide something reasonable. On the other hand, `cursive` and `fantasy` are less predictable and we recommend using them very carefully, testing as you go.

The five names are defined as follows:

| Term | Definition | Example |
| --- | --- | --- |
| `serif` |
 Fonts that have serifs (the flourishes and other small details you see
 at the ends of the strokes in some typefaces).
  |
```
My big red elephant
```
```

body {
  font-family: serif;
}
```
 |
| `sans-serif` | Fonts that don't have serifs. |
```
My big red elephant
```
```

body {
  font-family: sans-serif;
}
```
 |
| `monospace` |
 Fonts where every character has the same width, typically used in code
 listings.
  |
```
My big red elephant
```
```

body {
  font-family: monospace;
}
```
 |
| `cursive` |
 Fonts that are intended to emulate handwriting, with flowing, connected
 strokes.
  |
```
My big red elephant
```
```

body {
  font-family: cursive;
}
```
 |
| `fantasy` | Fonts that are intended to be decorative. |
```
My big red elephant
```
```

body {
  font-family: fantasy;
}
```
 |

#### Font stacks

Since you can't guarantee the availability of the fonts you want to use on your webpages (even a web font *could* fail for some reason), you can supply a **font stack** so that the browser has multiple fonts it can choose from. This involves a `font-family` value consisting of multiple font names separated by commas, e.g.,

```css
p {
  font-family: "Trebuchet MS", Verdana, sans-serif;
}
```

In such a case, the browser starts at the beginning of the list and looks to see if that font is available on the machine. If it is, it applies that font to the selected elements. If not, it moves on to the next font, and so on.

It is a good idea to provide a suitable generic font name at the end of the stack so that if none of the listed fonts are available, the browser can at least provide something approximately suitable. To emphasize this point, paragraphs are given the browser's default serif font if no other option is available — which is usually Times New Roman — this is no good for a sans-serif font!

**Note:** While you can use font family names that contain a space, such as `Trebuchet MS`, without quoting the name, to avoid mistakes in escaping, it is recommended to quote font family names that contain white space, digits, or punctuation characters other than hyphens.

**Warning:** Any font family name which could be misinterpreted as a generic family name or a CSS-wide keyword must be quoted. While the font-family names can be included as a `<custom-ident>` or a `<string>`, font family names that happen to be the same as a CSS-wide property value, like `initial`, or `inherit`, or CSS have the same name as one to the generic font family names, like `sans-serif` or `fantasy`, must be included as a quoted string. Otherwise, the font family name will be interpreted as being the equivalent CSS keyword or generic family name. When used as keywords, the generic font family names —`serif`, `sans-serif`, `monospace`, `cursive`, and `fantasy` — and the global CSS keywords MUST NOT be quoted, as strings are not interpreted as CSS keywords.

#### A font-family example

Let's add to our previous example, giving the paragraphs a sans-serif font:

```css
p {
  color: red;
  font-family: Helvetica, Arial, sans-serif;
}
```

This gives us the following result:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

### Font size

In our previous module's CSS values and units article, we reviewed length and size units. Font size (set with the `font-size` property) can take values measured in most of these units (and others, such as percentages); however, the most common units you'll use to size text are:

* `px` (pixels): The number of pixels high you want the text to be. This is an absolute unit — it results in the same final computed value for the font on the page in pretty much any situation.
* `em`s: 1 `em` is equal to the font size set on the parent element of the current element we are styling (more specifically, the width of a capital letter M contained inside the parent element). This can become tricky to work out if you have a lot of nested elements with different font sizes set, but it is doable, as you'll see below. Why bother? It is quite natural once you get used to it, and you can use `em` to size everything, not just text. You can have an entire website sized using `em`, which makes maintenance easy.
* `rem`s: These work just like `em`, except that 1 `rem` is equal to the font size set on the root element of the document (i.e. `<html>`), not the parent element. This makes doing the maths to work out your font sizes much easier, although if you want to support really old browsers, you might struggle — `rem` is not supported in Internet Explorer 8 and below.

The `font-size` of an element is inherited from that element's parent element. This all starts with the root element of the entire document — `<html>` — the standard `font-size` of which is set to `16px` across browsers. Any paragraph (or another element that doesn't have a different size set by the browser) inside the root element will have a final size of `16px`. Other elements may have different default sizes. For example, an h1 element has a size of `2em` set by default, so it will have a final size of `32px`.

Things become more tricky when you start altering the font size of nested elements. For example, if you had an `<article>` element in your page, and set its `font-size` to 1.5 `em` (which would compute to 24 `px` final size), and then wanted the paragraphs inside the `<article>` elements to have a computed font size of 20 `px`, what `em` value would you use?

```html
<!-- document base font-size is 16px -->
<article>
  <!-- If my font-size is 1.5em -->
  <p>My paragraph</p>
  <!-- How do I compute to 20px font-size? -->
</article>
```

You would need to set its `em` value to 20/24, or 0.83333333 `em`. The maths can be complicated, so you need to be careful about how you style things. It is best to use `rem` where you can to keep things simple, and avoid setting the `font-size` of container elements where possible.

### Font style, font weight, text transform, and text decoration

CSS provides four common properties to alter the visual weight/emphasis of text:

* `font-style`: Used to turn italic text on or off. Possible values are as follows (you'll rarely use this, unless you want to turn some italic styling off for some reason):
    + `normal`: Sets the text to the normal font (turns existing italics off).
    + `italic`: Sets the text to use the italic version of the font, if available; if not, it will simulate italics with oblique instead.
    + `oblique`: Sets the text to use a simulated version of an italic font, created by slanting the normal version.
* `font-weight`: Sets how bold the text is. This has many values available in case you have many font variants available (such as *-light*, *-normal*, *-bold*, *-extrabold*, *-black*, etc.), but realistically you'll rarely use any of them except for `normal` and `bold`:
    + `normal`, `bold`: Normal and bold font weight.
    + `lighter`, `bolder`: Sets the current element's boldness to be one step lighter or heavier than its parent element's boldness.
    + `100` – `900`: Numeric boldness values that provide finer grained control than the above keywords, if needed.
* `text-transform`: Allows you to set your font to be transformed. Values include:
    + `none`: Prevents any transformation.
    + `uppercase`: Transforms all text to capitals.
    + `lowercase`: Transforms all text to lower case.
    + `capitalize`: Transforms all words to have the first letter capitalized.
    + `full-width`: Transforms all glyphs to be written inside a fixed-width square, similar to a monospace font, allowing aligning of, e.g., Latin characters along with Asian language glyphs (like Chinese, Japanese, Korean).
* `text-decoration`: Sets/unsets text decorations on fonts (you'll mainly use this to unset the default underline on links when styling them). Available values are:
    + `none`: Unsets any text decorations already present.
    + `underline`: Underlines the text.
    + `overline`: Gives the text an overline.
    + `line-through`: Puts a strikethrough over the text.You should note that `text-decoration` can accept multiple values at once if you want to add multiple decorations simultaneously, for example, `text-decoration: underline overline`. Also note that `text-decoration` is a shorthand property for `text-decoration-line`, `text-decoration-style`, and `text-decoration-color`. You can use combinations of these property values to create interesting effects, for example: `text-decoration: line-through red wavy`.

Let's look at adding a couple of these properties to our example:

Our new result is like so:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

```css
html {
  font-size: 10px;
}

h1 {
  font-size: 5rem;
  text-transform: capitalize;
}

h1 + p {
  font-weight: bold;
}

p {
  font-size: 1.5rem;
  color: red;
  font-family: Helvetica, Arial, sans-serif;
}
```

### Text drop shadows

You can apply drop shadows to your text using the `text-shadow` property. This takes up to four values, as shown in the example below:

```css
text-shadow: 4px 4px 5px red;
```

The four properties are as follows:

1. The horizontal offset of the shadow from the original text — this can take most available CSS length and size units, but you'll most commonly use `px`; positive values move the shadow right, and negative values left. This value has to be included.
2. The vertical offset of the shadow from the original text. This behaves similarly to the horizontal offset, except that it moves the shadow up/down, not left/right. This value has to be included.
3. The blur radius: a higher value means the shadow is dispersed more widely. If this value is not included, it defaults to 0, which means no blur. This can take most available CSS length and size units.
4. The base color of the shadow, which can take any CSS color unit. If not included, it defaults to `currentcolor`, i.e. the shadow's color is taken from the element's `color` property.

#### Multiple shadows

You can apply multiple shadows to the same text by including multiple shadow values separated by commas, for example:

```css
h1 {
  text-shadow:
    1px 1px 1px red,
    2px 2px 1px red;
}
```

If we applied this to the h1 element in our Tommy The Cat example, we'd end up with this:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

```
html {
  font-size: 10px;
}

h1 {
  font-size: 5rem;
  text-transform: capitalize;
}

h1 + p {
  font-weight: bold;
}

p {
  font-size: 1.5rem;
  color: red;
  font-family: Helvetica, Arial, sans-serif;
}
```

**Note:** You can see more interesting examples of `text-shadow` usage in the Sitepoint article Moonlighting with CSS text-shadow.

Text layout
-----------

With basic font properties out of the way, let's have a look at properties we can use to affect text layout.

### Text alignment

The `text-align` property is used to control how text is aligned within its containing content box. The available values are listed below. They work in pretty much the same way as they do in a regular word processor application:

* `left`: Left-justifies the text.
* `right`: Right-justifies the text.
* `center`: Centers the text.
* `justify`: Makes the text spread out, varying the gaps in between the words so that all lines of text are the same width. You need to use this carefully — it can look terrible, especially when applied to a paragraph with lots of long words in it. If you are going to use this, you should also think about using something else along with it, such as `hyphens`, to break some of the longer words across lines.

If we applied `text-align: center;` to the h1 in our example, we'd end up with this:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

```css
html {
  font-size: 10px;
}

h1 {
  font-size: 5rem;
  text-transform: capitalize;
  text-shadow:
    1px 1px 1px red,
    2px 2px 1px red;
  text-align: center;
}

h1 + p {
  font-weight: bold;
}

p {
  font-size: 1.5rem;
  color: red;
  font-family: Helvetica, Arial, sans-serif;
}
```

### Line height

The `line-height` property sets the height of each line of text. This property can not only take most length and size units, but can also take a unitless value, which acts as a multiplier and is generally considered the best option. With a unitless value, the `font-size` gets multiplied and results in the `line-height`. Body text generally looks nicer and is easier to read when the lines are spaced apart. The recommended line height is around 1.5 – 2 (double spaced). To set our lines of text to 1.6 times the height of the font, we'd use:

```css
p {
  line-height: 1.6;
}
```

Applying this to the `<p>` elements in our example would give us this result:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

```css
html {
  font-size: 10px;
}

h1 {
  font-size: 5rem;
  text-transform: capitalize;
  text-shadow:
    1px 1px 1px red,
    2px 2px 1px red;
  text-align: center;
}

h1 + p {
  font-weight: bold;
}

p {
  font-size: 1.5rem;
  color: red;
  font-family: Helvetica, Arial, sans-serif;
  line-height: 1.6;
}
```

### Letter and word spacing

The `letter-spacing` and `word-spacing` properties allow you to set the spacing between letters and words in your text. You won't use these very often, but might find a use for them to obtain a specific look, or to improve the legibility of a particularly dense font. They can take most length and size units.

To illustrate, we could apply some word- and letter-spacing to the first line of each `<p>` element in our HTML sample with:

```css
p::first-line {
  letter-spacing: 4px;
  word-spacing: 4px;
}
```

This renders our HTML as:
```

<h1>Tommy the cat</h1>

<p>Well I remember it as though it were a meal ago…</p>

<p>
  Said Tommy the Cat as he reeled back to clear whatever foreign matter may have
  nestled its way into his mighty throat. Many a fat alley rat had met its
  demise while staring point blank down the cavernous barrel of this awesome
  prowling machine. Truly a wonder of nature this urban predator — Tommy the cat
  had many a story to tell. But it was a rare occasion such as this that he did.
</p>
```

```css
html {
  font-size: 10px;
}

h1 {
  font-size: 5rem;
  text-transform: capitalize;
  text-shadow:
    1px 1px 1px red,
    2px 2px 1px red;
  text-align: center;
  letter-spacing: 2px;
}

h1 + p {
  font-weight: bold;
}

p {
  font-size: 1.5rem;
  color: red;
  font-family: Helvetica, Arial, sans-serif;
  line-height: 1.6;
  letter-spacing: 1px;
}
```

### Other properties worth looking at

The above properties give you an idea of how to start styling text on a webpage, but there are many more properties you could use. We just wanted to cover the most important ones here. Once you've become used to using the above, you should also explore the following:

Font styles:

* `font-variant`: Switch between small caps and normal font alternatives.
* `font-kerning`: Switch font kerning options on and off.
* `font-feature-settings`: Switch various OpenType font features on and off.
* `font-variant-alternates`: Control the use of alternate glyphs for a given font-face.
* `font-variant-caps`: Control the use of alternate capital glyphs.
* `font-variant-east-asian`: Control the usage of alternate glyphs for East Asian scripts, like Japanese and Chinese.
* `font-variant-ligatures`: Control which ligatures and contextual forms are used in text.
* `font-variant-numeric`: Control the usage of alternate glyphs for numbers, fractions, and ordinal markers.
* `font-variant-position`: Control the usage of alternate glyphs of smaller sizes positioned as superscript or subscript.
* `font-size-adjust`: Adjust the visual size of the font independently of its actual font size.
* `font-stretch`: Switch between possible alternative stretched versions of a given font.
* `text-underline-position`: Specify the position of underlines set using the `text-decoration-line` property `underline` value.
* `text-rendering`: Try to perform some text rendering optimization.

Text layout styles:

* `text-indent`: Specify how much horizontal space should be left before the beginning of the first line of the text content.
* `text-overflow`: Define how overflowed content that is not displayed is signaled to users.
* `white-space`: Define how whitespace and associated line breaks inside the element are handled.
* `word-break`: Specify whether to break lines within words.
* `direction`: Define the text direction. (This depends on the language and usually it's better to let HTML handle that part as it is tied to the text content.)
* `hyphens`: Switch on and off hyphenation for supported languages.
* `line-break`: Relax or strengthen line breaking for Asian languages.
* `text-align-last`: Define how the last line of a block or a line, right before a forced line break, is aligned.
* `text-orientation`: Define the orientation of the text in a line.
* `overflow-wrap`: Specify whether or not the browser may break lines within words in order to prevent overflow.
* `writing-mode`: Define whether lines of text are laid out horizontally or vertically and the direction in which subsequent lines flow.
Font shorthand
--------------

Many font properties can also be set through the shorthand property `font`. These are written in the following order: `font-style`, `font-variant`, `font-weight`, `font-stretch`, `font-size`, `line-height`, and `font-family`.

Among all those properties, only `font-size` and `font-family` are required when using the `font` shorthand property.

A forward slash has to be put in between the `font-size` and `line-height` properties.

A full example would look like this:

```css
font:
  italic normal bold normal 3em/1.5 Helvetica,
  Arial,
  sans-serif;
```

Active learning: Playing with styling text
------------------------------------------

In this active learning session we don't have any specific exercises for you to do. We'd just like you to have a good play with some font/text layout properties. See for yourself what you can come up with! You can either do this using offline HTML/CSS files, or enter your code into the live editable example below.

If you make a mistake, you can always reset it using the *Reset* button.
```

<div
 class="body-wrapper"
 style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;">
  <h2>HTML Input</h2>
  <textarea
 id="code"
 class="html-input"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">
<p>Some sample text for your delight</p>
  </textarea>

  <h2>CSS Input</h2>
  <textarea
 id="code"
 class="css-input"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;">
p {

}
  </textarea>

  <h2>Output</h2>
  <div
 class="output"
 style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"></div>
  <div class="controls">
    <input
 id="reset"
 type="button"
 value="Reset"
 style="margin: 10px 10px 0 0;" />
  </div>
</div>
```

```
const htmlInput = document.querySelector(".html-input");
const cssInput = document.querySelector(".css-input");
const reset = document.getElementById("reset");
let htmlCode = htmlInput.value;
let cssCode = cssInput.value;
const output = document.querySelector(".output");

const styleElem = document.createElement("style");
const headElem = document.querySelector("head");
headElem.appendChild(styleElem);

function drawOutput() {
  output.innerHTML = htmlInput.value;
  styleElem.textContent = cssInput.value;
}

reset.addEventListener("click", () => {
  htmlInput.value = htmlCode;
  cssInput.value = cssCode;
  drawOutput();
});

htmlInput.addEventListener("input", drawOutput);
cssInput.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

Summary
-------

We hope you enjoyed playing with text in this article! The next article will provide you with all you need to know about styling HTML lists.

* Overview: Styling text
* Next


CSS selectors - Learn web development

CSS selectors
=============

* Overview: Building blocks
* Next

In CSS, selectors are used to target the HTML elements on our web pages that we want to style. There are a wide variety of CSS selectors available, allowing for fine-grained precision when selecting elements to style. In this article and its sub-articles we'll run through the different types in great detail, seeing how they work.

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

What is a selector?
-------------------

A CSS selector is the first part of a CSS Rule. It is a pattern of elements and other terms that tell the browser which HTML elements should be selected to have the CSS property values inside the rule applied to them. The element or elements which are selected by the selector are referred to as the *subject of the selector*.

![Some code with the h1 highlighted.](/en-US/docs/Learn/CSS/Building_blocks/Selectors/selector.png)

In other articles you may have met some different selectors, and learned that there are selectors that target the document in different ways — for example by selecting an element such as `h1`, or a class such as `.special`.

In CSS, selectors are defined in the CSS Selectors specification; like any other part of CSS they need to have support in browsers for them to work. The majority of selectors that you will come across are defined in the Level 3 Selectors specification and Level 4 Selectors specification, which are both mature specifications, therefore you will find excellent browser support for these selectors.

Selector lists
--------------

If you have more than one thing which uses the same CSS then the individual selectors can be combined into a *selector list* so that the rule is applied to all of the individual selectors. For example, if I have the same CSS for an `h1` and also a class of `.special`, I could write this as two separate rules.

```css
h1 {
  color: blue;
}

.special {
  color: blue;
}
```

I could also combine these into a selector list, by adding a comma between them.

```css
h1, .special {
  color: blue;
}
```

White space is valid before or after the comma. You may also find the selectors more readable if each is on a new line.

```css
h1,
.special {
  color: blue;
}
```

In the live example below try combining the two selectors which have identical declarations. The visual display should be the same after combining them.

When you group selectors in this way, if any selector is syntactically invalid, the whole rule will be ignored.

In the following example, the invalid class selector rule will be ignored, whereas the `h1` would still be styled.

```css
h1 {
  color: blue;
}

..special {
  color: blue;
}
```

When combined however, neither the `h1` nor the class will be styled as the entire rule is deemed invalid.

```css
h1, ..special {
  color: blue;
}
```

Types of selectors
------------------

There are a few different groupings of selectors, and knowing which type of selector you might need will help you to find the right tool for the job. In this article's subarticles we will look at the different groups of selectors in more detail.

### Type, class, and ID selectors

Type selectors target an HTML element such as an `<h1>`:

```css
h1 {
}
```

Class selectors target an element that has a specific value for its `class` attribute:

```css
.box {
}
```

ID selectors target an element that has a specific value for its `id` attribute:

```css
#unique {
}
```

### Attribute selectors

This group of selectors gives you different ways to select elements based on the presence of a certain attribute on an element:

```css
a[title] {
}
```

Or even make a selection based on the presence of an attribute with a particular value:

```css
a[href="https://example.com"]
{
}
```

### Pseudo-classes and pseudo-elements

This group of selectors includes pseudo-classes, which style certain states of an element. The `:hover` pseudo-class for example selects an element only when it is being hovered over by the mouse pointer:

```css
a:hover {
}
```

It also includes pseudo-elements, which select a certain part of an element rather than the element itself. For example, `::first-line` always selects the first line of text inside an element (a `<p>` in the below case), acting as if a `<span>` was wrapped around the first formatted line and then selected.

```css
p::first-line {
}
```

### Combinators

The final group of selectors combine other selectors in order to target elements within our documents. The following, for example, selects paragraphs that are direct children of `<article>` elements using the child combinator (`>`):

```css
article > p {
}
```

Summary
-------

In this article we've introduced CSS selectors, which enable you to target particular HTML elements. Next, we'll take a closer look at type, class, and ID selectors.

For a complete list of selectors, see our CSS selectors reference.

* Overview: Building blocks
* Next


Test your skills: Writing modes and logical properties - Learn web development

Test your skills: Writing modes and logical properties
======================================================

The aim of this skill test is to assess whether you understand how to handle different text directions using writing modes and logical properties 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, the box is displayed with a horizontal writing mode. Can you add a line of CSS to change it so it uses a vertical writing mode with right to left text?

Your final result should look like the image below:

![A box with a vertical writing mode](/en-US/docs/Learn/CSS/Building_blocks/Writing_Modes_Tasks/mdn-writing-modes1.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, we want you to use logical properties to replace `width` and `height` in order to maintain the aspect ratio of the box as it is turned vertically.

Your final result should look like the image below:

![Two boxes one horizontal the other vertical](/en-US/docs/Learn/CSS/Building_blocks/Writing_Modes_Tasks/mdn-writing-modes2.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, we want you to use logical versions of the margin, border, and padding properties so that the edges of the box relate to the text rather than following top, left, bottom and right.

Your final result should look like the image below:

![Two boxes one horizontal one vertical with different margin, border and padding](/en-US/docs/Learn/CSS/Building_blocks/Writing_Modes_Tasks/mdn-writing-modes3.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.


A cool-looking box - Learn web development

A cool-looking box
==================

* Previous
* Overview: Building blocks

In this assessment, you'll get some more practice in creating cool-looking boxes by trying to create an eye-catching box.

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

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

To get this assessment started, you should:

* Make local copies of the starting HTML and CSS — save them as `index.html` and `style.css` in a new directory.

 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
-------------

Your task is to create a cool, fancy box and explore the fun we can have with CSS.

### General tasks

* Apply the CSS to the HTML.
### Styling the box

We'd like you to style the provided `<div>`, giving it the following:

* A reasonable width for a large box, say around 200 pixels.
* A reasonable height for a large box, centering the text vertically in the process.
* Center the box horizontally.
* Center the text within the box.
* A slight increase in font size, to around 17-18 pixel computed style. Use rems. Write a comment about how you worked out the value.
* A base color for the design. Give the box this color as its background color.
* A contrasting color for the text and a black text shadow.
* A fairly subtle border radius.
* A 1-pixel solid border with a color similar to the base color, but a slightly darker shade.
* A linear semi-transparent black gradient that goes toward the bottom right corner. Make it completely transparent at the start, grading to around 0.2 opacity by 30% along, and remaining at the same color until the end.
* Multiple box shadows. Give it one standard box shadow to make the box look slightly raised off the page. The other two should be inset box shadows — a semi-transparent white shadow near the top left and a semi-transparent black shadow near the bottom right — to add to the nice raised 3D look of the box.
Hints and tips
--------------

* Use the W3C CSS Validator to catch and fix mistakes in your CSS.
Example
-------

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

![A big red box with rounded corners. White text with drop shadow reads 'this is a cool box'.](/en-US/docs/Learn/CSS/Building_blocks/A_cool_looking_box/fancy-box2.png)

* Previous
* Overview: Building blocks


Images, media, and form elements - Learn web development

Images, media, and form elements
================================

* Previous
* Overview: Building blocks
* Next

In this lesson we will take a look at how certain special elements are treated in CSS. Images, other media, and form elements behave a little differently from regular boxes in terms of your ability to style them with CSS. Understanding what is and isn't possible can save some frustration, and this lesson will highlight some of the main things that you need to know.

|  |  |
| --- | --- |
| 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 way that some elements behave unusually when styled
 with CSS.
  |

Replaced elements
-----------------

Images and video are described as **replaced elements**. This means that CSS cannot affect the internal layout of these elements — only their position on the page amongst other elements. As we will see however, there are various things that CSS can do with an image.

Certain replaced elements, such as images and video, are also described as having an **aspect ratio**. This means that it has a size in both the horizontal (x) and vertical (y) dimensions, and will be displayed using the intrinsic dimensions of the file by default.

Sizing images
-------------

As you already know from following these lessons, everything in CSS generates a box. If you place an image inside a box that is smaller or larger than the intrinsic dimensions of the image file in either direction, it will either appear smaller than the box, or overflow the box. You need to make a decision about what happens with the overflow.

In the example below we have two boxes, both 200 pixels in size:

* One contains an image which is smaller than 200 pixels — it is smaller than the box and doesn't stretch to fill it.
* The other is larger than 200 pixels and overflows the box.

So what can we do about the overflowing issue?

As we learned in our previous lesson, a common technique is to make the `max-width` of an image 100%. This will enable the image to become smaller in size than the box but not larger. This technique will also work with other replaced elements such as `<video>`s, or `<iframe>`s.

**Try adding `max-width: 100%` to the `<img>` element in the example above. You will see that the smaller image remains unchanged, but the larger one becomes smaller to fit into the box.**

You can make other choices about images inside containers. For example, you may want to size an image so it completely covers a box.

The `object-fit` property can help you here. When using `object-fit` the replaced element can be sized to fit a box in a variety of ways.

Below we have used the value `cover`, which sizes the image down, maintaining the aspect ratio so that it neatly fills the box. As the aspect ratio is maintained, some parts of the image will be cropped by the box.

If we use `contain` as a value, the image will be scaled down until it is small enough to fit inside the box. This will result in "letterboxing" if it is not the same aspect ratio as the box.

You could also try the value of `fill`, which will fill the box but not maintain the aspect ratio.

Replaced elements in layout
---------------------------

When using various CSS layout techniques on replaced elements, you may well find that they behave slightly differently from other elements. For example, in a flex or grid layout, elements are stretched by default to fill the entire area. Images will not stretch, and instead will be aligned to the start of the grid area or flex container.

You can see this happening in the example below where we have a two column, two row grid container, which has four items in it. All of the `<div>` elements have a background color and stretch to fill the row and column. The image, however, does not stretch.

If you are following these lessons in order then you may not have looked at layout yet. Just keep in mind that replaced elements, when they become part of a grid or flex layout, have different default behaviors, essentially to avoid them being stretched strangely by the layout.

To force the image to stretch to fill the grid cell it is in, you'd have to do something like the following:

```css
img {
  width: 100%;
  height: 100%;
}
```

This would, however, stretch the image, so it's probably not what you'd want to do.

Form elements
-------------

Form elements can be a tricky issue when it comes to styling with CSS. The Web Forms module contains detailed guides to the trickier aspects of styling these, which I will not fully reproduce here. There are, however, a few key basics worth highlighting in this section.

Many form controls are added to your page by way of the `<input>` element — this defines simple form fields such as text inputs, through to more complex fields such as color and date pickers. There are some additional elements, such as `<textarea>` for multiline text input, and also elements used to contain and label parts of forms such as `<fieldset>` and `<legend>`.

HTML also contains attributes that enable web developers to indicate which fields are required, and even the type of content that needs to be entered. If the user enters something unexpected, or leaves a required field blank, the browser can show an error message. Different browsers vary with one another in how much styling and customization they allow for such items.

### Styling text input elements

Elements that allow for text input, such as `<input type="text">`, and the more specific `<input type="email">`, and the `<textarea>` element are quite easy to style and tend to behave just like other boxes on your page. The default styling of these elements will differ, however, based on the operating system and browser that your user visits the site with.

In the example below we have styled some text inputs using CSS — you can see that things such as borders, margins and padding all apply as you would expect. We are using attribute selectors to target the different input types. Try changing how this form looks by adjusting the borders, adding background colors to the fields, and changing fonts and padding.

**Warning:** You should take care when changing the styling of form elements to make sure it is still obvious to the user they are form elements. You could create a form input with no borders and background that is almost indistinguishable from the content around it, but this would make it very hard to recognize and fill in.

As explained in the lessons on styling web forms, many of the more complex input types are rendered by the operating system and are inaccessible to styling. You should, therefore, always assume that forms are going to look quite different for different visitors and test complex forms in a number of browsers.

### Inheritance and form elements

In some browsers, form elements do not inherit font styling by default. Therefore, if you want to be sure that your form fields use the font defined on the body, or on a parent element, you should add this rule to your CSS.

```css
button,
input,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
}
```

### Form elements and box-sizing

Across browsers, form elements use different box sizing rules for different widgets. You learned about the `box-sizing` property in our box model lesson and you can use this knowledge when styling forms to ensure a consistent experience when setting widths and heights on form elements.

For consistency, it is a good idea to set margins and padding to `0` on all elements, then add these back in when styling particular controls:

```css
button,
input,
select,
textarea {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
```

### Other useful settings

In addition to the rules mentioned above, you should also set `overflow: auto` on `<textarea>`s to stop IE showing a scrollbar when there is no need for one:

```css
textarea {
  overflow: auto;
}
```

### Putting it all together into a "reset"

As a final step, we can wrap up the various properties discussed above into the following "form reset" to provide a consistent base to work from. This includes all the items mentioned in the last three sections:

```css
button,
input,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

textarea {
  overflow: auto;
}
```

**Note:** Normalizing stylesheets are used by many developers to create a set of baseline styles to use on all projects. Typically these do similar things to those described above, making sure that anything different across browsers is set to a consistent default before you do your own work on the CSS. They are not as important as they once were, as browsers are typically more consistent than in the past. However if you want to take a look at one example, check out Normalize.css, which is a very popular stylesheet used as a base by many projects.

For further information on styling forms, take a look at the two articles in the HTML section of these guides.

* Styling web forms
* Advanced form styling
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: Images and form elements.

Summary
-------

This lesson has highlighted some of the differences you will encounter when working with images, media, and other unusual elements in CSS.

In the next article, we'll learn how to style HTML tables.

* Previous
* Overview: Building blocks
* Next


Test your skills: Backgrounds and borders - Learn web development

Test your skills: Backgrounds and borders
=========================================

The aim of this skill test is to assess whether you understand backgrounds and borders of boxes 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, we want you to add a background, border, and some simple styling to a page header:

1. Give the box a 5px black solid border, with rounded corners of 10px.
2. Add a background image (use the URL `balloons.jpg`) and size it so that it covers the box.
3. Give the `<h2>` a semi-transparent black background color, and make the text white.

Your final result should look like the image below:

![Images shows a box with a photograph background, rounded border and white text on a semi-transparent black background.](/en-US/docs/Learn/CSS/Building_blocks/Test_your_skills_backgrounds_and_borders/backgrounds-task1.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, we want you to add background images, a border, and some other styling to a decorative box:

* Give the box a 5px lightblue border and round the top left corner 20px and the bottom right corner 40px.
* The heading uses the `star.png` image as a background image, with a single centered star on the left and a repeating pattern of stars on the right.
* Make sure that the heading text does not overlay the image, and that it is centered — you will need to use techniques learned in previous lessons to achieve this.

Your final result should look like the image below:

![Images shows a box with a blue border rounded at the top left and bottom right corners. On the left of the text is a single star, on the right 3 stars.](/en-US/docs/Learn/CSS/Building_blocks/Test_your_skills_backgrounds_and_borders/backgrounds-task2.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.


Test your skills: The Cascade - Learn web development

Test your skills: The Cascade
=============================

The aim of this skill test is to assess whether you understand universal property values for controlling inheritance 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, we want you to use one of the special values we looked at in the controlling inheritance section. To write a declaration in a new rule that will reset the background color back to white, without using an actual color value.

Your final result should look like the image below:

![Barely visible yellow links on a white background.](/en-US/docs/Learn/CSS/Building_blocks/Cascade_tasks/mdn-cascade.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, we want you to make your changes by leveraging the order of cascade layers section. Edit an existing declaration, without touching the lightgreen declaration, using the cascade layer order to make the links rebeccapurple.

Your final result should look like the image below:

![Barely visible yellow links on a white background.](/en-US/docs/Learn/CSS/Building_blocks/Cascade_tasks/mdn-cascade.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.