© Martine Dowden and Michael Dowden 2020
M. Dowden, M. DowdenArchitecting CSShttps://doi.org/10.1007/978-1-4842-5750-0_3

3. Order of Importance

Martine Dowden1  and Michael Dowden1
(1)
Brownsburg, IN, USA
 

As mentioned in Chapter 1, one of the important features of CSS is the ability for the user, browser, and web developer to all exert influence over the final output of the page. The user agent, the author, and the user can all three influence the output of the page. To dictate what property value “wins,” a multistep calculation is performed.

Inheritance

Inheritance is the mechanism by which CSS allows a value set on a parent element (such as <body>) to propagate to its descendants. This helps determine what value is used when no property is declared on an element property. The inherited value is determined by the computed value of a parent or ancestor. If none exists, the initial value, or default set by the browser, is used.

Not all property values are inherited by default.1 Properties that do are generally related to theming such as typography-related properties (font-size, line-height, letter-spacing, etc.). Layout-related properties such as display, border, width, and height are generally not. If there is no declared value on a non-inheritable property, then the initial value is used. See Listings 3-1 and 3-2 and Figure 3-1.
<body>
  <h1>Inheritance</h1>
  <p>Lorem ipsum dolor sit amet, consectetur... </p>
  <img src="image.png" alt="art">
  <table>
    <tr>
      <th>Lorem Ipsum</th>
      <td>Lorem ipsum dolor sit amet, consectetur... </td>
    </tr>
    <tr>
      <th>Pellentesque</th>
      <td>Pellentesque sit amet massa auctor est... </td>
    </tr>
  </table>
  <p>Pellentesque sit amet massa... </p>
</body>
Listing 3-1

Cascading and Inheritance HTML

body {
  color: gray;
  padding: 2rem;
  text-align: justify;
  line-height: 1.5rem;
  font-family: Helvetica, Arial, sans-serif;
  font-weight: lighter;
}
h1 {
  color: slategray;
  font-family: 'Comic Sans MS';
  font-size: 2.5rem;
  letter-spacing: .0625rem;
}
h1 {
  font-family: fantasy;
}
p:first-of-type::first-letter {
  color: gold;
  display: block;
  float: left;
  font-size: 3rem;
  line-height: 0;
  margin: .5rem .5rem 0 0;
}
table {
  border-collapse: collapse;
}
tr {
  color: slategray;
  border-top: solid 1px lightsteelblue;
  border-bottom: solid 1px lightsteelblue;
}
td {
  padding: .5rem 1rem;
}
img {
  margin: 0 0 0 1rem;
  float: right;
  width: 200px;
}
Listing 3-2

Cascading and Inheritance CSS

../images/487079_1_En_3_Chapter/487079_1_En_3_Fig1_HTML.jpg
Figure 3-1

Cascading and Inheritance

The body attribute has a text-align property value of justify. Styles are not set on paragraph attributes; however, the paragraphs are in fact justified. The paragraph text-align value is inherited from the body’s text-align property. Padding however is not inherited, which is why even though the body selector has a padding value of two rems, paragraphs, the image, links, and so on do not also have a 2rem padding value.

One of the main benefits of inheritance is that it prevents the need to write values for the same properties over and over again across different selectors helping with consistency of the styles and maintainability of the code.

In this example the color is also inherited, but the first letter of the first paragraph does not display in gray as set in the body selector, but in gold as set in the p:first-of-type::first-letter selector. The reason the first letter of the first paragraph is gold rather than gray is a question of specificity; p:first-of-type::first-letter is more specific than body.

Global Values

Inherit, unset , and initial are a little different from the rest of the property values available in CSS. These values are available on all properties and have the distinct difference of either resetting a value to default or to that of an ancestor rather than a new value. These values give you explicit control over how a property is inherited.

