CSS for JavaScript Developers Render Logic 2

To understand CSS, we need to understand its systems. In this module, we dive deep into positioned layout to understand how containing blocks and stacking contexts work. We'll also learn about managing overflow and visibility.

M2 rendering logic 2

在 module1 學的,都是 flow layout module2 開始學習 positioned layout (relative, absolute, fixed, sticky )

當 DOM 透過 position 被指定成 positioned layout 時候,也同時擁有:

  • top
  • left
  • right
  • bottom 這些屬性可以調整。

relative

根據自己本身原本位置爲參考點,做移動。

absolute

  • Absolutely-positioned elements are adjusted based on their container . 根據本身外面一層 parent 爲參考點,做移動。

  • 前提是(非常重要),外層必須是 『 Positioned layout 』(所以static 管不到 absolute 的 child )Absolute elements can only be contained by other elements using Positioned layout. This is a really important point, and a really common source of confusion.

if you set position: absolute, but don’t give it an anchor by setting top / left / right / bottom

If we don’t give our absolute element an anchor, it sits in its default in-flow position. I think of it as “inheriting” its default position from Flow layout.

effect on layout

  • When we set something to be position: absolute, we pull it out of flow. When the browser is laying out elements, it effectively pretends that absolutely-positioned elements don’t exist. They’re “incorporeal”. like a ghost.

  • 使用情境:Being able to take elements out-of-flow is super handy. Any time you want an element to be “floating above” the content, like a tooltip or a dropdown or a modal, absolute positioning is your friend.

parent 尺寸不會受到影響

Absolutely-positioned element 不會把 parent 撐開。 parent 尺寸原本多少就是多少。 Remember, absolute elements are like a ghost, they don’t really exist.

Absolute 定位是以 parent 的 border 爲基準,不管 padding 的。

The way to think about this: padding is used in Flow layout calculations, and absolute elements are taken out-of-flow. Those rules don’t apply.

Absolute 置中技巧非常實用!!!!!!!!!!!!

  • 上下左右置中
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

.box {
  position: absolute;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;
  width: 100px;
  height: 100px;
  margin: auto;
}
  • 自動拉伸,並置中(不要指定 width height )
1
2
3
4
5
6
7
8

.box {
      position: absolute;
      left: 5rem;
      right: 5rem;
      top: 30%;
      bottom: 30%;
    }
  • 左右自動拉伸,box 根據 content 有多少來決定高度,使用 top 調整 y 軸位置(不要指定 width height )
1
2
3
4
5
6
7

.box {
      position: absolute;
      left: 5rem;
      right: 5rem;
      top: 50%;
    }

即使現在有了 (Flexbox and Grid), 這個技巧 Josh 還是常常使用。 I still use this trick a ton! It’s especially useful for prominent bits of UI, things like modals or drawers or dialog boxes.

Containing Blocks

diagram showing the containing block

stacking contexts 超重要沒聽過的觀念

什麼是 stacking context

The stacking context is a three-dimensional conceptualization of HTML elements along an imaginary z-axis relative to the user, who is assumed to be facing the viewport or the webpage.

基礎觀念

  • As a general rule, positioned elements will always render on top of non-positioned ones.
  • We can think of it as a two-stage process:
  • first, all of the non-positioned elements are rendered (everything using Flow, Flexbox, Grid…).
  • Next, all of the positioned elements are rendered on top (relative, absolute, fixed, sticky). 所以 relative, absolute, fixed, sticky 會疊在上層,不管 DOM 的順序如何

重疊時候誰在上方誰在下方?

  • 在上方的權重
    • 先比較 position 的種類:positioned elements > non-positioned elements
    • 如果position 的種類相同,再看在 DOM 的順序。

z-index only works with positioned elements ( can also be used with flex/grid children; we’ll learn more about that later! )

  • z-index will have no effect on an element being rendered in Flow layout.

如何建立一個 stacking contexts

有以下許多方式:

  • 使用 positioned-layout ,而且增加 z-index 屬性

  • Setting opacity to a value less than 1

  • Setting position to fixed or sticky (No z-index needed for these values!)

  • Applying a mix-blend-mode other than normal

  • Adding a z-index to a child inside a display: flex or display: grid container

  • Using transform, filter, clip-path, or perspective

  • Explicitly creating a context with isolation: isolate

If you’re curious, you can see the full list of how stacking contexts are created on MDN.

