CSS 世界

概述

flow

本书讲解的是 css2.1 流不适用 table

选择器:

  • 类选择器
  • ID 选择器
  • 属性选择器 [title="css-world"]
    • [title="css-world"]
    • [title~="css-world"]
    • [title^="css-world"]
    • [title$="css-world"]
  • 伪类选择器 :first-child
  • 伪元素选择器 :before

关系选择器:

  • 后代选择器 空格连接
  • 相邻后代选择器 >
  • 兄弟选择器 ~
  • 相邻兄弟选择器 +

流、元素、基本尺寸

块级元素(block level element)

div/li/table 都是块级元素 配合 clear 来清除浮动,浮动属性对浮动元素同级块级元素设置,且必须在浮动元素之后(所以使用:after)

/**清除浮动带来的影响*/
.clear:after {
  content: "";
  display: "table";
  clear: both;
}

list-item 放小圆点的盒子叫 ”标记盒子(marker box)“

每个元素由两个盒子(外盒子和内外盒子)组成,按照 display 的不同

  • display:block 实际由外在的 块级盒子和内在的块级容器盒子组成,可以理解成 display:block-block;
  • display:inline-block 实际由外在的内联盒子和内在的块级容器盒子组成

box-model

width

“无宽度准则” width 默认作用在 content-box (容器盒子)上,

width: auto; 有如下四种宽度表现:

  • 充分利用可用空间 fill-available,如 div 默认是 100% 与父容器
  • 收缩与包裹,shrink-to-fit,如 inline-block,会根据 content 的实际宽度来计算,此外,浮动元素和绝对定位元素都具有包裹性
  • 收缩到最小,容易出现在 table 里面,table 的 td。
  • 超出容器限制,如内联元素被设置了 white-space:nowrap 或者很长的英文或者数字就会超出容器的限制

三无原则:

  • 无宽度,块级元素设置了宽度,流动性丢失
  • 无图片
  • 无浮动

格式化宽度仅出现在“绝对定位模型”中,position 为 absolute 或者 fixed的元素。表现为包裹性,宽度由内部尺寸决定。 对于非替换元素,如果同时设置了对立方位的属性,即 left/right 或 top/bottom,则元素 的宽度由祖先元素(postion != static)决定。如 1000(祖先元素 width)-20(right)-20(left)

替换元素的宽度不受 display 水平影响,即使设置了 display:block 宽度也不会变化。 非替换元素,如果 display:block,则具有流动特性,宽度由外部决定。

box-sizing

box-sizing 的作用是改变 width 作用的盒子

  • content-box 默认值
  • padding-box
  • border-box
  • margin-box

作者认为 box-sizing 被发明出来最大的初衷应该是解决替换元素宽度自适应问题。 原因如下:比如 textarea 是替换元素,首先上面说的 display 不能影响他的宽度,还得搭配 width 属性来设置宽度。但是 textarea 是有 border 的,并且自带有 padding,所以需要 width/border/padding 三者共存。如果是默认的 box-sizing:content-box; 设置宽度 100%,其最终的宽度=父元素的宽度+border+padding 的宽度,肯定超出父元素的,所以需要设置为 box-sizing:border-box;

<div>
  <textarea style="width:100%;"></textarea>
</div>

height

height: 100%; 如果父元素 height 为 auto 则会被忽略 生效的两种情况:

  • 设置 html, body 都是 100%,高度相对于 content-box 计算
  • 使用绝对定位,position: absolute; 相对于 padding-box 计算

min-width/max-width 出现在自适应布局或者流体布局中 min-width/min-height 初始值是 auto; max-width/max-height 初始值是 none;

图片设置 height:auto 可以保持原来的比例 max-width 会覆盖 width,即使 width 配置了 !important;

使用 max-height 实现过渡隐藏效果

.element {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s;
}
.element.active {
  max-height: 666px;
}
:checked ~ .element {
  /** checked 旁边的元素*/
}

内联元素 inline-level element

块级负责结构,内联负责内容,所以 height 和 width 只能作用在结构上。 内联指的是外在盒子,所以 inline-block 也是内联元素。

