CSS for JavaScript Developers M1 Render Logic 1

Flow layout is the "OG" layout algorithm of the web, and it's still used heavily today. In this module, we explore how to best use Flow layout in modern times. We'll also deepen our understanding of common fundamentals like the Box Model.

module1 Render Logic 1

瀏覽器預設樣式:user-agent stylesheet

These styles are part of the user-agent stylesheet. Each browser includes their own stylesheet full of base styles like this.

Inheritance

跟排版相關的屬性,大多會傳下去給內層的 elelment 繼承。 Most of the properties that inherit are typography-related, like color, font-size, text-shadow, and so on. You can find a more-or-less complete list of inheritable properties on SitePoint.

而像是 border 就沒有這樣的特性。

  • 用 JS 呈現其概念:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

class Main {
  color = 'black'
}
class Paragraph extends Main {
  backgroundColor = 'red'
}
class Span extends Paragraph {
}
const s = new Span();
console.log(s.color);
console.log(s.backgroundColor);

Forcing inheritance

預設不會傳下去給內層繼承的屬性,內層 element 可以透過 someProps: inherit 來手動繼承。

CSS also allows you to use the inherit keyword to force inheritance on properties that are not inherited by default. DevTools provide you easy access to all the properties that an element inherits from its ancestors. This can help you in quickly figuring out solutions to common layout related problems.

The Cascade

Similarities with JS merging (很貼切的比喻)

In principle, the cascade algorithm works something like this:

1
2
3
4
5
6
7
8
9

const appliedStyles = {
  ...inheritedStyles,   // 繼承的屬性,權重最小
  ...tagStyles,
  ...classStyles,
  ...idStyles,
  ...inlineStyles,
  ...importantStyles  // important,權重最高
}

In our earlier example, we saw this CSS snippet:

1
2
3
4
5
6
7
p {
  font-weight: bold;
  color: hsl(0deg 0% 10%);
}
.introduction {
  color: violet;
}

This could be written in JavaScript as:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const tagStyles = {
  fontWeight: 'bold',
  color: 'hsl(0deg 0% 10%)',
};
const classStyles = {
  color: 'violet',
}
const appliedStyles = {
  ...tagStyles,
  ...classStyles,
}

過往麻煩的 css 權重問題(specificity),在現代前端框架,被方便的解決了。 we’ll learn how to effectively use modern tooling and methodologies to solve problems for us.

Directions

the important takeaway is that like a real-world document, content is structured along a block axis and an inline axis.(block 上到下;inline 左到右)

  • logical properties
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

.asymmetric-padding {
  padding-top: 20px;
  padding-bottom: 40px;
  padding-left: 60px;
  padding-right: 80px;
}
/* The same thing, but using ✨ logical properties ✨  等同上面寫法*/
.asymmetric-logical-padding {
  padding-block-start: 20px;
  padding-block-end: 40px;
  padding-inline-start: 60px;
  padding-inline-end: 80px;
}

The Box Model(重要)

Box Sizing

The box-sizing CSS property allows us to change the rules for size calculations. The default value (content-box) only takes the inner content into account, but it offers an alternative value: border-box.

  • A new default

Instead of having to remember to swap box-sizing on every layout element, we can set it as the default value for all elements with this handy code snippet:

1
2
3
4
5
6
7
*,
*::before,
*::after {

 box-sizing: border-box;

}

Whenever I start a new project, I copy/paste this snippet into my global styles. I never want to work again in a project without it!

  • 小測驗,滿分通過,爽。

padding

  • 該用什麼單位?
    • Josh Comeau 偏好 px
    • 也可以使用 em
    • 但是不要使用 %

border

border vd. Ourline

The core difference is that outline doesn’t affect layout. Outline is kinda more like box-shadow; it’s a cosmetic effect draped over an element, without nudging it around, or changing its size.

margin

Negative margin

With padding and border, only positive numbers (including 0) are supported. With margin, however, we can drop into the negatives.

水獺橫幅滿版

這個練習值得再複習。 概念:

  • img 外層包一個 element,當成 container 作用
  • 這個 container 使用 Negative margin 的特性,可以突破外層 <div class="card"> 的 padding 限制
  • 因爲 img 的 width 100% 是跟著上一層(container),因此也跟著突破外層 <div class="card"> 的 padding 限制

Flow Layout

Every HTML element will have its layout calculated by a layout algorithm. These are known as “layout modes”, and there are 7 distinct ones.

較少聽過的 layout mode:

We’ll cover several layout modes in this course, including Positioned layout, “Flexible Box” layout (AKA Flexbox), and Grid layout (AKA CSS Grid). For now, though, let’s focus on Flow layout.

