This paper is based on the Chinese version of CSS 2.1 specification.

Use the browser Chrome 70 for testing.

preface

Some people may say, it is almost 2019 why still read CSS2.1 specification. On the one hand, the latest CSS (Core) specification is CSS2.2 (the following screenshot is from www.w3.org/TR/CSS/), and because CSS2.1 has a Chinese version and is not very different from CSS2.2, Finally, I chose to read CSS2.1 specification for the purpose of laziness.

Remember during the interview, the interviewer said, “Your JavaScript is much better than most people, but your CSS needs work.” After graduation in June this year, I officially became a front-end engineer, and reading THE CSS specification was included in my TODO list this year.

Last week, after a couple of months of piecemeal work, I finished with a slightly more systematic understanding of CSS. In the process of reading, I felt that some small knowledge points which are easy to be ignored by others may be used or interesting by myself. So I took this as the theme, extended it appropriately on this basis, and arranged an article to share with you.

Over a cup of coffee, let’s review some of the things that might not have caught your attention.

Enjoy your reading and please give me your advice.

Keywords, attributes, and identifiers

Keywords and attribute names beginning with – or _ are reserved for vendor specific extensions.

Identifiers in the CSS can contain only the characters [a-za-z0-9], U+00A0 or later in the ISO10646 characters, and hyphens (-) and underscores (_). They cannot start with a digit, two hyphens, or a hyphen following a digit.

This also means that the selector can be in Chinese (though not recommended).

< p style = "max-width: 100%; clear: both; min-height: 1em; } </style> .... <p class="Chinese"> This is the Chinese selector text. </p>Copy the code

At this point, the text inside the

tag will turn red.

@import

The user agent must ignore all @import rules that appear inside a block or after any statement other than @charset and @import rules that cannot be ignored.

This also means that the @import rule must precede all rules except @charset and other @import rules.

@import "subs.css"
h1 { color: blue; }
@import "list.css"
Copy the code

In the above code, the second @import statement is illegal and the parser will ignore this rule.

In addition, the @import rule can add a media query type to indicate that the stylesheet is only introduced if a particular media type is met.

@import "landscape.css" screen and (orientation:landscape)
Copy the code

Coding and @ charset

When a style sheet is embedded in another document, such as a style element or a style attribute in HTML, the style sheet shares the character encoding of the entire document.

If a style sheet is in a separate file, the character encoding of the style sheet is determined in the following order (from highest priority to lowest) :

  1. In the HTTP protocolContent-typeThe fieldcharestparameter
  2. BOM code or@charset
  3. <link charset="">Or other metadata from the linking mechanism
  4. The character set of the stylesheet or document to be introduced
  5. Is assumed to be utf-8

Writers who use the @charset rule must place it at the beginning of the stylesheet, without allowing any characters before it. The user agent must ignore any @charset rule that does not start the stylesheet.

: first – letter pseudo elements

The :first-letter pseudo-element selects the first letter (or number) of the first line (the first formatted line block) of a block, if the line is not preceded by anything else (such as an image or an inline table). The first letter of a table cell or inline-block element cannot be the first letter of its ancestor element.

<style>
.description:first-letter {
    color: white;
}
</style>

<p class="description"> "some text" < / p > < p class ="description">some text</p>
<p class="description"><img src="" />some text</p>
Copy the code

The actual effect is shown as follows:

:before and :after pseudo-elements

The :before and: After pseudo-elements inherit all inheritable attributes from the elements in the document tree to which they are attached. For non-inheritable elements, the initial value is taken.

Example usage:

p { color: red; display: block; }
p:before { content: 'T'; }
Copy the code

In the example above, the :before pseudo-element will appear red. Because the display property is not inheritable, its initial value is inline.

Extension: single and double colons for pseudoelements

The CSS3 draft distinguishes between pseudo-elements and pseudo-classes (CSS-selectors Level 4), with pseudo-classes still starting with a quote and pseudo-elements starting with two quotes. For the :before, :after, :first-line, and :first-letter pseudo-elements that exist in CSS1 and CSS2, the user agent must support both single and double quotation marks. For other newly introduced pseudo-classes, the user agent will not support single quotation marks.

