CSS有什么用?

CSS 整理

CSS 的作用是给 HTML 元素加上样式,同时又可以多个样式层叠,所以叫层叠样式表。

CSS 的内容也是比较复杂的。细节参考 https://www.runoob.com/css/css-tutorial.html https://www.xp.cn/css3/

需要理解不同元素类型能做的事和不能做的事,例如行内元素的宽度和高度是不能设置的。根据内容自动。

不过对于网页 CSS 设计来说,例如 Bootstrap 或者 Element 等前端组件库已经设定好了很多实用的样式。可以在此基础上进行自定义。关于页面的布局也是有对应的解决方案,需要理解的还是元素的类型,

参考 https://www.runoob.com/cssref/pr-class-display.html

CSS 相关的教程好少啊,但是感觉各种属性对应的布局却很麻烦。

关于各个布局

https://zh.learnlayout.com/ 可以用来了解布局相关的知识。

布局其实就是把网页根据内容进行一个规划。

网页的内容永远都是不确定的,那么布局当然是要怎么好看怎么来。

了解布局首先需要了解 display 这个属性。这个属性决定了 HTML 元素在 CSS 层面上的性质。每个 tag 都有默认的 display 属性,比如常见的 h1 div p form 就是块级元素,而 a b i span select img input 都是行内元素。

通过不同的元素特性,页面元素也会产生不同的显示效果。比如在弹性盒子中有很多新的特性和 CSS 样式,可以更加方便快捷的设定垂直居中效果,而在块级元素中就很难做到。大致上来说网页的布局也就分为一列、二列、三列,通过样式的叠加形成不同的网页显示效果。至于说的什么圣飞布局、双飞翼布局感觉没啥意思,究其原理还是浮动、弹性盒子、网格、定位这类基础属性,只能说是别人设计出来的网页布局就是了。重要的还是内容的排列。通过 display 属性获得不同的文字、图片、内容块的排列效果。

关于盒模型

盒模型是用来计算元素大小的一个标准模型,完整适用于块元素,部分适用于行内元素。盒模型还有一个替代模型IE盒模型,在IE盒模型中,所有的宽度和高度都是可见的,内容的宽度包括了Padding的宽度。

Diagram of the box model

W3C 模型中的块级元素大小 = Content+Padding*2+Margin*2+Border*2

IE 盒模型大小不包括 Margin。

一个被定义成块级的(block)盒子会表现出以下行为:

  • 盒子会在内联的方向上扩展并占据父容器在该方向上的所有可用空间,在绝大数情况下意味着盒子会和父容器一样宽
  • 每个盒子都会换行
  • width height 属性可以发挥作用
  • 内边距(padding), 外边距(margin) 和 边框(border) 会将其他元素从当前盒子周围“推开”

如果一个盒子对外显示为 inline ,那么他的行为如下:

  • 盒子不会产生换行。
  • width height 属性将不起作用。
  • 内边距、外边距以及边框会被应用但是不会把其他处于 inline 状态的盒子推开。

一个元素使用 display: inline-block ,实现我们需要的块级的部分效果:

  • 设置 widthheight 属性会生效。
  • padding , margin , 以及 border 会推开其他元素。

但是,它不会跳转到新行,如果显式添加 widthheight 属性,它只会变得比其内容更大。

https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Flexbox 详细介绍了 display:flexible 弹性盒子的 flex 模型

