day2 CSS深入理解 | 青训营笔记

133 阅读9分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

理解CSS

css三种使用方式

一般使用外链式,在使用框架时可能会写到一起,即嵌入,而内联用得较少,一般对于给定的组件重新设置个别属性时可以用到。

css如何工作

添加样式到DOM树之后形成渲染树,再展示节点

属性选择器

这种选择器见的较少,所以复习一下。

  • 选择不可输入的文本框,设置其样式,使用[属性] 进行选择
<label>用户名:</label>
<input value="zhao" disabled />

<label>密码:</label>
<input value="123456" type="password" />

<style>
  [disabled] {
    background: #eee;
    color: #999;
  }
</style>

  • 也可以根据属性的值来进行选择,以下选中了type属性为password的input标签
<p>
  <label>密码:</label>
  <input type="password" value="123456" />
</p>

<style>
  input[type="password"] {
    border-color: red;
    color: red;
  }
</style>
  • 也可以通过匹配属性的范围来进行选择,使用到了正则表达式。以下选中了href以#开头以及以.jpg结尾的;
<p><a href="#top">回到顶部</a></p>
<p><a href="a.jpg">查看图片</a></p>

<style>
  a[href^="#"] {
    color: #f54767;
    background: 0 center/1em url(https://assets.codepen.io/59477/arrow-up.png) no-repeat;
    padding-left: 1.1em;
  }
 
  a[href$=".jpg"] {
    color: deepskyblue;
    background: 0 center/1em url(https://assets.codepen.io/59477/image3.png) no-repeat;
    padding-left: 1.2em;
  }
</style>

伪类选择器

伪类分为状态性伪类和结构性伪类

  • 状态性伪类,指处于某种状态,对链接来说,:link表示默认状态,其他状态还有访问过、悬停、点击,对于各类元素来说,还有focus状态,比如文本框准备输入时就处在focus状态
<a href="http://example.com">
  example.com
</a>

<label>
  用户名:
  <input type="text">
</label>

<style>
a:link {
  color: black;
}

a:visited {
  color: gray;
}

a:hover {
  color: orange;
}

a:active {
  color: red;
}

:focus {
  outline: 2px solid orange;
}
</style>
  • 结构性伪类,指:last-child :first-child等,选中父级的某些孩子

组合选择

之前没太记住的有兄弟选择器和相邻选择器,注意连写AB表示同时要满足A和B,兄弟选择器 A~B选中在A后且和A同级的B,相邻选择器 A+B紧跟在A后面的B

颜色

除了RGB模型之外,可以使用HSL模式表示颜色,这样对颜色调节变化会更加直观,色相、鲜艳度、亮度

alpha表示不透明度,越高越不透明,直接加在颜色之后就可以,比如#ff00078 rgba(255,0,0,0.47) hsla(0,100%,50%,0.47)

font相关属性

字体族font-family

使用建议:

  • 字体列表最后一定要加一个通用字体族
  • 英文字体写在中文字体之前
<h1>卡尔斯巴德洞窟(Carlsbad Caverns)</h1>
<p>卡尔斯巴德洞窟(Carlsbad Caverns)是美国的
一座国家公园,位于新墨西哥州东南部。游客可以通过天
然入口徒步进入,也可以通过电梯直接到达230米的洞穴
深处。</p>

<style>
  h1 {
    font-family: Optima, Georgia, serif;
  }
  body {
    font-family: Helvetica, sans-serif;
  }
</style>

使用web font:

把字体文件放在服务器上,浏览器会从url找字体来进行渲染,但会对性能可能有影响

<h1>Web fonts are awesome!</h1>

<style>
  @font-face {
    font-family: "Megrim";
    src: url(https://fonts.gstatic.com/s/megrim/v11/46kulbz5WjvLqJZVam_hVUdI1w.woff2) format('woff2');
  }

  h1 {
    font-family: Megrim, Cursive;
  }
</style>

中文也可以使用web font,中文字符较多,所以可以只把用得到的字符裁切出来,保证性能和大小

<style>
  @font-face {
    font-family: f1;
    src: url("//s2.ssl.qhimg.com/static/ff00cb8151eeecd2.woff2") format("woff2");
  }

  @font-face {
    font-family: f2;
    src: url("//s3.ssl.qhimg.com/static/a59a90c9e8f21898.woff2") format("woff2");
  }

  @font-face {
    font-family: f3;
    src: url("//s2.ssl.qhimg.com/static/58324737c4cb53a5.woff2") format("woff2");
  }

</style>

<h1 style="font-family: f1, serif">落霞与孤鹜齐飞,秋水共长天一色。</h1>
<h1 style="font-family: f2, serif">落霞与孤鹜齐飞,秋水共长天一色。</h1>
<h1 style="font-family: f3, serif">落霞与孤鹜齐飞,秋水共长天一色。</h1>

font-size

  • 关键字small、medium、large
  • 长度px、em(相对单位,相对于父元素字体大小的倍数)
  • 百分数:相对于父元素字体大小

font-weight

  • 400-normal
  • 700-bold

不一定所有字体都可以设置很多种字重,有些字体只设置了两种如粗体和非粗体,所以有时候设置100 200 并没有什么区别

line-height

行高是上下字基准线之间的高度,行高使用1.6,指行高是字体自身font-size的1.6倍

简写属性

其中很多可以省略,可以只写size和family

排版相关属性

text-align

left:正常排,换行时留的空白会多一些

justify:中间拉大一些,保持两端对齐(对最后一行不拉大)

CodePen - 青训营/CSS/text-align (cdpn.io)

spacing

letter-spacing:字母之间的间距

word-spacing:单词之间的间距

CodePen - 青训营/CSS/spacing (cdpn.io)

text-indent

设置首行缩进

CodePen - 青训营/CSS/indent (cdpn.io)

white-space

对于空白符的处理,通常情况下html会把多个空格看作一个空格,即合并空格

  • nowrap:强制不换行
  • pre:保留所有空格和换行,和原始代码一样
  • pre-wrap:保留空格,一行内显示不下时,自动换行
  • pre-line:需要合并空格,但保留换行

css调试

深入css

判断使用哪个选择器

选择器的特异度

选择器的特异度用来计算选择器的优先级,特异度(specificity)越高的越优先;

继承

某些属性会自动继承父元素的计算值,一般和字体相关的都可以继承,和盒模型相关的都不能继承

  • 显式继承

可以显式设置inherit,设置所有元素的box-sizing都可以从父级继承,可以如下设置,将html这个容器中所有的box-sizing变成border-box,而一些组件需要设置为content-box,那个some-widget容器中的元素就变为content-box。

  • 初始值

CSS中,每个属性都有一个初始值,比如background-color的初始值为 transparent,margin-left的初始值为0,可以使用initial关键字显式重置为初始值background-color:initial

⭐CSS求值过程解析

筛选能有效匹配到的选择器,叫做声明值,可能有0到多个 → 选出优先级最高的一个属性值,叫做层叠值 → 如果层叠值为空,使用继承或者初始值 → 将相对值或关键字转换为绝对值,称作计算值 → 进一步转换计算值,得到使用值 → 将小数像素值转为整数,或者考虑到其他属性的限制(比如max-width),生成实际值

  • resolving能转换的值,只看css和html就能算出具体值的
  • formatting转换的值,是需要布局后才能知道的值,比如百分比等,要知道父元素的大小才能计算
  • 继承过程中,子元素是继承到父元素的计算值,即如果父元素是1.2em,那子元素继承的不是1.2em,而是父元素通过resolving得到的计算值

布局

布局Layout就是确定内容的大小的位置的算法,一句元素、容器、兄弟节点和内容等信息来计算。

盒模型:

  • 注意height和width设置百分比时,表示相对于容器的content box的大小,容器有指定高度时,百分数才生效。
  • 注意padding设置百分数也是相对于容器宽度。
  • 当四条边框颜色不同时,边角处是这样切分的,将元素宽高设置为0,再把其中的几个边框设为透明,则可以得到各种三角形

  • margin:0 auto 可以实现水平居中
  • margin collapse指在垂直方向上有margin的折叠,两者之间的间距取的是最大的margin设置,在文字排版上会比较方便

box-sizing:border-box

设置box-sizing:border-box 后,指定的宽高是加上了border和padding的大小

css盒模型 - 行级和块级

行级vs块级

display 属性

block :块级盒子 inline :行级盒子 inline-block :本身是行级,可以放在行盒中; 可以设置宽高;作为一个整体不会被拆散成多行(类比一张图,布局时不会被拆散成一半一半) none: 排版时完全被忽略

行级排版上下文

  • Inline Formatting Context (IFC)

  • 只包含行级盒子的容器会创建一个IFC

  • IFC内的排版规则

    • 盒子在一行内水平摆放
    • 一行放不下时,换行显示
    • text-align决定一行内盒子的水平对齐
    • vertical-align 决定一个盒子在行内的垂直对齐
    • 避开浮动(float)元素
  • overflow-wrap: break-word 表示单词显示不下时可以被拆开

块级排版上下文

  • Block Formatting Context (BFC)

  • 某些容器会创建一个BFC

    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow值不是visible的块盒
    • display: flow-root;
  • BFC 内的排版规则

    • 盒子从上到下摆放
    • 垂直margin 合并
    • BFC内盒子的margin不会与外面的含并
    • BFC不会和浮动元素重叠(清除浮动的技巧)
  • 浏览器不允许容器内同时有块级和行级盒子,如果既有块级和行级元素,会分别创建匿名的行级和块级盒子

<span>
  This is a text and
  <div>block</div>
  and other text.
</span>

<style>
  span {
    line-height: 3;
    border: 2px solid red;
    background: coral;
  }

  div {
    line-height: 1.5;
    background: lime;
  }
</style>

Flex Box

Flex理解

它可以控制子级盒子的:

  • 摆放的流向(→←)flex-direction默认为row
  • 摆放顺序
  • 盒子宽度和高度
  • 水平和垂直方向的对齐
  • 是否允许折行

  • 侧轴对齐align-items默认为strech会把子元素高度拉到和容器一样高
  • baseline则是把所有文字的基线对齐

  • 可以单独给子元素设置align-self来调整单个元素的位置

  • 也可以给子元素设置order,就会按order的形式来在现在的流向上依次鼻疽

Flex的Flexibility属性

  • 可以设置子项的弹性: 当容器有剩余空间时,会伸 展;客 容器空间不够时,会收缩
  • flex-grow 有剩余空间时的伸展能力
  • flex-shrink 容器空间不足时收缩的能力
  • flex-basis没有伸展或收缩时的基础长度

flex-grow:容器总宽度刨去定好长度的元素之后剩下的宽度,按flex-grow设定的比例来分配

<div class="container">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</div>

<style>
  .container {
    display: flex;
  }

  .a, .b, .c {
    width: 100px;
  }

  .a {
    flex-grow: 2;
  }

  .b {
    flex-grow: 1;
  }
</style>

flex-shrink:总宽度不够1200,a设置为flex-shrink为0表示不可压缩,所以bc被压缩

<div class="container">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</div>

<style>
  .container {
    display: flex;
  }

  .a, .b, .c {
    width: 400px;
  }

  .a {
    flex-shrink: 0;
  }
</style>

flex对应的设置规则如下,所以flex直接写就相当于flex-grow

Grid布局

和flex类似也是一种布局方法,首先通过俩个图理解,可以说是css最强大的布局工具

划分网格

CodePen - 青训营/CSS/grid-template (cdpn.io)

grid-template-colums设置列的划分,grid-template-rows设置行的划分。

第三个例子中的fr表示fraction,即份数,列设置100px 1fr 1fr,即先占100px,剩下的宽度各占一份

grid line网格线 和 grid area网格区域

先列好网格线,再用网格线编号表示网格区域,比如以上区域被表示为1/1/3/3,使用方法如下所示

CodePen - 青训营/CSS/grid-area (cdpn.io)

  • 可以使用开发者工具查看grid网格线

float浮动流

  • 实现图片环绕文字,回归本来用途,其他布局已经可以通过flex布局来解决了

postion属性

  • static 默认值, 非定位元素
  • relative 相对自身原本位置偏移, 不脱离文档流,其他元素布局时认为它依然在原位置

  • absolute 绝对定位, 相对非 static 祖先元素定位(子绝父相),脱离了常规流

  • fixed 相对于视口进行绝对定位
  • sticky 吸顶效果,元素一开始不在顶部,滚动到顶部时就黏在顶部,直到下一个sticky元素