byodian's blog

CSS 深入理解

无宽度和宽度分离原则

对于块状元素,如果 width: auto ,则元素宽度就会自适应占据整个容器。

宽度分离原则:CSS 中的 width 属性不与影响宽度的 padding/border 属性共存。使用包裹元素 width 独占一层标签,paddingbordermargin 利用流动性在内部自适应呈现。

.container {
width: 100px;
}
.item {
margin: 0 20px;
padding: 20px;
border: 1px solid;
}

box-sizing

input, textarea, img, video, object {
box-sizing: border;
}

inline elements vs. block-level elements

non-replaced inline elements vs. replaced inline elements

盒模型

width

width 默认值为 auto 。auto 作为默认值会出现至少四种不同的宽度表现

height

height 不会运用于行内非替换元素,内容区域的高度应该基于字体

height: 100% 无法生效的原因

Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the used height is calculated as if 'auto' was specified. A percentage height on the root element is relative to the initial containing block.

规范指出,如果包含块的高度没有显示指定 (高度由内容决定),并且该元素不是绝对定位,则计算值为 auto。这里,auto 和百分比数值无法计算。

For absolutely positioned elements whose containing block is based on a block-level element, the percentage is calculated with respect to the height of the padding box of that element. This is a change from CSS1, where the percentage was always calculated with respect to the content box of the parent element.

绝对定位元素高度百分数值基于包含块的 padding box 计算,非绝对定位元素基于包含块的 content-box 计算。

height: 100% 生效的方法

绝对定位的宽高比计算是相对于 padding-box 的,而非绝对定位元素则是相对于 content-box 计算。

padding

An element's padding area is the space between its content and its border.

一个元素的内边距是它的内容和边框之间的空间。

内联元素的垂直 padding 同样会影响布局

内联元素的 padding 在垂直方向同样会影响布局,影响视觉效果。只是内联元素没有可视高度和可视宽度的说法(clientHeight 和 clientWidth 永远为 0),视觉上没有改变上下行的间距,给人的的感觉是垂直 padding 没有作用。

我们给内联元素加一个背景或者边框,设置垂直 padding ,就可以看到内联元素的尺寸空间确实受到了影响,但是不会影响其他元素的布局。

a {
padding: 0.5rem 1rem;
background-color: red;
}

垂直 padding 增加内联元素的点击区域

利用垂直 padding 只影响内联元素的视觉效果,不影响其他元素的布局,可以用来增加链接或按钮的点击区域大小。默认情况下,链接的点击区域的高度受 font-size 的字体大小控制,和 line-height 无关

a {
padding: 1rem 0;
}

内联元素垂直方向上的行为完全受 line-heightvertical-align 的影响。

padding 实现自适应的等比例矩形效果

padding 的百分数值相对于包含块的宽度计算。利用这种特性,可以实现等比例缩放的布局效果。

<div class="container" > <img src="#" alt="hero" > </div > .container {
padding: 10% 50%;
position: relative;
}

.container img {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}

padding 与图形绘制

padding 属性和 background-clip 属性配合,可以实现一些图像绘制效果。

/* menu icon*/
.icon-menu {
display: inline-block;
width: 14px;
height: 1px;
padding: 3px 0;
border-top: 1px solid;
border-bottom: 1px solid;
background-color: currentColor;
background-clip: content-box;
}

/* dot icon */
.icon-dot {
display: inline-block;
width: 10px;
height: 10px;
padding: 1px;
border-top: 1px solid;
border-radius: 50%;
background-color: currentColor;
background-clip: content-box;
}

margin

外边距折叠只发生在常规文本流中块级盒子的垂直方向上,不同的具有 BFC 特性的元素之间不会发生折叠。比如:行内盒子、浮动盒子、绝对定位盒子、flex 或者 grid 盒子,这些元素之间不会发生外边距折叠。

顶部和底部外边距对非替换的行内元素无影响。

margin: auto 深入理解

水平填充规则:

<div class="container" > <div class="item" > </div > </div > .container {
width: 200px;
}

.item {
width: 100px;
height: 100px;
margin-right: auto; /* item 左对齐 */
}

margin-left

<div class="container" > <div class="item" > </div > </div > .container {
width: 300px;
}

.item {
width: 100px;
height: 100px;
margin: auto; /* 居中对齐 */
}

margin

margin 属性的 auto 计算控制块级元素的左右对齐,而 text-align 控制行内元素的左右对齐。

margin: auto 无法实现垂直居中的原因

If 'margin-top', or 'margin-bottom' are auto, their used value is 0. — w3.org

margin: auto 实现垂直居中方法

margin 负值

元素的尺寸:border-box 的尺寸,包括 padding 和 border ,原生 DOM API 中写作 offsetWidth 和 offsetHeight

元素的可视(内部)尺寸:padding-box 的尺寸,原生 DOM API 中写作 clientWidth 和 clientHeight

元素的外部尺寸:margin-box 的尺寸,包括 padding 和 border 以及 margin。

元素在充分利用可用空间的状态下,margin 可以改变元素的可视尺寸。

CSS 流体布局下的宽度分离原则

