CSS is actually far more complex than we imagine, and any one of its points may be able to write a large article, often can see the subtle. So CSS is more than just its name, cascading style sheets, it’s more of a world, an essential part of a web page.

Of course, the diagram above may not be comprehensive enough, but it illustrates the main components of CSS. Let’s briefly talk about some of the hidden attributes that may not be known, so as to leave a general impression and expand your CSS learning system, and then slowly go deep into them.

This article is also the author combined with “CSS World”, “CSS Authority guide” volume, “CSS Revealed”, summed up some usually ignored, or do not understand the place, field code practice in the browser.

This paper is also part of the construction of the front-end knowledge system, see detailsgithub

Text layout

The font declaration is simple, and the font-family declaration is done, but sometimes we see declarations like this:

h1 {
  font-family: -apple-system,system-ui,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,Helvetica Neue,PingFang  SC,Hiragino Sans GB,Microsoft YaHei,Arial; }Copy the code

The font Faimly attribute contains two types of values, the font name and the font family. As the name implies, a font family is a classification of all fonts. In the CSS world, there are generally several font families:

  • Serif font. It refers to strokes with extra decoration at the beginning and end, and strokes of different thickness.
  • Sans serif font. It’s just no decoration, the strokes are the same thickness.
  • Equal width font. The glyph are all of the same width.
  • Cursive font. Mimicking human handwriting.
  • Fantasy font. Other fonts that do not fall into the above four categories.

So statements such as sans-serif and Helvetica refer to families of fonts, the former being serif fonts and the latter sans serif fonts. The message is clear: if the previous font is available, use the previous font, if not, try to use the serif font, if not, continue to look for the font available in the subsequent declaration.

inheritance

General text class attributes can be inherited, such as color, font-size, font-family, etc.

Corresponding to some attributes cannot be inherited, such as border, padding, margin, background, etc. Actually also is easy to understand why these attributes cannot be inherited, because once these properties can be inherited, so will affect the whole layout, for example, we add a border on the parent element, but its child elements, offspring elements are inherited the borders, then had to write more code to eliminate the influence of inheritance and the result is not the intent of the CSS design for sure.

line-height

The first thing to make clear is that the line height applies to either the inline element or the block-level element. We declare that the line height also applies to the content of the block-level box, so it is often possible to see it used like this:

div {
  line-height: 100px;
  font-size: 20px;
}
Copy the code

And here’s what happens:

You might subconsciously assume that line-height works on block-level boxes. In fact, it works on the text in the block-level box. If you remove the text in the div, you will see that the height is less than 100px. The text is also an inline element, which should be clear.

The value of line-height can be a number, percentage, or length, including relative units such as em. Font-size: 16px; font-size: 16px; font-size: 16px; The value of 1.5 is 16 * 1.5 (24px), and the percentage value is calculated in the same way. However, it is important to note that the percentage value is inherited relative to the current font size. So the line height evaluates differently. There’s no problem with numbers, it’s always computed relative to numbers.

Another common usage is to center the text vertically:

div {
  line-height: 100px;
  height: 100px;
}
Copy the code

It doesn’t matter what height is underneath it, so why is it centered vertically? That’s how the line height property works. When line-height is set, the div is set to 100px, but the values are split with 100px-1em and applied to the upper and lower parts of the font, so that the font is evenly divided between the upper and lower parts. To create a vertical center, 1em is the font size. Of course, this is actually approximately vertical, because different fonts occupy different 1em sizes, so there is a bias in the allocation of the top and bottom half of the line height, in addition to the following attributes can affect this situation.

Struts (pillar)

This is an invisible but ubiquitous node in CSS that some books call blank nodes. It is the backbone that supports the existence of inline text. You can see him this way:

.line1 {
  line-height: 0;
  border: 1px solid red;
  font-size: 20px;
}
Copy the code

According to the above learned the knowledge about the line – height, when set to 0, the text line height is 0, then the containing block outside, is also the parent element theory should also is zero, but we found that the height is 2, in fact this is the so-called pillar exists, exists in each inline in the front of the box, remember his first, below will be used.

vertical-align

Vertical-align is quietly “doing a lot” behind the scenes, check out 🌰 :

<div class="line3">
  <img src=".. /.. /.. /assets/css_mindgraphy.png" width="100">
</div>
Copy the code

We can see that there is a gap underneath the image. In this case, vertical-align can be used. Just set vertical-align to a position other than the default.

.line3 > img {
  vertical-align: top;
}
Copy the code

Font-size: 10.0pt; line-height: 0; font-size: 10.0pt; The reason for this is that struts are inline elements, so they also have an invisible text node, like this

The default value of the line height is baseline, and the default value is vertical-align, at the bottom of the image, at the bottom of the text. Font-size: 0; line-height: 0; font-size: 0;

Another way to solve this problem is to change the display value of the image to a block-level element, so that the blank strut does not exist. However, the display value is changed, which may affect the layout, so the above methods are still recommended.