内联盒模型:

  • 内容区域(content area) 大小受字符本身控制,本质是字符盒子 character box
  • 内联盒子(inline box),指的是外在盒子,决定元素是内联还是块级
  • 行框盒子(line box),每一行都是一个行框盒子
  • 包含盒子(containing box),由一个个的行框盒子组成

“幽灵空白节点” 实际上也是一个盒子,不过是个假想盒,名叫“strut”,中文直译为“支柱”,是一个存在于每个“行框盒子”前面,同时具有该元素的字体和行高属性的 0 宽度的内联盒。

Each line box starts with a zero-width inline box with the element’s font and line height properties. We call that imaginary box a “strut

盒尺寸

content 属性

替换元素,根据内容是否可被替换,分为替换元素和非替换元素,如 input/img/video/iframe 等都是替换元素 修改某个属性值,内容可被替换的元素就叫替换元素。 所有替换元素都是内联水平元素,都可一行显示

替换元素的特性:

  1. 内容可替换
  2. 内容外观不受 css 的影响
  3. 有自己的尺寸
  4. 在很多 css 属性上有自己的表现规则,如 vertical-align 替换元素基线是下边缘

替换元素的尺寸计算规则优先级:css 尺寸(通过 css 定义的尺寸)>HTML 尺寸(如 img 的 width 属性)>固有尺寸(不设置任何样式和属性)

  • 替换元素和非替换元素只隔了一个 src 属性 chrome 的所有元素都支持 content 属性
  • 替换元素和非替换元素隔了一个 content 属性,使用 content 属性,我们还可以让普通标签元素变成替换元素。

首屏图片异步加载

img {
  visibility: hidden;
}
img[src] {
  visibility: visible;
}

content 无法设置 img 尺寸,即下面设置无效

div:before {
 content: url(1.jpg);
 display: block;
 width: 200px; height: 200px;
}

content 属性生成的内容都是替换元素

  • content 生成的内容,文本无法选中、复制
  • 不能左右 :empty 伪类
  • content 动态生成值无法获取

content 属性通常用在 :before :after 这两个伪元素中,通常用于下面几个地方:

  • 比如用于清除浮动
  • 用于字符内容生成
    • 如实现 ... 动态加载效果
    • 我们常用的字符图片
  • 图片生成
  • content 开启闭合符号生成,open-quote close-quote 不常用
  • content attr 属性值内容生成
:after {
  content: `\a`;
  white-space: pre;
  /**换行*/
  content: "...\A..\A.";
}

img:after {
  /* 获取 alt attr 的内容放到 content 里面*/
  content: attr(alt);
}

div:before {
  content: url(1png);
}

content 实现计数器,通常用于实现索引值

  • counter-reset 给计数器起名字,顺便告诉计数器从几开始,默认 0
  • counter-increment
  • counter()/counters()
/*计数器名字是 wangxiaoer 默认值是 2*/
.xxx {
  counter-reset: wangxiaoer 2 wangxiaosan 3;
}

css 计数器规则 ”普照规则“。普照源(counter-reset)唯一,每普照(counter-increment)一次,普照源增加一次计数值。

padding

  • 非替换的内联元素,padding、margin 和 border 都不加入行盒高度的计算。利用此特性,可以增加连接或者按钮点击区域大小

    比如 div 里面的 span 设置了 padding,会影响 span 的高度,但是这个 padding 设置的值对 div 的高度是没有影响的。 例子:通过这个特性设置锚点距离页面上部的距离 见 4.2.1

  • 不支持负值,padding 的百分比(水平和垂直方向)是相对于宽度计算的
  • 标签元素内置 padding
  • 图形绘制,padding 配合 background-clip 可以实现三道杠和双层圆点图形效果
.icon-dot {
    display: inline-block;
    width: 100px; height: 100px;
    padding: 10px;
    border: 10px solid;
    border-radius: 50%;
    background-color: currentColor;
    /*只对 content区域着背景色 default border-box*/
    background-clip: content-box;
}