flex_terms. png

  • 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main startmain end
  • 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross startcross end
  • 设置了 display: flex 的父元素(在本例中是 <section> )被称之为 flex 容器(flex container)。
  • 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项flex item)(本例中是 article 元素。

CSS 语句的权重

css选择器权重列表如下:

权重值 选择器
1,0,0,0 内联样式:style=””
0,1,0,0 ID选择器:#idName{...}
0,0,1,0 类、伪类、属性选择器:.className{...} / :hover{...} / [type="text"] ={...}
0,0,0,1 标签、伪元素选择器:div{...} / :after{...}
0,0,0,0 通用选择器(*)、子选择器(>)、相邻选择器(+)、同胞选择器(~)

需要注意的是这个权重并不是累加的,比如 ID 选择器会始终比属性选择器的优先级更高,即使在同一个元素上加10个属性选择器,优先级也不会比 ID 选择器高。系统在比较两个元素的优先级时会先比较高级的,如果相同才会向下比较,不相同就直接得出结果。

垂直对齐

行内元素

行内元素在块级元素中的垂直对齐主要使用 line-heightvertical-align 两个属性。

line-height 属性通过设置行高确定行距,行距是系统会自动设置上下对等的,所以将行高设置成块级元素的高即可使行内元素在块级元素中垂直居中。

line-height 属性可以在块级元素中设置也可以在子元素中设置,并且按照最大值确定。

vertical-align 属性只能作用于内联元素。考虑到内联元素就需要考虑到 基线 ,基线是字体对齐的标准。

一个设置了display: inline-block的元素:

  1. 如果元素内部没有内联元素,则该元素基线就是该元素下边缘;
  2. 如果元素设置了overflowhidden auto scroll,则其基线就是该元素下边缘;
  3. 如果元素内部还有内联元素,则其基线就是内部最后一行内联元素的基线。

需要注意的是 vertical-align 属性是基于行按照基线去对齐的,所以如果他需要对齐的父元素的高度并不是普通行高,是需要设置 line-height 的。也就是说大部分时候 line-height 属性就可以居中了,但是在视觉上可能没有那么居中,所以需要 vertical-align 来微调。

块级元素垂直对齐

  1. 使用 display: absolute ,然后为块级元素添加 topleft 属性,偏移值设置为 50% - width/2 或者设置为 50% 然后使用负值的 margin-top: width/2margin-left: width/2,这种方法需要知道这个块级元素的长宽,如果不知道,可以用transform: translate(-50%,-50%) 设置偏移,偏移量为自身的 50%。
  2. 使用 Flex 布局方式,父元素使用了 Flex 布局后,子元素可以直接设置 margin: auto 即可。IE 10+ 是支持这个布局方式的。
  3. 使用 display: absolute ,设置 topleftbottomright 为 0,设置 margin: auto

关于 BFC

常规流(Normal flow)

  • 在常规流中,盒一个接着一个排列;
  • 块级格式化上下文里面, 它们竖着排列;
  • 行内格式化上下文里面, 它们横着排列;
  • positionstaticrelative,并且floatnone时会触发常规流;
  • 对于静态定位(static positioning),position: static盒的位置是常规流布局里的位置
  • 对于相对定位(relative positioning),position: relative,盒偏移位置由这些属性定义topbottomleftandright即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置。

浮动(Floats)

  • 盒称为浮动盒(floating boxes);
  • 它位于当前行的开头或末尾;
  • 导致常规流环绕在它的周边,除非设置 clear 属性;

绝对定位(Absolute positioning)

  • 绝对定位方案,盒从常规流中被移除,不影响常规流的布局;
  • 它的定位相对于它的包含块,相关CSS属性:topbottomleftright
  • 如果元素的属性positionabsolutefixed,它是绝对定位元素;
  • 对于position: absolute,元素定位将相对于最近的一个relativefixedabsolute的父元素,如果没有则相对于body

BFC的创建方法

  • 根元素或其它包含它的元素;
  • 浮动 (元素的float不为none);
  • 绝对定位元素 (元素的positionabsolutefixed);
  • 行内块inline-blocks(元素的 display: inline-block);
  • 表格单元格(元素的display: table-cell,HTML表格单元格默认属性);
  • overflow的值不为visible的元素;
  • 弹性盒 flex boxes (元素的display: flexinline-flex);

但其中,最常见的就是overflow:hiddenfloat:left/rightposition:absolute。也就是说,每次看到这些属性的时候,就代表了该元素以及创建了一个BFC了。

清除浮动

  1. 通过在末尾添加一个空 div 设置 clear:both

    好用,但是用起来比较麻烦。

  2. 给父级设置

    1
    2
    father{zoom:1}
    father::after{display:block;clear:both;content:"";visibility:hidden;height:0}

    好用,而且没有后顾之忧。

  3. 给父级定义高度

    不好用,太死板。

  4. 父类使用 overflow-hidden 或者 auto 或者其他上面的创建方式形成 BFC

    会有副作用。

CSS3 更新了什么

CSS3被拆分为”模块”。旧规范已拆分成小块,还增加了新的。

一些最重要CSS3模块如下:

  • 选择器
  • 盒模型
  • 背景和边框
  • 文字特效
  • 2D/3D转换
  • 动画
  • 多列布局
  • 用户界面

新的边框属性

border-radius 可以为任何元素提供一个圆角,值一般是这个圆角的半径。可以单独为每个角进行设置。

box-shadow 属性用于给一个元素添加阴影效果。这个元素可以是块元素也可以是内联元素。

border-image 用于给边框提供一个自定义的图片。

新的背景属性

  • background-image
  • background-size
  • background-origin
  • background-clip

background-image 属性可以同时使用多张图片,通过逗号隔开,其他的关于图片背景的设置会按照 background-image 中的引入顺序进行配置。

background-origin 属性用于配置背景图片的位置是以 border、padding 还是 content 为起始位置。

background-clip 属性和 origin 差不太多,只是作用不太一样,origin 是指定背景图片的位置,clip 是指定整个背景的范围。这里只用的裁剪,更适合用在纯色背景上。

渐变效果(好看

  • 线性渐变(Linear Gradients)- 向下/向上/向左/向右/对角方向
  • 径向渐变(Radial Gradients)- 由它们的中心定义
1
2
background-image: linear-gradient(direction, color-stop1, color-stop2, ...);
background-image: radial-gradient(shape size at position, start-color, ..., last-color);

默认情况下是从上到下的渐变。

角度图

也可以通过角度来设置方向。

(可以设置多个节点但是彩虹色好看吗?)

变化更多的话可以使用透明度,也就是使用 rgba() 函数来定义颜色节点。

径向渐变就是一个渐变圆,默认是一个椭圆,可以设置为圆形的渐变。

甚至可以通过 repeating-radial-gradient() 设置重复效果。或许可以用来做水滴波纹样式。

新的文本属性

  • text-shadow
  • box-shadow
  • text-overflow
  • word-wrap
  • word-break

text-shadow 适用于文本的阴影,box-shadow 适用于盒子的阴影。

text-overflow 是针对文本如果会超出包含元素时采取什么样的措施。可以使用 clip 值来直接修剪,ellipsis 值通过省略号代替后续内容,或者指定文本。

word-wrapword-break 都是用于指定长文本的换行方式,wrap 设定为 break-word 时即可让长文本自动换行。break 用于设定当一个单词过长,是否将这个单词拆分并换行,默认情况下会保持单词长度。

更多的字体选择

CSS3 可以读取网站资源下的字体资源并使用该字体。使得网页的字体选择更加多样化。不再需要考虑字体的兼容性问题。通过 @font-face 进行设置。

1
2
3
4
5
6
7
8
9
10
11
12
<style> 
@font-face
{
font-family: myFirstFont;
src: url(sansation_light.woff);
}

div
{
font-family:myFirstFont;
}
</style>

转换效果

分为 2D 转换和 3D 转换

2D 转换中会使用到

  • translate()
  • rotate()
  • scale()
  • skew()
  • matrix()

translate() 方法,根据左( X 轴)和顶部( Y 轴)位置给定的参数,从当前元素位置移动。

rotate() 方法,在一个给定度数顺时针旋转的元素。负值是允许的,这样是元素逆时针旋转。

scale()方法,该元素增加或减少的大小,取决于宽度( X 轴)和高度( Y 轴)的参数:

包含两个参数值,分别表示X轴和Y轴倾斜的角度,如果第二个参数为空,则默认为0,参数为负表示向相反方向倾斜。

  • skewX(<angle>);表示只在 X 轴(水平方向)倾斜。
  • skewY(<angle>);表示只在 Y 轴(垂直方向)倾斜。

matrix()方法和2D变换方法合并成一个。

matrix 方法有六个参数,包含旋转,缩放,移动(平移)和倾斜功能。

3D 转换

rotateX()方法,围绕其在一个给定度数X轴旋转的元素。

rotateY()方法,围绕其在一个给定度数Y轴旋转的元素。

这些方法都是作为 transform 属性的值来生效的。更多的方法参考 https://www.runoob.com/cssref/css3-pr-transform.html

样式过渡

  • transition 简写属性,用于在一个属性中设置四个过渡属性。
  • transition-property 规定应用过渡的 CSS 属性的名称。
  • transition-duration 定义过渡效果花费的时间。默认是 0。
  • transition-timing-function 规定过渡效果的时间曲线。默认是 “ease”。
  • transition-delay 规定过渡效果何时开始。默认是 0。

在上面的转换中我们可以做到通过 CSS 来实现一些设定好的动画,比如移动、翻转、旋转等,为了让这些动画更加可控,就可以使用过渡(transition)来控制这些动画的时间、延迟、时间曲线。

这个过渡不一定是和 transform 一起搭配使用的,因为其过渡的本质是对比当一个事件发生后,之前和之后的 CSS 是否有变化,比如我希望在 hover 的时候宽度增加,就可以直接在 hover 的 CSS 中添加宽度增加的语句,在原 CSS 中使用 transition 对这一个 样式变化 进行过渡。

transition-property 属性在使用的时候如果被指定,其他的样式的变化是不会被过渡的,同时我感觉应该对性能方面会有所提升,所以建议使用,代码也会更加清晰。

动画!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
div
{
width:100px;
height:100px;
background:red;
animation:myfirst 5s;
-webkit-animation:myfirst 5s; /* Safari and Chrome */
}

@keyframes myfirst
{
0% {background:red; left:0px; top:0px;}
25% {background:yellow; left:200px; top:0px;}
50% {background:blue; left:200px; top:200px;}
75% {background:green; left:0px; top:200px;}
100% {background:red; left:0px; top:0px;}
}

</style>

通过 @keyframes 定义了一个名为 myfirst 的动画,通过 animationdiv 使用了该动画,持续时间5秒。

可以通过百分比去控制这个动画帧的进度,使得动画更加层次感。将需要改变的样式写在后面的 {} 中,通过 ; 隔开。

  • @keyframes 规定动画。
  • animation 所有动画属性的简写属性,除了 animation-play-state 属性。
  • animation-name 规定 @keyframes 动画的名称。
  • animation-duration 规定动画完成一个周期所花费的秒或毫秒。默认是 0。
  • animation-timing-function 规定动画的速度曲线。默认是 “ease”。
  • animation-fill-mode 规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。
  • animation-delay 规定动画何时开始。默认是 0。
  • animation-iteration-count 规定动画被播放的次数。默认是 1。
  • animation-direction 规定动画是否在下一周期逆向地播放。默认是 “normal”。
  • animation-play-state 规定动画是否正在运行或暂停。默认是 “running”。

具体的属性和上面的过渡相差并不算很多。

多列

  • column-count 指定元素应该被分割的列数。
  • column-fill 指定如何填充列
  • column-gap 指定列与列之间的间隙
  • column-rule 所有 column-rule-* 属性的简写
  • column-rule-color 指定两列间边框的颜色
  • column-rule-style 指定两列间边框的样式
  • column-rule-width 指定两列间边框的厚度
  • column-span 指定元素要跨越多少列
  • column-width 指定列的宽度
  • columns 设置 column-width 和 column-count 的简写

这些属性一般用于块级元素,例如 div 或者 p,会将块级元素中的文本作为多列进行排列。

column-span 属性在指定跨列的时候需要注意,值为 all 即是占一整行,如果为 1 会导致两个块级元素同行。并且如果跨列的元素文本过长则是在元素内部换行。

感觉背后原理大概是用的 float

如果设置了 column-countcolumn-width 不会生效。

用户界面

  • appearance 允许您使一个元素的外观像一个标准的用户界面元素(不兼容)
  • box-sizing 允许你以适应区域而用某种方式定义某些元素
  • icon 为创作者提供了将元素设置为图标等价物的能力(不兼容)
  • nav-down 指定在何处使用箭头向下导航键时进行导航(不兼容)
  • nav-index 指定一个元素的Tab的顺序(不兼容)
  • nav-left 指定在何处使用左侧的箭头导航键进行导航(不兼容)
  • nav-right 指定在何处使用右侧的箭头导航键进行导航(不兼容)
  • nav-up 指定在何处使用箭头向上导航键时进行导航(不兼容)
  • outline-offset 外轮廓修饰并绘制超出边框的边缘
  • resize 指定一个元素是否是由用户调整大小

box-sizing 最主要的用法是规定容器元素的最终尺寸计算方式。

  • content-box 这是 CSS2.1 指定的宽度和高度的行为。指定元素的宽度和高度(最小/最大属性)适用于box的宽度和高度。元素的填充和边框布局和绘制指定宽度和高度除外
  • border-box 指定宽度和高度(最小/最大属性)确定元素边框。也就是说,对元素指定宽度和高度包括了 padding 和 border 。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
  • inherit 指定 box-sizing 属性的值,应该从父元素继承

弹性盒子(Flex)

弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成。

弹性容器通过设置 display 属性的值为 flexinline-flex 将其定义为弹性容器。

Flex 布局可以更加方便的对齐弹性子元素,并且是符合响应式的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: -webkit-flex;
display: flex;
width: 400px;
height: 250px;
background-color: lightgrey;
}

.flex-item {
background-color: cornflowerblue;
width: 100px;
height: 100px;
margin: 10px;
}
</style>
</head>
<body>

<div class="flex-container">
<div class="flex-item">flex item 1</div>
<div class="flex-item">flex item 2</div>
<div class="flex-item">flex item 3</div>
</div>

</body>
</html>

在这个例子中,我们可以把3个 div 块级元素放在一行,但是需要注意的是,因为这里我们是设定好了的宽度,但是三个子元素和 margin 加起来很明显是填不满 400px 的,整体宽度就是(100+20)*3=360px,需要注意的是子元素之前没有 margin 合并现象。这样一来右边会出现一个 40px 的空隙,如果需要填满的比如把 margin 设置的更高,如果3个子元素的总宽度超过了父元素的宽度,就会直接三等分并且缩减 content 区域。所以一个比较好的做法就是设置子元素为百分比大小,三等分就33%。纵向排列的效果也是一样的。

  • flex-direction

    flex-direction 属性可以设置子元素的排列方式。

    • row:横向从左到右排列(左对齐),默认的排列方式。
    • row-reverse:反转横向排列(右对齐,从后往前排,最后一项排在最前面。
    • column:纵向排列。
    • column-reverse:反转纵向排列,从后往前排,最后一项排在最上面。、
  • justify-content

    把弹性项沿着弹性容器的主轴线(main axis)对齐。

    对齐

    使用这个属性的好处就在于如果是正常的从左到右从上到下如果父元素的宽度或高度过高,可以使用这个属性将子元素对齐,防止子元素的 Content 区域被自动减小。

    • flex-start

      弹性项目向行头紧挨着填充。这个是默认值。第一个弹性项的main-start外边距边线被放置在该行的main-start边线,而后续弹性项依次平齐摆放。

    • flex-end

      弹性项目向行尾紧挨着填充。第一个弹性项的main-end外边距边线被放置在该行的main-end边线,而后续弹性项依次平齐摆放。

    • center

      弹性项目居中紧挨着填充。(如果剩余的自由空间是负的,则弹性项目将在两个方向上同时溢出)。

    • space-between

      弹性项目平均分布在该行上。如果剩余空间为负或者只有一个弹性项,则该值等同于flex-start。否则,第1个弹性项的外边距和行的main-start边线对齐,而最后1个弹性项的外边距和行的main-end边线对齐,然后剩余的弹性项分布在该行上,相邻项目的间隔相等。

    • space-around

      弹性项目平均分布在该行上,两边留有一半的间隔空间。如果剩余空间为负或者只有一个弹性项,则该值等同于center。否则,弹性项目沿该行分布,且彼此间隔相等(比如是20px),同时首尾两边和弹性容器之间留有一半的间隔(1/2*20px=10px)

  • flex-wrap

    flex-wrap 属性用于指定弹性盒子的子元素换行方式。

    如果父元素的宽度过小,Flex 布局默认情况下是不会将子元素换行的,但是可以通过这个属性进行设置,换行后可以保证子元素的大小是和写的是一样的,如果父元素的高度不支持换行,依然是会换的,

    • nowrap - 默认, 弹性容器为单行。该情况下弹性子项可能会溢出容器。
    • wrap - 弹性容器为多行。该情况下弹性子项溢出的部分会被放置到新行,子项内部会发生断行
    • wrap-reverse -反转 wrap 排列。
  • align-content

    align-content 属性用于修改 flex-wrap 属性的行为。类似于 align-items, 但它不是设置弹性子元素的对齐,而是设置各个行的对齐。

    • stretch - 默认。各行将会伸展以占用剩余的空间。
    • flex-start - 各行向弹性盒容器的起始位置堆叠。
    • flex-end - 各行向弹性盒容器的结束位置堆叠。
    • center -各行向弹性盒容器的中间位置堆叠。
    • space-between -各行在弹性盒容器中平均分布。
    • space-around - 各行在弹性盒容器中平均分布,两端保留子元素与子元素之间间距大小的一半。

除了这些弹性容器上的设置,我们也可以对弹性子元素设置进行一个调整。

  • order 设置弹性盒子的子元素排列顺序。
  • align-self 在弹性子元素上使用。覆盖容器的 align-items 属性。
  • flex 设置弹性盒子的子元素如何分配空间。

网格布局(Grid)

多媒体查询

多媒体查询是为了给不同分辨率的媒体类型提供不同的样式。

1
2
3
@media not|only mediatype and (expressions) {
CSS 代码...;
}

这是媒体查询的主要语法,通过 @media 作为标志符

  • all 用于所有多媒体类型设备
  • print 用于打印机
  • screen 用于电脑屏幕,平板,智能手机等。
  • speech 用于屏幕阅读器

兼容

不同浏览器可能会有某些属性的兼容问题。

img 前缀-ms-的IE浏览器
img 前缀-moz-的火狐浏览器
img 前缀-webkit-的Google Chrome浏览器
img 前缀-webkit-的Safari浏览器
img 前缀-o-的Opera浏览器
img 前缀-xv-的Opera浏览器

使用某些属性的时候可以使用这种方式去对不同浏览器进行适配。

具体可以查询 https://www.runoob.com/cssref/css3-browsersupport.html

或者 https://caniuse.com/

如果面试官让你讲一下CSS3

CSS3 是新一代的 CSS 标准,对比与以前的 CSS,新增了更多的可控的属性,比如对于边框的定义,可以使用图片作为边框,可以对元素(任何元素)设置圆角,对于背景图片更加可控,新增了渐变效果,可以使用更多的自定义字体了。transform(转换)transition(过渡),提供动画(animation)操作。提供原生的多列文本操作。以及最重要的 Flex 布局方式。Flex 布局方式可以更加方便的对齐元素和自适应间隔以及垂直居中问题。