Vertical-align = top, middle, bottom; vertical-align = top, middle, bottom;

Global key of THE CSS

The global keyword is the property value that can be used by all attributes, including inherit, initial, and unset. These keywords are new to CSS3 and are not supported before IE11 and Opera Mini.

Inherit breaks the inheritance limitation. If the property value is set to inherit, the property can be inherited from the parent element.

Initial is used for properties that do not have a pre-defined initial value, such as the color property, which by default depends on the user agent, is a user-set color value, whereas initial turns the font color black.

Unset is the replacement of the preceding two keywords, that is, for inherited attributes, unset represents inherit, while for uninherited attributes, unset represents initial.

A special attribute, all, supports only these three keywords. All indicates all attributes except direction and Unicode-bidi. Therefore, if you set all: inherit, all CSS attributes except the two preceding attributes are inherited from their parent element.

selector

In this case, selectors are what we call selectors. There are many different kinds of selectors, but most of them are the ones listed above. In addition, there are some general selectors that you might ignore in your daily life:

* {
  box-sizing: border-box;
}
Copy the code

It seems simple enough, but abusing it can have unintended consequences. Homepage is he will give all of the elements are added on the corresponding property, even if less than this attribute this element is used, thus causing the certain performance waste, another thing is very easy to overlook is his priority, and we say specifically, universal selector specified degree 0, combined with the above inheritance, inheritance is not characteristic of degrees, So if you use a universal selector and expect the element to inherit from its parent, it won’t work. To see a 🌰

* {
  color: green;
}
div#page {
  color: black;
}
Copy the code
<div id="page">I am small in the CSS world<em>The chicken dish</em>
</div>
Copy the code

Obviously, the final dish chicken is green. So this is also a very confusing area, so the recommendation is to try not to overuse it

The box model

Block-level box

We all know the terms BFC and IFC and their definitions. BFC, for example, is a block-level formatting context that represents the area defined by a block-level box, has its own rendering rules, and boxes do not interact with each other. However, the details of what rendering rules are included and how rendering might be known are vague, and here is also the place that is easy to ignore.

Before we talk about these rendering rules, let’s talk about some concepts that will help us understand the box model better.

  • Block-level frames, such as div, are generated by block-level elements
  • Inline boxes. Similarly, the box generated by an inline element like span is an inline box
  • Inline block-level box, i.edisplay: inline-blockThe box body generated by the inline block-level element of.
  • Accommodate fast, is to contain the current element’s parent box body, in simple terms, block level element’s accommodate block is block level box, row element’s accommodate block is inline box, of course, may also be block level box.

Formatting contexts such as BFC and IFC are defined in the containment block. To start with the horizontal layout, see 🌰 below

.line8 > .child1 {
  width: auto;
  margin-left: 50px;
  margin-right: 20px;
}
.line8 > .child2 {
  width: 300px;
  margin-left: auto;
  margin-right: 150px;
}
.line8 > .child3 {
  width: 300px;
  margin-left: auto;
  margin-right: auto;
}
.line8 > .child4 {
  width: 300px;
  margin-left: auto;
  margin-right: -200px;
}
Copy the code
<div class="line8">
  <span class="child1">CSS world p element 1</span>
  <span class="child1">CSS world p element 1</span>
</div>
<div class="line8">
  <p class="child2">CSS World p element 2</p>
</div>
<div class="line8">
  <p class="child3">CSS world p element 3</p>
</div>
<div class="line8">
  <p class="child4">CSS world p element 3</p>
</div>
Copy the code

The results are as follows:

It is not difficult to see:

  1. In a landscape layout, margins do not fold
  2. Contains aautoValue, subtract the width of the set from the width of the entire containment block. The remaining width is allocated to the setautoBecause margins can be negative, the same rules apply to negative values, as you can see in the fourth div.
  3. Consists of twoautoPhi is dividing the remaining distance into two parts, eachautoIt’s 50/50, which is what we usually usemargin: 0 auto;The principle of centrality is the same.

Need to be aware of when, where some of the properties of block-level box like margin, padding, borders, outline, etc., in addition to distance outside can be set to a negative value, the other is set to a negative value, the browser will ignore the rule, and a wide high auto value only, from the outside, and outline properties can be set up, the other set auto values are invalid, Will be ignored by the browser.

Besides, vertical layout will produce margin folding, and the rule of folding is to take a large value, that is, for two vertical layout elements, margin-bottom and margin-top overlap, so the value of the one with a large value will be taken as the value of the margin after folding. If margin is negative, the value with the largest absolute value is taken as the folded margin, as shown below:

.line8 > .child5 {
  margin-bottom: 10px;
}
.line8 > .child6 {
  margin-top: -50px;
}
Copy the code

The inline boxes

The inline elements are divided into two, a non-permutation element and a permutation element. The two elements are also different in layout.