Examples for inherit , unset, and initial are based on the code found in Listings 3-3 and 3-4.
<body>
  <h1>Exceptions</h1>
  <ol>
    <li>Cursive</li>
    <li>Unset</li>
    <li>Initial</li>
    <li>Inherit</li>
  </ol>
  <p>1 Lorem ipsum dolor sit amet, consectetur... </p>
  <p>2 Pellentesque sit amet massa auctor est... </p>
  <p>3 Duis vitae iaculis risus. Vivamus id egestas... </p>
  <p>4 Mauris vel mi quis lorem laoreet aliquet... </p>
</body>
Listing 3-3

Exceptions HTML

body {
  font-family: sans-serif;
  padding: 10px;
}
p {
  padding: 20px;
  border: dashed 1px gray;
}
p::first-letter {
  display: block;
  float: left;
  font-size: 3rem;
  color: red;
}
p:nth-of-type(2) { padding: unset }
p:nth-of-type(3) { padding: default }
p:nth-of-type(3) { padding: initial }
p:nth-of-type(4) { padding: inherit }
li { font-family: cursive; }
li:nth-of-type(2) { font-family: unset; }
li:nth-of-type(3) { font-family: initial; }
li:nth-of-type(4) { font-family: inherit; }
Listing 3-4

Exceptions CSS

Unset

Unset works differently depending upon the property to which it is being assigned. If the value can be inherited from the parent, it will inherit; otherwise, it will set the property value to initial.

In the case of the list item, since font-family can be inherited, the second list item will have a font-family of sans-serif. The value is inherited from body, it’s parent container (see Figure 3-2).
../images/487079_1_En_3_Chapter/487079_1_En_3_Fig2_HTML.jpg
Figure 3-2

Inherited Unset

Because padding is not inheritable, padding gets set to 0 on the second paragraph tag because the initial padding value on a paragraph tag is 0 (see Figure 3-3).
../images/487079_1_En_3_Chapter/487079_1_En_3_Fig3_HTML.jpg
Figure 3-3

Unset on a Non-inheritable Property

Initial

The initial value for a property may be set by the browser and can vary depending on the user agent. If an initial value is declared in the CSS specification, then initial should return that value. Most modern browsers are consistent but mileage may vary. For example, in Firefox the default value for font-family is serif . Therefore, the third list element font-family value is serif (see Figure 3-4).
../images/487079_1_En_3_Chapter/487079_1_En_3_Fig4_HTML.jpg
Figure 3-4

Initial

Inherit

The property value will equate that of the parent’s property whether the property is by default inherited or not. Padding is not inherited. Even so, when inherit is set on the padding property of the fourth paragraph tag, the paragraph tag takes the value set to its parent <body>. Body has a padding value of 10px; therefore, the paragraph also does. See Figure 3-5.
../images/487079_1_En_3_Chapter/487079_1_En_3_Fig5_HTML.jpg
Figure 3-5

Inherit

As this example shows, we can force inheritance through the use of the inherit property, giving us direct control over the cascade.

Specificity

There is an order of importance given to the various types of selectors, based upon how specificity is calculated. There are four categories of importance summarized in Table 3-1, each of which is an order of magnitude more important than the one below it.
Table 3-1

Selector Ranking

Category

Selectors

A

ID selectors

B

Class selectors, attribute selectors, pseudo classes

C

Type selectors, pseudo elements

0

Universal selector

The specificity of any given selector is calculated as a three-digit number, with the digits A, B, and C, where A, B, and C represent the total number of selectors of their category.2 Several examples are shown in Table 3-2.
Table 3-2

Calculating Specificity

Example Selector

A

B

C

Specificity

*

0

0

0

0

button

0

0

1

1

ul li

0

0

2

2

button:not([type=submit])

0

1

1

1 1

a[href$=".pdf"]::before

0

1

2

1 2

button.outline.bold

0

2

1

2 1

button#submit

1

0

1

1 0 1

Specificity plays an important role in determining which styles will get applied during the cascade.

Inline Styles

Styles applied directly to the element in the HTML such as

<p style="margin-left: 10px">Lorem ipsum am met...</p>