margin

  • 元素尺寸,包括 border 和 padding,offsetWidth 和 offsetHeight,也叫“元素偏移尺寸”,对应 jquery 的 width 和 height
  • 元素内部尺寸,padding box 的尺寸,clientWidth 和 clientHeight,也叫“元素可视尺寸”,对应 jquery 的 innerWidth 和 innerHeight
  • 元素外部尺寸,包含 padding、border、margin,对应 jquery 的 outerWidth(true) 和 outerHeight(true)
  • window.innerHeight 浏览器可视高度,如果有水平滚动条包含滚动条的高度
  • window.innerWidth 浏览器可视宽度,如果有垂直滚动条包含滚动条的宽度

元素尺寸符合充分利用可用空间,则可通过 margin 改变尺寸。

/*获取第三个元素*/
li:nth-of-type(3n) {
  margin-right: 0;
}

特性 chrome 浏览器子元素超过 content box 会触发滚动条显示 只能使用子元素的 margin-bottom 来触发滚动条留白

margin 合并:

  1. 相邻元素 margin 合并
  2. 腹肌和第一个最后一个子元素
  3. 空块级元素 margin 合并

margin 的初始值是 0,margin:auto; 是为块级元素左中右对其设计的,对应 text-align 控制左中右对其,填充规则:

元素水平方向自动填充为父元素宽度,垂直方向无法自动填充,默认为零,所以设置 margin:auto,垂直方向无法居中。margin 触发的条件是,width 或者 height 为 auto 时,具有水平或者垂直方向的自动填充。

  • 一侧定值,一个 auto,auto 为剩余空间大小
  • 两侧 auto,平分剩余空间

正常情况下,margin:auto;只会水平居中,可以利用绝对定位进行垂直水平居中:

.father {
  width: 300px;
  height: 150px;
  position: relative;
}
.son {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 200px;
  height: 100px;
}

margin 无效情形:

  • 内联非替换元素 margin 无效,比如对 span 设置 margin 无效
  • 表格的 tr、td 或者 display:table-cell/table-row 的元素设置 margin 无效
  • margin 合并的时候
  • 绝对定位元素非定位方向 margin 无效

    若想使 margin 生效,必须是和当前元素定位方向一样的 margin 属性才可以,元素默认定位方向是左和上

  • 定高容器的子元素的 margin-bottom 或者宽度定死的子元素的 margin-right 的 定位“失效”
  • 内联特性导致的 margin 无效,比如 img 的 vertical-align 特性基线对齐,导致 margin-top 到一定的范围之后不再继续生效

border

  • border-width 不支持百分比
  • border-style
    • none
    • solid
    • dashed
    • double,由上中下三部分组成,如 1px=0+1+0,是一根实线,5px=2+1+2,上下两根实线,中建一个 1px 的间隙

通过透明 border 来扩大按钮的可点击区域 border 实现三角形和梯形

/*三角形*/
div {
 width: 0;
 border: 10px solid;
 border-color: #f30 transparent transparent;
}

内联元素与流

line-height

x-height

基线就是字母 x 的下边缘,x-height 是字母 x 的高度。vertical-align:middle 不是绝对的垂直水平居中,原因是不同的字体在行内盒子位置不一样,可能会有下沉效果。

ex CSS 中的一个相对单位,指的是小写字母 x 的高度,可以实现 不受字体和字号影响的内联元素的垂直居中对齐效果 内联元素默认是基线对齐的

div 的高度由行高而非文字决定

  1. 非替换的内联元素,可视高度由 line-height 决定

    行距 = line-height - font-size,第一行与最上边的距离是半行距

  2. 替换元素, line-height 不会影响替换元素的高度,line-height 改变的是“幽灵空白节点“的高度,只能决定最小高度。

  3. 块级元素,对块级元素没有作用

    改变 line-height,实际上是通过改变块级元素里面的”行框盒子“占据的高度实现的进而改变了块级元素的高度 line-height 不仅是内联元素高度的基石,而且还是整个 CSS 世界高度体系的基石。

多行文本实现垂直居中效果:

  • 多行文字使用一个标签包裹,然后设置 line-height,相当于设置了幽灵空白节点的高度
  • 设置 vertical-align: middle

line-height 支持的值:

  • 数值,如 line-height:1.5,子元素会继承这个值
  • 百分比值,如 line-height:150%,子元素会继承计算后的值,即 150%*font-size
  • 长度值,如 line-height:20px,同上