工具 CSS Stacking Context Inspecto

I want to introduce a super nifty tool first: CSS Stacking Context Inspector

This is a free Chrome/Firefox extension which answers a few critical questions about any individual element:

  • Which stacking context does this element belong to?
  • Does it create a stacking context of its own?
  • If it uses the z-index property, is it having any effect? If not, why not?
  • Where does it sit relative to other elements in the same stacking context?

managing z-index

The isolation property isolation: isolate;

What The Heck, z-index??

The isolation property does precisely 1 thing: creates a stacking context.It has the same effect of flattening all of the child elements, but it does so without requiring that we also set a z-index on the parent. It’s the lightest-touch way to create a stacking context.

Ever since discovering the isolation property,

I’ve been using it a ton. Whenever a child within a component applies a z-index value, I add isolation: isolate to the component’s parent element.

This guarantees that we won’t see weird “slip-in-between” bugs, like the one we saw with the sticky header. But it doesn’t contribute at all to z-index inflation, or force me to pick a value.

the Flexbox algorithm uses the z-index property in the same way that the Positioned layout algorithm does. z-index doesn’t work in Flow layout, but it does in Flexbox (as well as Grid).

Fixed Positioning

Fixed position is a close cousin to absolute positioning. Many of the tips and tricks we learned for absolute positioning will work here as well: for example, a fixed element can be centered on the screen using the same party trick. This is perfect for overlays like modals:

Incompatibility with certain CSS properties 父層有些屬性會破壞 fixed 效果

像是 transform, filter… Fixed Positioning • Josh W Comeau’s Course Platform

Overflow

  • Hidden overflow is a necessary ingredient for truncating text with an ellipsis (…).
  • We can hide overflow for artistic purposes, on decorative elements

Scroll Containers

In CSS, there are certain “hidden mechanisms”, devices and concepts that exist within the language, but are totally invisible to most developers. If we want to truly understand how CSS works, we have to learn about these mechanisms.

I like to think of scroll containers like the TARDIS from the British sci-fi show Dr. Who: It’s a regular-sized telephone ship from the outside, but a large spaceship inside

summarize:

  • When we use overflow: scroll, overflow: auto, or overflow: hidden, we create a scroll container. This is true whether we set the property on the X axis, the Y axis, or both.
  • A scroll container is like a portal to a pocket dimension. When an element is contained by a scroll container, it’s guaranteed to be stuck inside. It will never overflow beyond the 4 corners of the scroll container.
  • Setting overflow: hidden creates a scroll container and then hides the scrollbars. It follows all the same rules as overflow: scroll.

Overflow: clip (2022 年的瀏覽器還沒有全部支援)

overflow: clip doesn’t create a scroll container

overflow: clip works quite a bit like overflow: hidden, but it doesn’t create a scroll container. Essentially, it acts the way most developers think overflow: hidden should work. It trims off any overflow, in one or both directions.

Horizontal Overflow

Images are inline by default. Like words in a paragraph, they line-wrap when they can’t all fit. The overflow property on its own won’t help us:

white-space: nowrap;

How can we instruct the container to not linewrap, and instead to leave the content in a single line? The white-space property has got our back: white-space: nowrap; white-space is a property that lets us tweak how words and other inline/inline-block elements wrap. By setting it to nowrap, we instruct the container to never break lines. That, in tandem with overflow: auto, allows us to achieve a horizontally-scrollable element.

Positioned Layout

Overflow and containing blocks

overflow 有作用:父層:relative,子層:absolute overflow 無作用:父層:relative,子層:fixed

in order for a child to “trigger” the overflow, it needs to be contained by it. Setting position: relative is enough to contain an absolute child, but fixed children are only ever contained by the “initial containing block”, a box that exists outside the DOM structure.

Sticky Positioning

Troubleshooting, Sticky 會失效的原因

  • A parent is hiding/managing overflow position: sticky can only stick in one “context”. If it’s within a scroll container, it can only stick within that container.

  • The container isn’t big enough Make sure that your sticky element has room to move within its parent container.

  • The sticky element is stretched When using Flexbox or Grid, it’s possible for a sticky element to be stretched along the cross-axis. This, in effect, makes it so that the element has no space to move in its parent container.

Hidden Content

display: none

Visibility: hidden

當 父層 Visibility: hidden 時,子層可以用 Visibility: visible 讓子層顯示出來,神奇的特性。