CSS Positioned Layout Module Level 3

Flow layout is the default layout mode. All the examples we’ve seen so far are rendered in Flow layout. A plain HTML document, with no CSS applied, uses Flow layout exclusively.

Inline elements don’t want to make a fuss

Inline elements are generally meant to highlight a selection of text.

They don’t want to inconvenience anyone by pushing any boundaries. They’re like polite dinner-party guests who sit exactly where they’re assigned.

You can shift things in the inline direction with margin-left and margin-right, but you can’t change its width or height. And in terms of the block direction, an inline element is where it is, and that’s the end of the story.

Inline 規則的例外 :replaced elements

There are two exceptions to this rule. The first is replaced elements.

A replaced element is one that embeds a “foreign” object. This includes: 以下是 inline 元素

  • <img />

  • <video />

  • <canvas />

These elements are all technically inline, but they’re special: they can affect block layout. You can give them explicit dimensions, or add some margin-top.

How do we reconcile this? I have a trick.

I like to pretend that it’s a foreign object within an inline wrapper.

When you pass it a width or height, you’re applying those properties to the foreign object. The inline wrapper still goes with the flow.

The second exception is the <button> tag. They aren’t quite replaced elements, but they function the same way. They can be given a width/height.

Inline elements have “magic space”

img 外層包一層 divdiv 的高度會高於 img 一點。

因爲: the browser treats inline elements as if they’re typography. img 預設是 inline , 而瀏覽器會把 inline 元素當做文字處理,會刻意留一點下方空間。

  • 解決方式
    • img display 換成 block
    • 外層 div line-height 設成 0

Inline elements can line-wrap

更深入說明一些可能不常用的特性,有空可再看

Block elements don’t share

What if we force it to shrink down to the minimum size required for the letters? We can do this with the special width keyword fit-content

inline-block

作者覺得是奇怪產物。 it’s an element that internally acts like a block element, but externally acts like an inline element. The parent container will treat it as an inline element, since it’s external. But the element itself can be styled like a block.

Inline-block doesn’t line-wrap

Width Algorithms

Block elements have a default width value of auto, not 100%. width: auto works very similar to margin: auto; it’s a hungry value that will grow as much as it’s able to, but no more.

by default, block elements have dynamic sizing. They’re context-aware.

Keyword values

Broadly speaking, there are two kinds of values we can specify for width:

  1. Measurements (100%, 200px, 5rem)
  2. Keywords (auto, fit-content)

an intrinsic value

min-content / max-content / fit-content 根據本身內容多寡決定寬度

width 給的單位: rem % 都是根據上一層的 content 寬度。 we aren’t sizing based on the space made available by the parent, we’re sizing based on the element’s children!

練習:使用其他方式代替 fit-content

Figures and captions

The <figure> HTML element is fairly niche, but super useful. It allows us to display any sort of “non-typical” content: images, videos, code snippets, widgets, etc. It also lets us caption that content with <figcaption>.

Height Algorithms

The default “width” behaviour of a block-level element is to fill all the available width, whereas the default “height” behaviour is to be as small as possible while fitting all of the element’s content; it’s closer to width: min-content than width: auto!

height 屬性 給與 % 是沒作用的。 Have you ever tried to use a percentage-based height, only to discover that it seems to have no effect? In this lesson, we’re going to look at why this happens.

it’s a really important one: width looks up the tree, while height looks down the tree.

An element’s width is calculated based on its parent’s size, but an element’s height is calculated based on its children.

When it comes to height, a parent element will “shrinkwrap” itself around its children, like a pouch of vacuum-sealed food. width 根據父層計算 % height 根據子層計算 %

What about the vh unit?

You may be familiar with the vh unit, a unit designed exactly for this purpose. If you set height: 100vh, your element will inherit its height from the viewport size.

Unfortunately, this unit doesn’t quite work the way we’d often like, because of mobile devices.

In general, I recommend using the html/body height: 100% method described above. It produces a better experience in most cases.

結論:But what about when we want to set a minimum height?

  1. using the html/body height: 100%
  2. 最方便的方式:使用 flexbox。 Specifically, in order to solve this problem, we’d need to use Flexbox.

Margin Collapse

personal space 的概念來解釋,非常好懂!!Margin Collapse • Josh W Comeau’s Course Platform

Rules of Margin Collapse

  • Only vertical margins collapse

  • Margins only collapse in Flow layout

  • Only adjacent elements collapse 只有臨近的兩個元素會 collapse

  • The bigger margin wins

  • Nesting doesn’t prevent collapsing

    • Here’s the takeaway from these three scenarios: Margins must be touching in order for them to collapse.
  • Margins can collapse in the same direction

  • More than two margins can collapse