每个”行框盒子“前面都有一个宽度为 0 的具有该元素字体和行高属性的”幽灵空白节点“ 行框盒子的高度由高度最高的内联盒子决定的

vertical-align

line-height 起作用的地方 vertical-align 一定起作用,line-height 只能应用于内联元素以及 display 值为 table-cell 的元素 属性值分为 4 类:

  • 线类,如 base-line、top、middle、bottom
    • top、bottom 看边缘和行框盒子
    • baseline/middle 和字符 x 打交道
  • 文本类,如 text-bottom
  • 上标下标类,如 sub、super
  • 数值百分比类,如 20px, 20% 等,百分比是针对 line-height 的计算值计算的

vertical-align 属性只能作用在 display 计算值为 inline、inline-block,inline-table 或 table-cell 的元素上。因此,默认情况下,\、\、 \等内联元素,\、\、\等替换元素,非 HTML 规范的自定义标签元素,以及\单元格,都是支持 vertical-align 属性的,其他块级元素则不支持。浮动和绝对定位会让元素块状化。

.box {
  line-height: 32px;
}
.box > span {
  font-size: 24px;
}
<div class="box">
 <span>文字</span>
</div>

上面这段 css 会导致 box 的实际高度不是 32px,而是 36px,原因是 vertical-align 默认值是 base-line,”幽灵空白节点“ 的 font-size 和 span 都受 line-height:32px 影响,因为文字默认是基线对齐,两个字号不一致,导致彼此会发生上下位移。位移距离足够大,就会超过行高的限制。 解决办法:改变 box 的 font-size 和 span 的字体大小一致,或者设置 span vertical-align: top;

  • vertical-align: text-top; 盒子的顶部和父级内容区域的顶部对齐
  • vertical-align: text-bottom; 盒子的底部和父级内容区域的底部对齐

inline-block 元素如果里面没有内联元素,则基线是 margin 底边缘,否则基线是元素最后一行内联元素的基线。

一个实现的很棒的 modal 框

<div class="container">
 <div class="dialog"></dialog>
</div>

<style>
  .container {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.5);
    text-align: center;
    font-size: 0;
    white-space: nowrap;
    overflow: auto;
  }
  .container:after {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: middle;
  }
  .dialog {
    display: inline-block;
    vertical-align: middle;
    text-align: left;
    font-size: 14px;
    white-space: normal;
  }
</style>

原理: font-size:0,则 x 中心点应该在 container 的上边缘,因为设置了高度 100% 伪元素,导致伪元素和这个中心点对齐,x 中心点下移了半个容器高度,x 中心点就在容器的垂直中心线上。此时设置 dialog 的 vertical:middle,弹框的垂直中心位置和 x 中心点对齐,所以事先了 dialog 的垂直居中,配合 text-align: center 进而实现水平垂直居中

流的破坏与保护

浮动的本质是实现文字环绕效果,有两个特性:

  1. 父级元素塌陷(目的就是为了实现文字环绕效果),父级元素定高可以解决
  2. 行框盒子区域限制,行框盒(每行内联元素在的盒子)高度如果和浮动元素垂直高度有重叠,则行框盒子会跟随浮动元素,而不会有重叠

浮动元素的特性:

  • 包裹性; 将子元素包裹起来,宽高都等于子元素
  • 块状化并格式化上下文;内联元素使用 float 修饰之后,就会变成块级元素
  • 破坏文档流;会使父元素塌陷,
    • 浮动参考,float “浮动参考” 是 “行框盒子”,相对于当前的行框盒子进行定位
    • 浮动锚点,如果没有内联元素行框盒子,则相对于浮动锚点定位,可以理解成一个没有 border、margin、padding 空的内联元素
  • 没有任何 margin 合并;

clear

clear 元素只对块级元素才有效,设置 clear 属性的元素作用对象是自己,而不是针对 float 元素。

clear 属性是让自身不能和前面的浮动元素相邻,对后面的浮动元素不闻不问

.clear:after {
 content: '';
 display: table; // 也可以是'block',或者是'list-item'
 clear: both;
}

上面代码能撑开盒子的原因就是为了不和浮动元素相邻,撑开了盒子

  • clear:both 元素前面是 float 元素,即使当前元素设置 margin-top 为负值也不会和浮动元素同一行显示
  • clear:both 后面元素依然可能发生文字环绕