As usual, here are some concepts:

  • Anonymous text is text that does not contain tags, as we did in the previous example with the span elementx-heightSuch text is anonymous text.
  • Font boxes, as the name suggests, arefont-sizeProperty determines the box the font occupies
  • The line spacing is justline-heightProperty set value minusfont-sizeThe value of is the line height divided by 2 and the upper and lower ends of the font, which is half the line space.
  • The inline box, which is the line space plus the content area, which is the area of the font text, for non-displacement elements in the line, isline-heightThe value set, in the case of the substitution element, is its content area.
  • Line frame, the distance between the highest point of all line frames in a row and the lowest point in a row.

Here’s his schematic

  1. Nonpermutation element

Combining the above concepts, let’s look at 🌰

.line10 {
  border: 1px solid red;
}
.line10 > p {
  font-size: 12px;
  line-height: 12px;
}
.line10 > p::first-line {
  border: 1px solid #ccc;
  background: #f2f2f2;
}
.line10 > p > strong {
  font-size: 24px;
}
Copy the code

Get the following display:

As you can see, the bold text is clearly out of the content area, but even so, the text is still aligned by default. Let’s change the emphasis text and add some styles:

.line10 > p > em {
  padding: 20px;
}
.line10 > p > em {
  border: 20px solid blue;
}
.line10 > p > em {
  margin: 20px;
}
Copy the code

Here, the 1-pixel blue border is used to clearly highlight the area occupied by the text. By comparing these results, we can see that for the inline elements, no matter the padding, border or margin, it has no influence on the line frame at all, that is, the longitudinal distance remains unchanged. Similarly, for negative margin, the size of the line box remains the same, but the left and right sides overlap.

So since the vertical layout of inline elements is not affected by these attributes that make up the box model, what attributes affect the size of the row box? Try this attribute:

.line10 > p > strong {
  font-size: 24px;
  vertical-align: 4px;
}
Copy the code

You can see that the line box is 4px taller than before, which means that vertical-align affects the vertical layout. As mentioned in the previous section, vertical-align calculation is affected by line-height, and for the displacement elements described below, line-height is the content area of the displacement element, so we know that these two main attributes affect the vertical layout of the elements in the row.

  1. Replacement elements

The layout of the replacement elements is different. See 🌰

.line11 {
  font-size: 15px;
  line-height: 18px;
  border: 1px solid red;
}
.line11 > img {
  height: 30px;
  /* margin: 20px; * /
  /* border: 0; * /
  /* padding: 0; * /
}
Copy the code

The result is exactly the same as the image gap example we introduced above. Now let’s look at the effect on layout. Try each of the three properties commented above, and you will find that they all affect the height of the line inner box, which is completely different from non-displacement elements. I’m not going to show you the results, but you can try it out for yourself.

  1. Inline block-level elements

Inline block-level elements are included here because they can be considered substitution elements, so their layout effects are the same. The attributes of the box model all affect up, down, left, and right, so I won’t go into details here.

Cascading rules

What we know about the element hierarchy is that it is set using the Z-index attribute. The larger the attribute value is, the higher the hierarchy is. In other words, the closer it is to us. However, z-index does not work. Many times you can find that no matter how big z-index is set, it does not work. This is what I want to share here.

Once we assign a hierarchy to an element, the first thing that works is that the element must be a static element. This is easier to understand because there is no overlap in normal positioning, so there is no hierarchy problem. If the overlap is created using negative margins, z-index does not work unless non-static positioning is set.

The other thing is that setting the hierarchy creates something called a cascading context, which can be thought of as creating a separate space in which any child elements cannot escape the cascading constraints of their parent. That is, if you have two elements, one with a Z-index of 100 and the other with a z-index of 99, and both elements have child elements, then no matter how large the z-index of the child element of the two elements is, it will not be able to override the other sibling element. This may not be intuitive, but here is 🌰 :

.father1 {
    position: relative;
    z-index: 100;
    border: 1px solid red;
    width: 100px;
    height: 100px;
    background: #fff;
}

.father2 {
    position: relative;
    z-index: 99;
    border: 1px solid blue;
    width: 100px;
    height: 100px;
    background: #fff;
}

.father1>div {
    position: absolute;
    z-index: 2000;
    border: 1px solid green;
}

.father2>div {
    position: absolute;
    top: -20px;
    z-index: 3000;
    border: 1px solid black;
}
Copy the code
<div class="father1">
	<div>I'm a child of two</div>
</div>
<div class="father2">
	<div>I'm a child of two</div>
</div>
Copy the code

If you remove the white background, you can see the children below, which demonstrates the significance of the cascading context.

The end of the

The more YOU learn CSS, the more you will find that what you actually know is fur. We can see a lot of very interesting and practical CSS layout effects on the Internet, but it is far from enough to remember how to write code. If you do not understand the principle, you will still not be able to write it next time. Of course, principle is extremely important for any code. There are a lot of interesting things in this article. I will update this article one by one after I finish sorting them out.