Selectors with cascading

In the selector, the document language element names are case-sensitive depending on the document language, for example in HTML element names are case-insensitive, while in XML element names are case-sensitive.

Cascading order

Stylesheets can come from three different sources: the writer, the user, and the user agent (such as the browser).

To find the value of an element or attribute combination, the user agent must sort by:

  1. Find all the declarations that apply to the element and target attributes under the target media type
  2. Sorted by the importance (@important) rule and source, the priority from low to high is:
    • User Agent declaration
    • User general statement
    • Editor general declaration
    • Important note to the writer
    • User Important Statement
  3. The rules of equal importance and origin are sorted according to the specificity of the selector, the more specific selector will override the general one. Pseudo-elements and pseudo-classes are counted as regular elements and classes, respectively
  4. Finally, sort according to the specified order: if the two statements have the same weight, source, and particularity, the later one takes effect.@importDeclarations in the introduced stylesheet are considered to precede all declarations in the stylesheet itself

Specificity of a Computational selector

The particularity of a selector (A-B-C-D) is calculated according to the following rules (with decreasing weights from A to D) :

  • If the statement comes from astyleProperty instead of a selector style rule, count 1, otherwise 0 (=a)
  • Count the number of ID attributes in the selector (=b)
  • Count the number of other attributes and pseudo-classes in the selector (=c)
  • Count the number of element names and pseudo-elements in the selector (=d)
* {} /*a=0, b=0, c=0, d=0*/
li {} /*a=0, b=0, c=0, d=1*/
.description {} /*a=0, b=0, c=1, d=0*/
*[rel=up] {} /*a=0, b=0, c=1, d=0*/
#element {} /*a=0, b=1, c=0, d=0*/
style="" /*a=1, b=0, c=0, d=0*/
Copy the code

That is, although #p123 selects the same object as [id=p123], the ID selector has a higher specificity than the attribute selector.

supplement

I have read some blogs before, when mentioning the particularity of the cascade, the weight of 1000, 100, 10, 1 is used to describe the above a-B-C-D calculation method. Actually, that’s not accurate. This can be disproved by a simple experiment.

In the following example, we define a div named zero with ten tiers of divs nested inside, the innermost of which is given the id last. If you follow the 10-fold increment algorithm, the particularity of the nested 11-layer class is 110, the particularity of using an ID is 100, and the background is black. If the specificity of the former is 0-0-11-0 and the specificity of the latter is 0-1-0-0 according to the algorithm of A-B-C-D, the background will be red.

By looking at the performance of using eleven classes and one ID, the conclusion can be drawn.

<style>
#last {
    background: red;
}
.zero .one .two .three .four
.five .six .seven .eight
.nine .ten {
    background: black;
    height: 100px;
    width: 100%;
}
</style>
<div class="zero">
    <div class="one">
        <div class="two">
            <div class="three">
                <div class="four">
                    <div class="five">
                        <div class="six">
                            <div class="seven">
                                <div class="eight">
                                    <div class="nine">
                                        <div class="ten" id="last"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
Copy the code

As shown in the figure, the background is red, so the calculation method of 1000, 100, 10 and 1 is not accurate.

However, due to implementation problems, there may be a finite number of classes with higher priorities than one ID. In 2012, Zhang Xinxu shared an article “Interesting: 256 Class selectors can Kill 1 ID selector”. This is mainly because at the time of writing this article some browsers are using 8-bit counters to calculate the number of classes. When the number of classes reaches 256, the weight will be higher than the ID due to carry. Later browsers use counters with higher bits, and it is still theoretically possible to have a boundary value, but it will be harder to reach.

Attr attribute in content

content: attr(X)
Copy the code

The attr(X) function returns a string whose value is the value of the X property of the object selected by the selector. If the object has no X property, an empty string is returned.

Example usage:

p:after { content: "," attr(data-name); }
Copy the code
<p data-name="Thorn">Hello</p>
Copy the code