BFC

block formating context,块级格式化上下文,BFC 内部子元素不会影响外面元素,也不会受外面元素影响。 主要目的是实现更健壮、更智能的自适应布局。

触发 BFC

  • HTML 根元素
  • float 不为 none
  • overflow 为 auto、scroll 或 hidden,普通元素设置了 overflow:hidden 之后,会自动填满容器中除了浮动元素外的剩余空间

    如浮动元素相邻元素会发生文字环绕,此时对相邻元素设置 overflow: hidden 后会自动填充除了浮动元素外的空间

  • display 为 table-cell、table-caption 或 inline-block
  • position 不为 relative 或 static

BFC 特性的自适应布局的优点:

  • 自适应内容由于封闭而健壮,容错性更强。

    设置 clear:both 不与浮动元素一行显示,会导致错位;而设置 overflow:hidden 则会实现自适应布局,与浮动元素同行显示

  • 自适应内容自动填满浮动以外区域,无需关心浮动元素宽度

BFC 自适应元素:

  • overflow:auto/hidden
  • display:inline-block
  • display:table-cell

overflow

裁剪的是 border-box 的内边缘

overflow 属性值

  • visible 默认值
  • hidden 裁剪
  • scroll 滚动条区域一直存在
  • auto,不足滚动没有滚动条,可以滚动时滚动条出现

一些特性总结:

  • html 页面默认的滚动条是作用在 html 标签上的,可以通过 overflow:hidden 来取消滚动
  • 滚动条会占用容器的可用宽度或者高度,滚动条的宽度通常是 17px

实现单行文字溢出 ... 效果,下面三个设置缺一不可

.ell {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

position:absoulte

具有块状化、包裹性、破坏性,absolte 和 float 同时存在,float 无效

“无依赖绝对定位”:没有设置 left/top/right/bottom 属性值的绝对定位,有如下特性:

  • 相对性,是相对于当前位置进行计算

    虽然 position:absolute 会导致内联元素块状化,但是内联元素并不会导致换行。 我理解作用的顺序是,先按正常位置渲染出 div/span,然后 position:absolute 开始起作用,根据 margin 等配置调整位置,但是整个过程结束之后不占据实际的 css 空间

  • 不占据空间,不占用 css 流的尺寸空间

    absolute 虽然会导致当前元素块状化,但是作用在 span 上,并不会导致换行,原因是它不占据空间。 比如用来实现图表左上角的 TOP1 提示、导航右上方的图标提示、实现登录页面 里面的必填图标和错误提示的布局、下拉列表

absolute 和 text-align 相互作用原理:

行内元素有 “幽灵空白节点作用”,如 text-align:center 会导致该节点在行中建,然后 absolute 元素才开始起作用,导致跟随该节点

absolute 和 overflow:

如果 overflow 不是定位元素,同时绝对定位元素和 overflow 容器之间也没有定位元素,则 overflow 无法对 absolute 元素进行剪裁。

absolute 和 clip:

clip 要起作用,position 必须是 absolute 或者 fixed

.clip {
 position: absolute;
 clip: rect(0 0 0 0);
}

使用 clip 进行剪裁的元素其clientWidth 和 clientHeight 包括样式计算的宽高都还是原来的大小 clip 隐藏仅仅是决定了哪部分是可见的,非可见部分无法响应点击事件等;然后,虽然视觉上隐藏,但是元素的尺寸依然是原本的尺寸

absolute 流动性: 当 absolute 遇到 left/top/right/bottom 属性的时候,absolute 元素才真正变成绝对定位元素 普通元素流体特性只有一个方向,默认是水平方向,但是绝对定位元素可以让垂直方向和水平方向同时保持流动性

/* 上下左右留白 30px */
.box {
 position: absolute;
 left: 0; right: 0; top: 0; bottom: 0;
 margin: 30px;
}

absolute 和 margin:

绝对定位元素的 marg

position:relative

relative 的定位有两大特性:一是相对自身;二是无侵入。

tips

  • 内联状态下,图片底部是有间隙的

results matching ""

    No results matching ""