CSS 中的 width 属性不与影响宽度的 padding/border属性共存。这样做的目的是将影响宽度的因素降到最低。

方法:嵌套一层标签,外部父元素设置 width 值,内部子元素设置 padding/border

文本属性

text-align

line-height

设置 inline 元素的高度,常用来设置文本行之间的距离。

vertical-align

垂直对齐的属性值相对于它的父元素。对齐同一包含块中的元素。

::selection

应用样式到用户选定的那一部分文档。支持的属性有:

包含块 - containing blocks

In CSS 2.2, many box positions and sizes are calculated with respect to the edges of a rectangular box called a containing block.

在 CSS 2.2 中,许多的盒子的定位和大小的计算与一个叫做包含块的正方形的盒子有关。

正常流 (Normal flow)

Block formatting contexts

It's the region in which the layout of block boxes occurs and in which floats interact with other elements.

它是块级盒子布局过程产生,也是浮动元素与其他元素交互的区域。

Block formatting contexts are important for the positioning (see float) and clearing (see clear) of floats. The rules for positioning and clearing of floats apply only to things within the same block formatting context. Floats don't affect the layout of the content inside other block formatting contexts and clear only clears past floats in the same block formatting context. Margin collapsing also occurs only between blocks that belong to the same block formatting context.

BFC 对于浮动元素的定位和清除是重要的。浮动元素的定位和清除仅仅应用于同一个 BFC 元素。浮动元素不会影响其他具有 BFC 元素的布局,清除浮动也只应用在同一 BFC 元素中之前浮动的元素。外边距合并也只发生在同一 BFC 元素中。

BFC 特性

触发 BFC 条件

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that ** are not blocked boxes,** and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

举例

浮动元素和 BFC 元素实现自动填充的自适应布局。

<div class="media-container">
<img class="media-picture" src="xx.png" >
<div class="media-body">
<h3>Title</h3>
<p>Description</p>
</div>
</div>
/* .media-container 元素避免高度塌陷, 具有 BFC 特性的元素会包含所有的子元素*/
/* .media-body clear float */
.media-container,
.media-body
{
overflow: hidden;
}

.media-picture {
float: float;
margin-right: 10px;
}

层叠上下文(stacking context)

HTML 元素的一个三维概念,指具有层叠上下文的元素在显示器与用户相对的 z 轴上可以优先显示。

层叠水平(stacking level)

决定了同一层叠上下文中元素在 z 轴上的显示顺序,所有的元素都具有层叠水平,只是层叠水平各有差异。另外, z-index 只能影响定位元素、flex 容器的子元素以及 grid 容器子元素的层叠水平。

层叠上下文特 性

层叠上下文的创建

层叠原则

当元素发生层叠的时候,其覆盖关系遵循两条规则:

  1. 当元素层叠水平和层叠顺序相同的时候,在 DOM 流中处于后面元素会覆盖前面的元素。
  2. 当具有明显的层叠水平标识的时候,如生效的 z-index 属性值,在同一层叠上下文领域,层叠水平值大的会覆盖层叠水平小的元素

层叠顺序

普通元素具有层叠上下文,其层叠顺序就会变高。

层叠顺序依次增大:

  1. 层叠上下文 background/border
  2. z-index
  3. block 块状水平盒子
  4. float 浮动盒子
  5. inline 水平盒子
  6. z-index: auto 可看成 z-index: 0 和不依赖 z-index 的层叠上下文
  7. z-index

float

浮动元素的本质:实现文字环绕效果。

浮动元素的包含块:最近的块级元素

浮动元素与正常流中的内容发生重叠的情况:

clear

clear 属性应用于 block 水平元素

定位

absolute

The absolutely positioned element is positioned relative to its nearest positioned ancestor. If a positioned ancestor doesn't exist, it is positioned relative to the initial containing block, which the containing block of the document's root element.

absolute 是非常独立的 CSS 属性值,其样式和行为表现不依赖任何其他 CSS 属性,就可以完成。

绝对定位的元素默认会待在自己静态定位时的地方,可通过外边距控制偏移位置。

当 absolute 遇到 left/top/right/bottom 属性的时候,absolute 元素才真正变成绝对定位元素。

当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了。此时宽度表现为格式化宽度,其大小自适应于包含块的 padding-box 的宽度。

绝对定位的流体特性

条件:对立方向同时发生定位偏移的时候。

<div class="box" > </div > .box {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}

absolute 水平垂直居中

利用绝对定位的流体特性和 margin: auto 的自动分配特性实现居中。

.box {
width: 200px;
height: 100px;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}

Flexbox

Properties for the flex items

Parent element's properties

CSS grid

fr - a fraction of available space

Grid items property

Grid areas

Overflow

::after & ::before

单位

两条简单的规则:

  1. 如果属性缩放根据它的的 font-size 变化,则使用 em(Size in em if the property scales according to its font-size
  2. 其他的尺寸使用 rem (Size everything else in rem

em

设置浏览器默认字体操作步骤:

  1. Chrome 浏览器:设置 -> 外观 -> 字号
  2. Firefox 浏览器:选项 -> 常规 -> 语言和外观 -> 字体和颜色

参考

REM vs EM – The Great Debate PX, EM or REM Media Queries?