“Helo, Thorn” will be rendered.

counter

Counters use case-sensitive identifiers. Auto numbering is controlled by the counter-increment and counter-reset properties.

If you have given the same counter counter counter reset or counter increment multiple times, each counter reset or increment is processed in the specified order.

/* The second section omits the reset value and will be set to the default value 0. The section will be reset to 2 first and then to 0 */ h1 {counterreset: Section 2 section; } /* Insert section increment1, section increment2, section increment2 */ h1 {counter-increment: Section 2; }Copy the code

In addition, the counter-reset property follows the cascading rule, so that if two counters are to be reset at the same time, they must be specified at the same time.

h1 { counter-reset: section 0 image 0; } /* This will cascade so that only one counter takes effect */ h1 {counterreset: section 0; } h1 { counter-reset: image 0; }Copy the code

Nested counters and scopes

Counters are self-nested, and if you reset a counter in a descendant or pseudo-element, a new counter instance is automatically created. The scope of a counter starts with the first element in the document that has “counter-reset + this counter” and includes the descendants and subsequent brothers of that element and their descendants, but does not include any elements that are in the scope of a counter of the same name.

<style>
ol {
    counter-reset: section;
    list-style-type: none;
}
li:before {
    counter-increment: section;
    content: "The first" counters(section, ".") "Chapter"; } </style> <ol> <li>item</li> <! -- Chapter 1 --> <li> <! -- chapter 2 --> <ol> <li>item</li> <! --> </ol> </li> <li>item</li> <! -- Chapter 3 --> </ol>Copy the code

The effect is shown in the figure

display:noneThe counter in the element of

An element whose display value is set to None does not increment or reset the counter. Pseudo-elements that cannot be generated do not increment or reset the counter, whereas elements whose visibility is set to hidden do.

The list of

An element with display: list-item generates a main block box for the contents of that element, and possibly a tag box as a visual indication that the element is a list item.

The Background attribute applies only to the main box, and the outer tag box is transparent. (However, if you set list-style position to inside, since the background of the tag box is transparent, the background of the main box will pass through, visually adding a background to both the main box and the tag box.)

background

According to the box model, the background refers to the content, the inner margin, and the background of the border area. Border colors and styles can be set through the border properties, and margins are always transparent.

<style>
.transparent-border {
    border: 10px solid rgba(0, 0, 0, 0);
    color: white;
    background: blue;
}
</style>

<p class="transparent-border"When the border color is set to transparent, the background color will pass through. </p>Copy the code

The background property is not inheritable, but because background-color is originally transparent, the parent box’s background will pass through.

In addition, when both the background-image and background-color properties are set, the image will be rendered above the background color if available. This also means that the background color is visible in the transparent part of the image.

The outline (outline)

Difference between outline and border:

  • outlineOccupies no space, and showing or hiding does not cause rearrangement or overflow
  • outlineIt can’t be a rectangle
  • In all directionsoutlineIt’s the same asborderIn contrast, there is nooutline-topoutline-leftattribute
  • If the element is split into multiple rows, andborderCompared to theoutlineThe start or end of the line box is not disconnected, but always tries to be fully connected.
  • becauseoutlineWithout affecting formatting, it may overlap with other elements on the page

Outline -width accepts the same values as background-width (except hidden).

Outline -style and background-style accept the same values (except hidden).

Outline -color accepts the same values as background-color. In addition, the outline color can be set to Invert to invert the screen pixels (although not all browsers support this property).

The default styles

When the font size is not specified, the header size is slightly thicker than the normal font size, the h4 font size is the same as the normal font size, and the H5 and H6 fonts are slightly smaller than the normal font size.

h1, h2, h3, h4, h5, h6 { font-weight: bolder; } h1 { font-size: 2em; margin: .67em 0; } h2 {font-size: 1.5em; margin: .75em 0; } h3 {font-size: 1.17em; margin: .83em 0; } h4 {margin: 1.12em 0; } h5 { font-size: .83em; Margin: 1.5 em 0; } h6 { font-size: .75em; Margin: 1.67 em 0; }Copy the code