In the last six months, I have not encountered good front-end problems on Zhihu, and this question is in my heart.

Over the course of the past year, students have repeatedly tried and failed to understand CSS rationally.

I tell them CSS has no logic! They didn’t believe it.

This question and answer is a good illustration of my understanding. Here are my answers.

Short answer: because CSS is not orthogonal.

The long answer:

Let me just explain what orthogonal is.

You’ve adjusted the brightness, hue, and saturation of your monitor.

  • “Brightness” is the degree of brightness, and the higher the value, the brighter the screen.
  • “Hue” is color, and you can change red to green by tinting.
  • “Saturation” is the degree of vividness, and the higher the value, the brighter it is.

Orthogonality is when you adjust one of these without affecting the other two.

  • Hue and saturation do not change when you adjust brightness.
  • Brightness and saturation do not change when you adjust hue.
  • Brightness and hue do not change when you adjust saturation.

Orthogonal seems obvious, right.

Imagine the “non-orthogonal” situation: when you adjust the “brightness”, the “hue” and “saturation” change irregularly. If so, you’ll be desperate, because it’s hard to get what you want.

CSS, on the other hand, is not orthogonal.

I take the effect of width on margin-left as an example, assuming the following code:

The width of the.child inside the.parent is 300px. Now I add a margin-left: -10px

The entire.child is shifted 10 pixels to the left

Ok, so we know that margin-left: -10px shifts the element to the left as a whole.

Is it really so?

At this point, the width is removed and the experiment is done again. This is before adding margin-left:

This is after adding margin-left:

Margin-left: -10px doesn’t move the entire element to the left, it just moves the left edge to the left and the right edge doesn’t move.

Now to sum up:

  1. If width is specified, margin-left: 10px will shift the entire element to the left
  2. If width is not specified, margin-left: 10px will only shift the edge to the left.

CSS is particularly non-orthogonal when you look at this:

  1. Why does the presence or absence of width affect margin-left?
  2. Are there any other attributes besides width that affect margin-left? I’m afraid you don’t.

This is the horror of non-orthogonality. You can only know the true law of margin-left if you use all attributes together with it.

And that’s just the effect of two properties, can you imagine three properties affecting each other?

Let me take a second example. We all know that position: Fixed is positioned relative to the viewport.

But this “truth” is influenced by another element… Yeah, I know you’re shocked…

Let’s look at normal conditions first:

To the right of the page is an iframe, and the red.fixed element is positioned relative to the upper left corner of the iframe viewport, as expected.

Next I’ll add a CSS3 property to the.box to change your perception:

Fixed is positioned relative to the parent container after adding a transform.

Who knows, in the future, CSS will add more variables to affect what I already take to be true?

That’s the nasty thing about not being orthogonal.

If you add margin: 0 auto to a fixed width div, you can center it horizontally. If you add margin: 0 auto to a fixed width div, you can center it horizontally.

It can:

But the element must have position: absolute; top: 0; bottom:0; Is vertically centered. That’s not orthogonal.

How do you learn something that’s not orthogonal?

There’s only one way: try.

The more combinations you try, the more you learn about strange phenomena.

There is no other way.

Currently, there are 50 commonly used properties of the CSS. There are 1225 scenarios for the two property combinations, and 19,600 scenarios for the three property combinations. And that’s not even taking into account the interaction between parent and child elements.

Boy, try it while you’re still alive.

So far we know that

  1. Different combinations of attributes have different effects;
  2. [Fixed] New stats affect what you already know
  3. There’s no logic to these rules. You just try them out. This is why CSS is hard to learn.

In my experience, the more rational a person is, the harder it is to understand CSS; The more sensitive the person, the easier it is to understand CSS.

That’s why most backend programmers can learn JS, but not CSS — they’re too rational.

Do you want to learn CSS in the same way you learned programming? Give it up!

You need to learn CSS the same way you learn to draw — draw an egg a thousand times a day in different ways.

So I said in class:

CSS is not a science, CSS is an art.

P.S. the concept of “orthogonal” I learned from the Art of Unix Programming. Focus on the Front end of Hungry Valley — a front end community of love.