are inline styles. They are the equivalent of adding property values directly in the DOM with the use of JavaScript. Inline styles are given a specificity of [1 0 0 0],3 which is higher than anything possible using normal selectors, as shown in Table 3-2. Inline styles are generally considered bad practice because they ignore inheritance and cascading. There are a few exceptions where they may be unavoidable though, including HTML e-mails.

Precedence

The order in which rules are applied matters. Directly targeted rules will always take precedence over rules which inherited from a parent or ancestor. If two rules with the same level of specificity are applied, the last one in order will be applied. This concept lies at the core of CSS and has since its inception, as indicated by its name “Cascading Style Sheets.”

!important

The !important annotation is well known among CSS practitioners as both a powerful tool and a great liability. It’s sometimes used by web developers to force a style to take effect when nothing else seems to work. But did you know that the purpose of !important is actually to improve accessibility? Because important user declarations always have the highest precedence, it gives the user the final say on which properties and values are set when the page is rendered.

As well as specificity , the source of the rule is also a factor in determining the value used by the element. Table 3-3 shows the order in which rules are applied during cascading, in order from least to most important.
Table 3-3

Order of Cascading4

Order

Origin

Importance

Precedence

1

User Agent

Normal

8

2

User

Normal

7

3

Author

Normal

6

4

Animations

 

5

5

Author

!important

4

6

User

!important

3

7

User Agent

!important

2

8

Transitions

 

1

In cascading, the last item to be applied wins; therefore, transitions will win over user agent !important containing rules over user !important rules and so forth.

Cascading

Cascading represents the way properties and values from a variety of sources, at varying levels of precedence and specificity, come together to determine the final set of styles that will be rendered.

It is important to note that it is properties that are cascaded to elements, not rulesets. The final state of an element may include properties that were declared in many different rulesets.

To calculate the cascade, the following formula is applied:5
  1. 1.

    The declarations with the highest precedence are selected.

     
  2. 2.

    The remaining declarations with the highest specificity are selected.

     
  3. 3.

    When all other factors are equal, the declaration that appears last will be the one that is applied.

     

Value Processing

All of the different sources of property values are used together to determine the final value using the following calculation:6
  1. 1.

    First, all the declared values applied to an element are collected, for each property on each element. There may be 0 or many declared values applied to the element.

     
  2. 2.

    Cascading yields the cascaded value. There is at most one cascaded value per property per element.

     
  3. 3.

    Defaulting yields the specified value . Every element has exactly one specified value per property.

     
  4. 4.

    Resolving value dependencies yields the computed value. Every element has exactly one computed value per property.

     
  5. 5.

    Formatting the document yields the used value. An element only has a used value for a given property if that property applies to the element.

     
  6. 6.

    Finally, the used value is transformed to the actual value based on constraints of the display environment. As with the used value, there may or may not be an actual value for a given property on an element.

     
This calculation from the W3C Specification references a variety of value classifications, which are defined as
  • Declared These are all the values (0many) that match the element and property under review.

  • Cascaded This is the value (01) that is selected after processing the cascade.

  • Specified This is the value of the cascade, if available, or the default value for the property and element. There will always be exactly one (1) specified value for each property and element.

  • Computed The absolute value of the specified value which can then be inherited by child elements.

  • Used This is the final value that the user agent uses for the layout of the document.

  • Actual This is the value that is actually shown on a device, which may be adjusted from the used value due to device or environmental limitations.

The final actual values used for each property on each element are determined by a wide variety of factors external to your project code, including device, user agent or browser, user agent style sheet, and user-provided style sheet.

Summary

In this chapter you have learned the details of how CSS takes rulesets from many different sources and builds a cohesive set of applied styles for the web page. In particular, you’ve learned
  • How HTML inline styles and !important annotations affect cascading

  • How to calculate the specificity for any given selector

  • The way properties are inherited within the DOM tree

In the following chapter, you will learn about the different options CSS provides for building fluid and responsive layouts that can adapt to variations in device and content.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.218.146