css的使用

# CSS

# 三大特性

**层叠:**是说当数量相同时,通过层叠(后者覆盖前者)的样式。

**优先级:**是指不同类别样式的权重比较;

**继承:**即子类元素继承父类的样式;

# 样式导入

  • 内嵌行内样式: 直接对 HTML 的标记使用 style 属性,然后将 CSS 代码直接写进去;

  • 内嵌头部式:将 CSS 写 headhead 之间,并且用 stylestyle 标记进行声明;

  • 链接式:通过将 上的 CSS 提起到指定的 CSS 文件上,然后通过 的方式在 HTML 上链接起来;

  • 导入样式:@import 导入式;

# 引入方式的层叠优先级

同权重: 内嵌行内样式 > 内嵌头部式> 链接式 > @import 导入式。 !important > id > class > tag !important 比 内联优先级高

总括:

  • !important
  • 内联样式style=""
  • ID选择器#id
  • 类选择器/属性选择器/伪类选择器.class.active[href=""]
  • 元素选择器/关系选择器/伪元素选择器html+div>span::after
  • 通配符选择器*

# CSS选择器的优先级

  1. 在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式。 -》最高

  2. 作为style属性写在元素内的样式(行内样式) -》1000

  3. id选择器(#myid) -》100

  4. 类选择器(.myclass) -》10

  5. 标签选择器(div, h1,p) -》1

  6. 通配符选择器(*)

  7. 浏览器自定义或继承

    总结排序!important > 行内样式 > ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

    总括分析:1:!important优先级最高;2:后面的会覆盖前面的;3:越具体越优先;

<p style="color: #fff; backgournd: deepskyblue;"></p>

<head>
  <style>
    p {
      color: #fff;
      background: deepskyblue;
    }
  </style>
</head>

<head>
  <link href="reset.css" type="text/css" rel="stylesheet">
</head>

<head>
  <style>
    @import url(reset.css);
  </style>
</head>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# css定义的权重

行内样式,1000,ID100,属性选择器/class/伪类10,元素名/伪元素1

相同的权重:以后面出现的选择器为最后规则;不同的权重,权重值高则生效

总括分析:1:!important优先级最高;2:后面的会覆盖前面的;3:越具体越优先;

position: static !important;
margin-left: 0 !important;
/*权重为1*/
div{
}
/*权重为10*/
.class1{
}
/*权重为100*/
#id1{
}
/*权重为100+1=101*/
#id1 div{
}
/*权重为10+1=11*/
.class1 div{
}
/*权重为10+10+1=21*/
.class1 .class2 div{
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 使用link和@import的区别

  • link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用而@import是CSS提供的,只能用于加载CSS;

  • 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载; @import相当于将css放在网页内容底部。

  • link是XHTML标签,无兼容问题,而import是CSS2.1 提出的,只在IE5以上才能被识别;

  • link支持使用js控制DOM去改变样式,而@import不支持;

  • link方式的样式的权重 高于@import的权重.

# src与href的区别

1.src用于替换当前元素,href用于在当前文档和引用资源之间确立关系。

<script src="source.js"></script>
1

当浏览器解析到元素时,会暂停其他资源的下载和处理,直到该资源,编译,执行完毕,图片和框架也是如此,类似将所指向资源嵌入标签内,这也是为什么js放在底部而不是头部。

2.href - Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档之间的链接;

<link href="css.css" rel="stylesheet"/>
1

href 目的不是为了引用资源,而是为了建立联系,让当前标签能够链接到目标地址

那么浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式。

# CSS单位

# 比较

单位 描述
% 百分比
px 像素。计算机屏幕上的一个点为 1px
em 相对单位。相对于父元素计算,假如某个 p 元素为 font-size: 12px,在它内部有个 span 标签,设置 font-size: 2em,那么,这时候的 span 字体大小为:12 * 2 = 24px
rem 相对单位。相对于根元素 html 的 font-size,假如 html 为 font-size: 12px,那么,在其当中的 div 设置为 font-size: 2rem,就是当中的 div 为 24px
rpx 微信小程序相对单位。1rpx = 屏幕宽度 / 750 px。在 750px 的设计稿上,1rpx = 1px。

# px em rem vw

  • px:(pixel 像素的缩写),相对于显示器屏幕分辨率;
  • em:相对于父元素的 font-size;
  • rem可想成 root-em,相对于 root(html)的 font-size;
  • vw相对视口(viewport)的宽度而定的,长度等于视口宽度的 1/100;
  • 除此之外还有 pt、ex 等单位;

浏览器的兼容性 除了IE6-IE8r,其它的浏览器都支持em和rem属性,px是所有浏览器都支持。 因此为了浏览器的兼容性,可“px”和“rem”一起使用,用"px"来实现IE6-8下的效果,然后使用“rem”来实现代浏览器的效果。

注意,rem是只相对于根元素htm的font-size,即只需要设置根元素的font-size,其它元素使用rem单位设置成相应的百分比即可;

一般浏览器的默认字体大小都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

# CSS选择符

  • 1.id选择器( # myid)ID一般用在JavaScript中
  • 2.类选择器(.myclassname)Class一般用在CSS中
  • 3.标签选择器(div, h1, p)
  • 4.相邻选择器(h1 + p)
  • 5.子选择器(ul > li)
  • 6.后代选择器(li a)
  • 7.通配符选择器( * )
  • 8.属性选择器(a[rel = "external"])
  • 9.伪类选择器(a:hover, li:nth-child)

是否可以继承

  • 可继承的样式: font-size font-family color, text-indent, UL LI DL DD DT;
  • 不可继承的样式:margin border padding width height ;【mbpc】

简写设置规则:1个【上右下左】, 2个【(上下)(左右)】,3个【上(左右)下】

# 盒模型

# 分类及区别

盒模型: CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距(margin),边框(border),填充(padding),和实际内容(content)。盒模型允许我们在其它元素和周围元素边框之间的空间放置元素有两种: IE 盒子模型、W3C 盒子模型; 区 别IE的content部分把 border 和 padding计算了进去; CSS 中有个属性叫 box-sizing: box-sizing: content-box|border-box|inherit;

box-sizing: content-box(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。默认box-sizing: border-boxIE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距(padding) + 边框的大小(border)。背景会延伸到边框的外沿。

正常情况下(content-box)

  • padding + border + width= 盒子的宽度
  • padding+ border + height = 盒子的高度

content-box是默认值,总宽度= margin+border+padding+width(直接是广度)

border-box在css中设置的width = border + padding + content, 那么总宽度 = margin + width ; 常在box宽度是100%,又想要两边有内间距

ps: border-box这种使用场景一般用在item中间对齐后,又要保证内容全部填充完整;

# 相关属性【mbpc】

  • margin:盒子外边距; 外边距
  • border:盒子边框宽度;
  • padding:盒子内边距; 内边距
  • width:盒子宽度(content)
  • height:盒子高度(content)

不可继承的样式:margin border padding width height ;【mbpc】

# 浏览器兼容性

  • IE8及以上版本支持该属性,Firefox 需要加上浏览器厂商前缀-moz-,对于低版本的IOSAndroid浏览器也需要加上-webkit-。实际上,很多reset.css或者normal.css里都包含如下CSS语句,也是比较赞成的用法:
.div0 {/*实际内容:120x120*/
  width: 100px;
  height: 100px;
  margin: 10px;
  padding: 10px;
  background-color: blue;
}
.div1 {/*实际内容:120x120*/
  width: 100px;
  height: 100px;
  box-sizing: content-box;
  margin: 10px;
  padding: 10px;
  background-color: burlywood;
}
.div2 {/*实际内容:100x100*/
  width: 100px;
  height: 100px;
  margin: 10px;
  box-sizing: border-box;
  padding: 10px;
  background-color: green;
}

/*兼容性设置*/
*, *:before, *:after {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}
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

# 注意点

  • width属性默认值为auto,块级元素的贪婪性和行内元素的懒惰性
  • 有些标签有默认的padding值和margin值,所以一般写网页时都会重置样式 *{margin:0;padding:0;}

# 获取盒子宽高的几种方式及区别

  • dom.style.width/height :这种方式只能取到dom元素内联样式所设置的宽高,也就是说如果该节点的样式是在style标签中或外联的CSS文件中设置的话,通过这种方法是获取不到dom的宽高的

  • dom.currentStyle.width/height :获取渲染后的宽高。但是仅IE支持

  • window.getComputedStyle(dom).width/height :与2原理相似,但是兼容性,通用性更好一些

  • dom.getBoundingClientRect().width/height:计算元素绝对位置,获取到四个元素left,top,width,height

获取浏览器高度和宽度的兼容性写法:

var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
1
2
const {clientHeight, clientWidth} = document.getElementsByClassName(styles.autoSize)[0];

@debounce(300)
resize() {
    const height = document.getElementsByClassName(styles.partition)[0].offsetHeight;
    this.setState({ height: height - 49 });
}
1
2
3
4
5
6
7

# height、clientHeight、scrollHeight、offsetHeight区别

# 布局相关设置【PDFOZ】

  • postion
  • display
  • float
  • overflow
  • z-index

# position 定位方式

定位: left(左),right(右),top(上),bottom(下)离页面顶点的距离

设置:【SRAFI】

  • static 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right z-index 声明)。
  • relative 生成相对定位的元素,相对于其正常位置进行定位。
  • absolute 生成绝对定位的元素,相对于值不为 static的第一个父元素进行定位。 fixed也可以;如果先辈元素全是static,那么相对于视口定位;(特殊情况);如果无已定位祖先元素, 以body元素为偏移参照基准, 完全脱离了标准文档流。
  • fixed 生成绝对定位的元素,相对于浏览器窗口进行定位 ;悬浮设置后,宽高会自适应,记得设置 width: 100%,及定位设置;一个固定定位元素不会保留它原本在页面应有的空隙。(老IE不支持);如果先辈元素有 非nonetransform属性,那么相对于该先辈元素定位(不注意容易产生BUG)
  • inherit 继承; 规定从父元素继承 position 属性的值。

absolutefixed定位的比较

  • 共同点:改变行内元素的呈现方式,都脱离了文档流

  • 不同点:absolute的**”根元素“是可以设置的,fixed的“根元素”固定为浏览器窗口**

position: absolute;

  • 相对于非static的先辈元素定位;(正常情况); 相对于最近的已定位的祖先元素, 有已定位(指position不是static的元素)祖先元素, 以最近的祖先元素为参考标准。如果无已定位祖先元素, 以body元素为偏移参照基准, 完全脱离了标准文档流。
  • 如果先辈元素全是static,那么相对于视口定位;(特殊情况)

position:fixed

  • 相对于视口定位;(正常情况)
  • 如果先辈元素有 非nonetransform属性,那么相对于该先辈元素定位(不注意容易产生BUG)

失效的解决办法是:对父级元素设置transform: none; 或者display:inline

# position:fixed;在android下无效怎么处理?

手机上兼容设置:所以说并不是iOS不支持fixed,只是fixed的元素不是相对手机屏幕固定的

通过以下设置处理:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
1

# display的设置

单位 描述
none 元素不显示,并从文档流中移除。
block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
inherit 规定应该从父元素继承 display 属性的值。
table 此元素会作为块级表格来显示。表格显示;
list-item 象块类型元素一样显示,并添加样式列表标记。项目列表;
/*==display 显示属性(div与span的区别); 反过来设置==*/
.div_span_1_cls,.div_span_2_cls,.div_span_3_cls{
  background: green;
  display: inline;
}
span{
  background-color: red;
  display: block;
  width: 200px;
}
<div class="div_span_1_cls">Samy张</div>
<div class="div_span_2_cls">Samy张</div>
<div class="div_span_3_cls">Samy张</div>
<span class="span_div_3_cls">Samy张S</span>
<span class="span_div_3_cls">Samy张S</span>
<span class="span_div_3_cls">Samy张S</span>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# float 浮动属性

left 左浮动 right 右浮动 clear 清除浮动; clear:both

注:设置 Flex 布局后,子元素的 float 布局将失效

# overflow 溢出处理

  • hidden 隐藏超出层大小的内容
  • scroll 无论内容是否超出层大小都添加滚动条
  • auto 超出时自动添加滚动条

# z-index网页的层叠等级

z-index 层覆盖先后顺序(优先级); 大于0的数字;数字大的最上面

其实一个网页是分为好多层的,具体层次和层叠等级如下图:

z-index为正值 》 z-index: 0/auto 》 行内元素 》 浮动元素 》 块级元素 》z-index为负数 》 background/border

# margin 属性

  • margin 属性为给定元素设置所有四个(上左下右)方向的外边距属性。

  • 普通元素的 百分比margin 都是相对于容器的宽度计算的

  • 绝对定位元素的 百分比margin 相对于其定位祖先元素的宽度计算的

  • 上下margin会重叠:只会发生在 block元素上,(取最大值)

    解决重叠方法:

    1. 父元素设置 BFC(如overflow:hidden;如position:absolute等)
    2. 父元素设置 border/padding
  • 当 margin 的值为 auto时。浏览器会自动选择一个合适的margin来应用(自动分配剩余空间)

    1. 需要元素是 块状元素
    2. 需要元素 设置宽度
  • margin 可以为 负值

# 设置DOM元素不显示在浏览器可视范围内

# visibility:hidden、display:none、z-index=-1、opacity:0 及比较;【OVDZ】

  1. opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
  2. visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件; (重绘)
  3. display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉; (回流+重绘)
  4. z-index=-1置于其他元素下面; 注意:z-index的数值不跟单位。z-index的数字越高越靠前,并且值必须为整数和正数(正数的整数)。

总括

最基本的:设置visibility属性为hidden,或者设置display属性为none

技巧性:设置透明度为0,设置z-index位置在-1000, 设置宽高为0

# 行内(inline)/块级(block)/空(void)元素

首先:CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值

如span默认display属性值为“inline”,是“行内”元素; div的display默认值为“block”,则为“块级”元素;

行内(inline)元素宽度和高度由内容决定与其他元素共占一行的元素; 内边距的top/bottom(padding-top/padding-bottom)和外边距的top/bottom(margin-top/margin-bottom)都不可改变(也就是padding和margin的left和right是可以设置的),就是里面文字或图片的大小。

​ 如:i a b span select strong

块级(block)元素默认宽度由父容器决定,默认高度由内容决定独占一行并且可以设置宽高的元素;

​ 如:div ul ol li dl dt dd h1 h2 h3 h4…p

浏览器还有默认的天生inline-block【空】元素(拥有内在尺寸,可设置高宽,但不会自动换行

​ 如:<input> 、<img> 、<button> 、<texterea> 、<label>

在日常开发中,经常使用 CSS 的 display 属性来打破两者的壁垒:display: inline-block,使它们拥有更多的状态。常见的空元素: 不同浏览器(版本)、HTML4(5)、CSS2等实际略有差异;

<br> <hr> <img> <input> <link> <meta>
//鲜为人知的是:
<area> <base> <col> <command> <embed> <keygen> <param> <source> <track> <wbr>
1
2
3

说明

  • 块级标签可以设置width和height
  • 行内标签不可以设置width和height它的width由内容决定,height由font-size决定
  • block水平的元素inline-block化后,IE6/7没有换行符间隙问题,其他浏览器均有;{ display: inline-block; *display: inline; *zoom: 1; } inline水平的元素inline-block后,所有主流浏览器都有换行符/空格间隙问题
# 注意
  • 对于行级元素:margin-top和margin-bottom对于上下元素无效,margin-left和margin-right有效也就是padding和margin的left和right是可以设置的【要点】
  • 对于相邻的块级元素: margin-bottom和margin-top 取值方式;
    • 1) 都是正数: 取最大值
    • 2) 都是负数: 取最小值
    • 3)上面是正数,下面是负数或者 上面是负数,下面是正数: 正负相加

# display:inline-block元素之间空隙的产生原因和解决办法 [水平及垂直]方向

这就是**“换行符/空格间隙问题”** 这些元素之间的间距会随着字体的大小而变化,当行内元素font-size:16px时,间距为8px。

# li与li之间有看不见的空白间隔是什么原因引起的,有什么解决办法

li设置成行内元素了,行内元素之间是会有一定间隙的 解决:

解决空隙的办法:(水平方向)

  • 办法一:解决元素之间的空白符; 缺点:代码的可读性变差。
  • 方法二:为父元素中设置font-size: 0,在子元素上重置正确的font-size;去除换行符间隙; 缺点:inline-block元素必须设定字体,不然行内元素中的字体不会显示。 增加了代码量。且在Safari浏览器依然会出现空白间隔。
  • 方法三:为inline-block元素添加样式float:left; 缺点:float布局会有高度塌陷问题;
  • 方法四:设置子元素margin值为负数; 缺点:元素之间间距的大小与上下文字体大小相关;并且同一大小的字体,元素之间的间距在不同浏览器下是不一样的
  • 方法五:最优解在这,**设置父元素,letter-spacing:-5px;(-大于4px就可以) 子元素,letter-spacing:normal **;【推荐】
  • 如考虑浏览器完全兼容设置: 方案2和方案4结合使用;

补充: (垂直方向) 有时候inline-block还会遇到顶部不在一个基准线的情况(垂直方向上产生的间隙),解决办法:在每一个子元素上加一个属性:vertical-align:top;(或者值是bottom,要看具体实现的效果了,想让顶部对齐就top,想让底部对齐就bottom)

# title与h1的区别、b与strong的区别、i与em的区别?

  • title属性没有明确意义只表示是个标题H1则表示层次明确的标题,对页面信息的抓取也有很大的影响;

  • strong是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时; <strong>会重读,而<B>是展示强调内容

  • i内容展示为斜体em表示强调的文本

Physical Style Elements -- 自然样式标签 b, i, u, s, pre Semantic Style Elements -- 语义样式标签 strong, em, ins, del, code 应该准确使用语义样式标签, 但不能滥用, 如果不能确定时首选使用自然样式标签

# 清除浮动的方法【要点】

浮动会脱离文档流,浮动可以内联排列,会导致父元素高度坍塌

清除浮动的原理:基本上都是clear:both

方式

  1. 在同一级加一个div,style是clear:both;
  2. 给父元素添加 overflow:auto 或者hidden 样式,触发BFC; (让父元素的高度包含子浮动元素
  3. 父元素加伪元素 .clearfix:after { display: block; content: " "; clear: both; }
  4. flex布局能够替代浮动布局;

具体实现

  • 在浮动元素后面添加 clear:both 的空 div 元素; 这种方法通俗易懂,但添加了无意义的空标签,违背了结构和表现分离的原则 ,对于后续维护不友好。

    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
        <div style="clear:both"></div>
    </div>
    
    1
    2
    3
    4
    5
  • 给父元素添加 overflow:auto 或者hidden 样式,触发BFC。【推荐】 浮动元素会回到容器层,将容器高度撑开,达到清除浮动的效果。

    .container{
        width: 300px;
        background-color: #aaa;
        overflow:hidden;
        zoom:1;   /*IE6*/
    }
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • 使用after伪元素,也是在元素末尾添加一个点并带有 clear: both 属性的元素实现的。

    .clearfix{
        zoom: 1; /*IE6: 针对于IE6的,因为IE6不支持:after伪类,这个神奇的zoom:1让IE6的元素可以清除浮动来包裹内部元素。*/
    }
    .clearfix:after{/*在类名为“clearfix”的元素内最后面加入内容*/
        display: block;
        content: "";/*内容为“.”就是一个英文的句号而已。也可以不写。 */
        height: 0;
        clear: both;
        visibility: hidden;/*可见度设为隐藏。注意它和display:none;是有区别的。visibility:hidden;仍然占据空间,只是看不到而已*/
    }
    <div class="container clearfix">
        <div class="left"></div>
        <div class="right"></div>
    </div>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  • flex布局能够替代浮动布局

# 水平/垂直居中

# 水平居中

  1. 行内元素:display: inline(-block); text-align: center;
  2. 块级元素:margin: 0 auto; display: block
  3. Flex:display: flex; justify-content: center; //节水

# 垂直居中

  1. 行高 = 元素高:line-height: height (单行文本)
  2. Flex:display: flex; align-items: center; (单行文本)
  3. 多行文本 垂直居中; (下面的table处理类似)

# margin:auto法
div{
  width: 400px;
  height: 400px;
  position: relative;
  border: 1px solid #465468;
 }
 img{
      position: absolute;
      margin: auto;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
 }

<div>
 <img src="mm.jpg">
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

定位为上下左右为0,margin:0可以实现脱离文档流的居中.

# margin负值法
.container{
  width: 500px;
  height: 400px;
  border: 2px solid #379;
  position: relative;
}
.inner{
  width: 480px;
  height: 380px;
  background-color: #746;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -190px; /*height的一半*/
  margin-left: -240px; /*width的一半*/
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

补充:其实这里也可以将marin-top和margin-left负值替换成, transform:translateX(-50%)和transform:translateY(-50%)

# table-cell(未脱离文档流的)

设置父元素的display:table-cell,并且vertical-align:middle,这样子元素可以实现垂直居中。

css:
div{
    width: 300px;
    height: 300px;
    border: 3px solid #555;
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}
img{
    vertical-align: middle;
}
1
2
3
4
5
6
7
8
9
10
11
12
# 利用flex

将父元素设置为display:flex,并且设置align-items:center;justify-content:center;

css:
.container{
      width: 300px;
      height: 200px;
      border: 3px solid #546461;
      display: -webkit-flex;
      display: flex;
      -webkit-align-items: center;
      align-items: center;
      -webkit-justify-content: center;
      justify-content: center;
 }
 .inner{
      border: 3px solid #458761;
      padding: 20px;
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# CSS属性支持判断

# 利用属性覆盖原理

将高版本浏览器支持的特性写在后面。利用浏览器的2个CSS解析特性:

  • 后面的属性覆盖前面的属性
  • 遇到不认识的语法,CSS parser 不解析。
div {
    background: red;
    background: linear-gradient(90deg, red, yellow)
}
1
2
3
4

# 使用 .css@supports

使用 .css@supports 来判断属性支持情况

// 支持特定属性的处理
@supports (position:sticky) {
    div {
        position:sticky;
    }
}
// 不支持特定属性:用not处理
@supports not (background: linear-gradient(90deg, red, yellow)) {
    div {
        background: red;
    }
}
// 如果是多个css属性:用and处理
@supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) {
    p {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 使用 JS 判断

使用 JS 判断 CSS 属性支持情况

作为 @supports 的另一种形式出现的,可以使用 javascript 的方式来获得 CSS 属性的支持情况。

CSS.supports('display', 'flex'); 必须2个参数, 否则返回false,(目前不支持IE浏览器)

# 使用 JS 库 modernizr

如果浏览器不支持@supports,可以通过调用ele.style来判断属性支持情况(库:Modernizr (opens new window)

# 通过判断 赋值再查询

通过判断 赋值再查询 来判断是否支持

var root = document.documentElement; //HTML
for(var key in root.style) {
    console.log(key);
}
// 将会打印
// alignContent
// alignItems
// alignSelf
// alignmentBaseline
// all
// animation
// ...
1
2
3
4
5
6
7
8
9
10
11
12

元素可能有 background 属性,但是不支持具体的 linear-gradinet() 属性值。这个时候该如何检测呢?只需要将具体的值赋值给某一元素,再查询这个属性值能否被读取。

var root = document.documentElement;
root.style.backgroundImage = 'linear-gradient(90deg, #888, #ccc)';
if(root.style.backgroundImage) {// 支持
} else {// 不支持
}
1
2
3
4
5

# 简单的 CSS 属性支持封装

通过页面隐藏的元素进行测试。

/**
    * 用于简单的 CSS 特性检测
    * @param [String] property 需要检测的 CSS 属性名
    * @param [String] value 样式的具体属性值
    * @return [Boolean] 是否通过检查
    */
function cssTest(property, value) {
    // CSS && CSS.supports
    // CSS.supports('display', 'flex');  必须2个参数, 否则返回false
    var ele = document.getElementById('test-display-none');// 用于测试的元素,隐藏在页面上
    if(arguments.length === 1) {// 只有一个参数的情况
        if(property in ele.style) {
            return true;
        }
    }else if(arguments.length === 2){// 两个参数的情况
        ele.style[property] = value;
        if(ele.style[property]) {
            return true;
        }
    }
    return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# BFC

# 简介

BFC全称”Block Formatting Context”, 中文为“块级格式化上下文”。记住这么一句话:BFC元素特性表现原则就是,内部子元素再怎么翻江倒海,翻云覆雨都不会影响外部的元素。所以,避免margin穿透啊,清除浮动什么的也好理解了。BFC 的工作是把东西装在盒子里,防止它们从盒子里跑出来。

# 常见触发BFC【PDFOZ】【要点】

  • 根元素,即HTML元素;
  • position的值不为relativestatic ;为absolute, fixed
  • float的值不为none; 为left, rightfloat:left 浮动元素本身BFC化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性;
  • overflow的值不为visible; 为auto,scrollhidden 。清除浮动: .clearfix { overflow: hidden; zoom: 1; }
  • display的值为inline-blockinline-flexflexflow-roottable-captiontable-cell中的任何一个。
  • 定制了一个新的属性值:display:flow-root。 可以使用display:flow-root安全的创建BFC,来解决上文中提到的各种问题:包裹浮动元素阻止外边距叠加阻止围绕浮动元素。 目前还有兼容性问题;flow-root 浏览器支持情况 https://caniuse.com/

优化处理:【FOPD】

  • 根元素
  • float不为none的元素
  • overflow不为visible的元素
  • position为fixed和absolute的元素, 不为relativestatic
  • display为inline-block、table-cell、table-caption,flex,inline-flex的元素

# overflow失效检查

html元素的overflow默认属性是visible,导致body元素的overflow:hidden被应用于视口,导致body元素的overflow属性最终为visible,因此body没有触发BFC。

所以只能先将html元素的overflow属性设置为hidden,再把body元素的overflow属性设置为hidden,才能使body触发BFC 。

# 特性/作用

# 特性

BFC的定位方案

那么BFC就是一个决定如何渲染元素的容器。我们要了解就是它的渲染规则。

  1. 内部的块级元素会在垂直方向,一个接一个地放置。
  2. 块级元素垂直方向的距离由margin决定。属于同一个BFC的两个相邻块级元素的margin会发生重叠。
  3. 对于从左往右的格式化,每个元素(块级元素与行内元素)的左边缘,与包含块的左边缘相接触,(对于从右往左的格式化则相反)。即使包含块中的元素存在浮动也是如此,除非其中元素再生成一个BFC。
  4. BFC的区域不会与浮动元素重叠。
  5. BFC是一个隔离的独立容器,容器里面的子元素和外面的元素互不影响。
  6. 计算BFC容器的高度时,浮动元素也参与计算。
# 使用场景/作用

可以将 BFC 看作是页面内的一个迷你布局。一旦一个元素创建了一个 BFC,它就包含了所有的内容。正如我们所看到的,这包括浮动的元素,它们不再从盒子底部伸出来。BFC 还会导致一些其他有用的行为。

总括

  • 清除内部浮动; 清除浮动(让父元素的高度包含子浮动元素
  • 防止margin重叠; 去除边距重叠现象
  • 自适应两(多)栏布局; 避免多列布局由于宽度计算四舍五入而自动换行
  • 防止字体环绕; 避免某元素被浮动元素覆盖

清除浮动

前面提到用clear:both来清除浮动,也可以根据BFC的渲染规则第6点(计算BFC容器的高度时,浮动元素也参与计算)来清除浮动,解决高度坍塌的问题。

解决上下margin边距问题

<body>
    <div style="width:100px;height:100px;background:red;margin:20px;"></div>
    <div style="width:100px;height:100px;background:blue;margin:20px;"></div>
</body>
1
2
3
4

利用BFC渲染规则第2点(属于同一个BFC的两个相邻块级元素的margin会发生重叠),那么不属于同一个BFC的两个相邻块级元素的margin就不会发生重叠。

总之一句话,如果元素的父级不是BFC或者IFC,那么就会去找父级的父级,直到找到触发BFC或者IFC的元素。

那么在第二个div元素用一个div元素包裹起来,并用overflow:auto触发其BFC。再看一下效果是不是不重叠了。

<body>
    <div style="width:100px;height:100px;background:red;margin:20px;"></div>
    <div style="overflow:auto">
        <div style="width:100px;height:100px;background:blue;margin:20px;"></div>
    </div>
</body>
1
2
3
4
5
6

img

实现自适应两栏布局

自适应两栏布局,是一个主内容区域和一个侧边栏区域组成,两个区域的宽度都可以随窗口大小自适应。有很多种写法可以实现。

这里来实现一种利用BFC的渲染规则的写法。

<style>
    .main{
        background: red;
        height:500px;
    }
    .sider {
        float: left;
        width: 20%;
        height:300px;
        background: blue;
    }
</stley>
<body>
    <div class="sider">我是侧边栏</div>
    <div class="main">我是主体内容</div>
<body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

img

首先我们根据规则1,要先把.sider div写在.main div前面。这个.sider div才会浮动起来覆盖在.main div上面。

再根据规则4(BFC的区域不会与浮动元素重叠),给.main加上overflow:auto;触发.main div生成BFC。

img

在多列布局中使用 BFC

# IFC

# 简介

IFC的全称是Inline Formatting Contexts,也就是“内联格式化上下文”。

# 生成条件

IFC的形成条件非常简单,块级元素中仅包含内联级别元素,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个IFC。

# 渲染规则

  • 子元素水平方向横向排列,并且垂直方向起点为元素顶部。
  • 子元素只会计算横向样式空间,【padding、border、margin】,垂直方向样式空间不会被计算,【padding、border、margin】。
  • 在垂直方向上,子元素会以不同形式来对齐(vertical-align)
  • 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(line box)。行框的宽度是由包含块(containing box)和与其中的浮动来决定。
  • IFC中的“line box”一般左右边贴紧其包含块,但float元素会优先排列。
  • IFC中的“line box”高度由 CSS 行高计算规则来确定,同个IFC下的多个line box高度可能会不同。
  • 当 inline-level boxes的总宽度少于包含它们的line box时,其水平渲染规则由 text-align 属性值来决定。
  • 当一个“inline box”超过父元素的宽度时,它会被分割成多个boxes,这些 boxes 分布在多个“line box”中。如果子元素未设置强制换行的情况下,“inline box”将不可被分割,将会溢出父元素。

# 应用

  • 水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
  • 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

# FFC

# 概念

FFC的全称是Flex formatting contexts,弹性盒模型。

# 生成条件

父级元素设置display:flex或者display:inline-flex

# 渲染规则

参考阮一峰的Flex 布局教程:语法篇 (opens new window),讲的非常详细。

要注意一点。生成FFC后,其子元素的float、clear和vertical-align属性将失效。

# 应用

# 自动撑开页面高度

自动撑开页面高度,底栏总是出现在页面的底部

img

<style>
.wrap{
    display:flex;
    padding:0;
    margin:0;
    min-height:100vh;
    flex-direction:column;
}
.main{
    flex-grow:1;
}
</style>
<body class="wrap">
    <header style="line-height:50px;background:red;color:#fff;text-align:center">头部</header>
    <main class="main">内容</main>
    <footer style="line-height:50px;background:#eeeeee;color:#333;text-align:center">底栏</footer>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

img

# 经典的圣杯布局[推荐]
<style>
.wrap {
    display: flex;
    padding: 0;
    margin: 0;
    min-height: 100vh;
    flex-direction: column;
}
header,
footer {
    flex: 0 0 50px;
}

.content {
    display: flex;
    flex: 1
}

.main {
    flex: 1;
}
.nav,
.ads{
    flex: 0 0 100px;
    background:green;
}
.nav{
    order:-1;
    background:yellow;
}
</style>
<body class="wrap">
    <header style="line-height:50px;background:red;color:#fff;text-align:center">头部</header>
    <div class="content">
        <main class="main">内容区</main>
        <nav class="nav">侧边导航</nav>
        <aside class="ads">侧边栏</aside>
    </div>
    <footer style="line-height:50px;background:#eeeeee;color:#333;text-align:center">底栏</footer>
</body>
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
31
32
33
34
35
36
37
38
39
40

img

# CSS3

# Flex 布局

Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性

行内元素也可以使用 Flex 布局。display: inline-flex;Webkit 内核的浏览器,必须加上-webkit前缀。display: -webkit-flex; /* Safari */

注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效

父元素属性(6个)

属性名 属性值 备注
display flex 定义了一个flex容器,它的直接子元素会接受这个flex环境
flex-direction row,row-reverse,column,column-reverse 决定主轴的方向
flex-wrap nowrap,wrap,wrap-reverse 如果一条轴线排不下,如何换行
flex-flow [flex-direction] , [flex-wrap] flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
justify-content flex-start,flex-end,center,space-between,space-around 设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式
align-items flex-start,flex-end,center,baseline,stretch 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式

子元素属性(6个)

属性名 属性值 备注
order [int] 默认情况下flex order会按照书写顺训呈现,可以通过order属性改变,数值小的在前面,还可以是负数。
flex-grow [number] 设置或检索弹性盒的扩展比率,根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间
flex-shrink [number] 设置或检索弹性盒的收缩比率,根据弹性盒子元素所设置的收缩因子作为比率来收缩空间
flex-basis [length], auto 设置或检索弹性盒伸缩基准值
align-self auto,flex-start,flex-end,center,baseline,stretch 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式,可以覆盖父容器align-items的设置
flex [number] 占比

# 在容器上的6个属性设置

  • flex-direction
    • flex-direction属性决定主轴的方向(即项目的排列方向)。
    • flex-direction: row | row-reverse | column | column-reverse;
      • row(默认值):主轴为水平方向,起点在左端。
      • row-reverse:主轴为水平方向,起点在右端。
      • column:主轴为垂直方向,起点在上沿。
      • column-reverse:主轴为垂直方向,起点在下沿。
  • flex-wrap
    • 默认情况下,在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
    • flex-wrap: nowrap | wrap | wrap-reverse;
      • nowrap(默认):不换行。
      • wrap:换行,第一行在上方。
      • wrap-reverse:换行,第一行在下方。
  • flex-flow
    • flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
    • flex-flow: <flex-direction> || <flex-wrap>;
  • justify-content 水平方向
    • justify-content属性定义了项目在主轴上的对齐方式
    • justify-content: flex-start | flex-end | center | space-between | space-around;
      • flex-start(默认值):左对齐
      • flex-end:右对齐
      • center: 居中
      • space-between:两端对齐,项目之间的间隔都相等。
      • space-around:每个项目两侧的间隔相等。所以项目之间的间隔比项目与边框的间隔大一倍。
  • align-items 垂直方向
    • align-items属性定义项目在交叉轴上如何对齐
    • align-items: flex-start | flex-end | center | baseline | stretch;
      • flex-start:交叉轴的起点对齐。
      • flex-end:交叉轴的终点对齐。
      • center:交叉轴的中点对齐。
      • baseline: 项目的第一行文字的基线对齐。
      • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
  • align-content
    • align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
    • align-content: flex-start | flex-end | center | space-between | space-around | stretch;
      • flex-start:与交叉轴的起点对齐。

      • flex-end:与交叉轴的终点对齐。

      • center:与交叉轴的中点对齐。

      • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。

      • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。

      • stretch(默认值):轴线占满整个交叉轴。

# 在项目上的6个属性设置

  • order
    • order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
    • order:<integer>;
  • flex-grow
    • flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
    • flex-grow: <number>; /* default 0 */
      • 有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。
      • 如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
  • flex-shrink
    • flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
    • flex-shrink:<number>; /* default 1 */
      • 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。
      • 如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
      • 负值对该属性无效。
  • flex-basis
    • flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。**浏览器根据这个属性,计算主轴是否有多余空间。**它的默认值为auto,即项目的本来大小。
    • flex-basis: <length> | auto; /* default auto */
      • 它可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间。
  • flex
    • flex属性是flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto。后两个属性可选。
    • flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
      • 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
      • 建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
  • align-self
    • align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch
    • align-self: auto | flex-start | flex-end | center | baseline | stretch;
      • 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
  <style>
    .container {
      display: flex;
    }
    .child-one {
      width: 300px;
      height: 300px;
      background: red;
    }
    .child-two {
      width: 100%;
      height: 300px;
      background: deepskyblue;
    }
  </style>
<body>
  <div class="container">
    <div class="child-one"></div>
    <div class="child-two"></div>
  </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 新增伪类

伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类(:first-child :link :visitive :hover :focus :lang)

旧语法:

属性 描述 CSS
:active (opens new window) 向被激活的元素添加样式。 1
:focus (opens new window) 向拥有键盘输入焦点的元素添加样式。 2
:hover (opens new window) 当鼠标悬浮在元素上方时,向元素添加样式。 1
:link (opens new window) 向未被访问的链接添加样式。 1
:visited (opens new window) 向已被访问的链接添加样式。 1
:first-child (opens new window) 向元素的第一个子元素添加样式。 2
:lang (opens new window) 向带有指定 lang 属性的元素添加样式。 2

图示:

# 动态伪类

这些伪类并不存在于HTML中,而只有当用户和网站交互的时候才能体现出来,动态伪类包含两种,

  • 第一种是我们在链接中常看到的锚点伪类,如":link",":visited";

  • 另外一种被称作用户行为伪类,如“:hover”,":active"和":focus"。

    • hover: 用于当用户把鼠标移动到元素上面时的效果
    • active: 用于用户点击元素那一下的效果(正发生在点的那一下,松开鼠标左键此动作也就完成了)
    • focus: 用于元素成为焦点,这个经常用在表单元素上

# 超链接访问过后hover样式就不出现的问题是什么?如何解决?

被点击访问过的超链接样式不在具有hover和active了,解决方法是改变CSS属性的排列顺序: L-V-H-A(link,visited,hover,active) 【love hate】

# CSS3常见伪类选择器

:nth选择器:主要注意的是CSS3添加的nth选择器在IE8下不支持。以下是常用几种;

  • fist-child: 选择某个元素的第一个子元素;
  • last-child: 选择某个元素的最后一个子元素;
  • nth-child(): 选择某个元素的一个或多个特定的子元素;
    • 参数n时选中所有行
    • 参数为n+i时表示从第i行开始下面的都被选中,如n+3,从第3行开始下面全部选中
    • 2n表示2的倍数行被选中,选中偶数行
    • 2n+1表示选中奇数行
    • 3n表示每个3行选中一次
  • :nth-of-type():可以通过参数来选择表格中的奇数行和偶数行,odd表示奇数行,even表示偶数行;

举例

/*最常见的伪类选择器, 注意这里的顺序:LVHA*/
a:link{ color: #ff6600 } /* 未被访问的链接 */
a:visited{ color: #87b291 } /* 已被访问的链接 */
a:hover{ color: #6535b2 } /* 鼠标指针移动到链接上 */
a:active{ color: #55b28e } /* 正在被点击的链接 */   	

p:first-of-type	选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
p:last-of-type	选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
p:only-of-type	选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
p:only-child		选择属于其父元素的唯一子元素的每个 <p> 元素。
p:nth-child(2)	选择属于其父元素的第二个子元素的每个 <p> 元素。
1
2
3
4
5
6
7
8
9
10
11

# CSS3属性选择器

  • a[href$='.pdf']:选择href属性中以.pdf结尾的元素
  • a[href^='www']:选择href属性中以www开头的元素
  • a[href*='tmc']:选择href属性中包含tmc的元素

# 伪元素[2:元]

伪元素控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象不存在于文档中,所以叫伪元素(:first-line :first-letter :befoe :after);

  • :before 在元素之前添加内容;
  • :after 在元素之后添加内容; 也可以用来做清除浮动。
  • ::selection::placeholder

旧语法:

属性 描述 CSS
:first-letter (opens new window) 向文本的第一个字母添加特殊样式。 1
:first-line (opens new window) 向文本的首行添加特殊样式。 1
:before (opens new window) 在元素之前添加内容。 2
:after (opens new window) 在元素之后添加内容。 2

# UI元素状态伪类

主要是针对于HTML中的Form元素操作, IE8不支持":checked",":enabled",":disabled"这三种选择器。

# 伪类和伪元素的作用和区别

简介:css引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说,伪类和伪元素都是用来修饰不在文档树中的部分。核心的区别:伪类与伪元素(有创建)的区别在于:有没有创建一个文档树之外的元素

伪类(😃:伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类(:first-child :link :visitive :hover :focus :lang)

伪元素(:😃:伪元素控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象,不存在于文档中,所以叫伪元素(:first-line :first-letter :befoe :after) 记住:伪元素是不会对文档的内容改变的,改变的只有呈现在用户面前的显示

冒号和两个冒号是区别css中的伪类(:)与伪元素(:😃。 【单类】 单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。(伪元素由双冒号和伪元素名称组成) 双冒号是在当前规范中引入的,用于区分伪类和伪元素。不过浏览器需要同时支持旧的已经存在的伪元素写法, 比如:first-line、:first-letter、:before、:after等,而新的在CSS3中引入的伪元素则不允许再支持旧的单冒号的写法。

# ::before 和 :after 中双冒号和单冒号的区别

  • 在 CSS 中伪类一直用 : 表示,如 :hover, :active 等
  • 伪元素在CSS1中已存在,当时语法是用 : 表示,如 :before 和 :after
  • 后来在CSS3中修订,伪元素用 :: 表示,如 ::before 和 ::after,以此区分伪元素和伪类
  • 由于低版本IE对双冒号不兼容,开发者为了兼容性各浏览器,继续使使用 :after 这种老语法表示伪元素
  • 综上所述:::before 是 CSS3 中写伪元素的新语法; :after 是 CSS1 中存在的、兼容IE的老语法;对于 CSS2 标准的老伪元素,比如:first-line:first-letter:before:after,写一个冒号浏览器也能识别,但对于 CSS3 标准的新伪元素,比如::selection,就必须写2个冒号了。【2元】

示例

在官方定义中规定单冒号都为伪类,是一种选择器;eg:

a:first-child{}
a:last-child {}
a:nth-of-type(2) {}
a:nth-of-type(even) {}
a:nth-of-type(odd) {}
1
2
3
4
5

而伪元素的使用中可以用单冒号和双冒号都可以实现伪元素的使用,但是较规范而言建议使用双冒号来实现。eg:

a::after {content: ""}
a::before {content: ""}
1
2

# 新特性

  • transition:过渡
  • transform:旋转、缩放、移动或者倾斜
  • animation:动画
  • gradient:渐变
  • shadow:阴影
    • 文字阴影: text-shadow: 2px 2px 2px #000;
    • (水平阴影,垂直阴影,模糊距离,阴影颜色) 盒子阴影: box-shadow: 10px 10px 5px #999
    • text-overflow 超过指定容器的边界时如何显示
    • text-decoration 文字渲染
  • border-radius:圆角
  • word-wrap 文字换行
  • gradient渐变效果
  • transition过渡效果 transition-duration:过渡的持续时间
  • transform拉伸,压缩,旋转,偏移等变换
  • animation动画

其他

新增各种CSS选择器 (: not(.input):所有 class 不是“input”的节点) 圆角 (border-radius:8px) 多列布局 (multi-column layout) 阴影和反射 (Shadow\Reflect) 文字特效 (text-shadow、) 文字渲染 (Text-decoration) 线性渐变 (gradient) 旋转 (transform)

# transition和animation的区别

Animation和transition大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是transition需要触发一个事件才能改变属性,而animation不需要触发任何事件的情况下才会随时间改变属性值,并且transition为2帧,从from .... to,而animation可以一帧一帧的。

示例: 一个拥有渐变的小球,做着横向运动,如果你鼠标移动到它上面,它的宽度会放大,并且进行倾斜。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>CSS3 新特性</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        border-radius: 50px;
        background: linear-gradient(red, orange);
        box-shadow: 10px 10px 5px #888888;
        position: relative;
        transition: width 2s;
        animation: mymove 5s infinite;
      }
      div:hover {
        width: 300px;
        transform: rotate(7deg);
      }
      @keyframes mymove {
        from {
          left: 0px;
        }
        to {
          left: 200px;
        }
      }
    </style>
  </head>
  <body>
    <div></div>
  </body>
</html>
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
31
32
33
34

# 如果需要手动写动画,你认为最小时间间隔是多久?

多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms

# requestAnimationFrame (RAF)

requestAnimationFrame 并不是定时器,但和 setTimeout 很相似,在没有 requestAnimationFrame 的浏览器一般都是用 setTimeout 模拟

requestAnimationFrame 跟屏幕刷新同步,大多数屏幕的刷新频率都是 60Hz,对应的 requestAnimationFrame 大概每隔 16.7ms 触发一次,如果屏幕刷新频率更高,requestAnimationFrame 也会更快触发。基于这点,在支持 requestAnimationFrame 的浏览器还使用 setTimeout 做动画显然是不明智的。

在不支持 requestAnimationFrame 的浏览器,如果使用 setTimeout/setInterval 来做动画,最佳延迟时间也是 16.7ms。 如果太小,很可能连续两次或者多次修改 dom 才一次屏幕刷新,这样就会丢帧,动画就会卡;如果太大,显而易见也会有卡顿的感觉

有趣的是,第一次触发 requestAnimationFrame 的时机在不同浏览器也存在差异,Edge 中,大概 16.7ms 之后触发,而 Chrome 则立即触发,跟 setImmediate 差不多。按理说 Edge 的实现似乎更符合常理。

(function testRequestAnimationFrame() {
    const label = 'requestAnimationFrame';
    console.time(label);
    requestAnimationFrame(() => {
        console.timeEnd(label);
    });
})();
1
2
3
4
5
6
7

Edge 输出:requestAnimationFrame: 16.66 毫秒

Chrome 输出:requestAnimationFrame: 0.698ms

但相邻两次 requestAnimationFrame 的时间间隔大概都是 16.7ms,这一点是一致的。当然也不是绝对的,如果页面本身性能就比较低,相隔的时间可能会变大,这就意味着页面达不到 60fps。

# calc函数

calc函数是css3新增的功能,可以使用calc()计算border、margin、pading、font-size和width等属性设置动态值。

#div1 {
    position: absolute;
    left: 50px;
    width: calc( 100% / (100px * 2) );
    //兼容写法
    width: -moz-calc( 100% / (100px * 2) );
    width: -webkit-calc( 100% / (100px * 2) );
    border: 1px solid black;
}
1
2
3
4
5
6
7
8
9

注意点:

  • 需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
  • calc()函数支持 "+", "-", "*", "/" 运算;
  • 对于不支持 calc() 的浏览器,整个属性值表达式将被忽略。不过我们可以对那些不支持 calc()的浏览器,使用一个固定值作为回退。

# SASS

# CSS 预处理器 / 后处理器

  • 预处理器 例如:LESS、Sass、Stylus,用来预编译Sass或less,增强了css代码的复用性, 还有层级、mixin、变量、循环、函数等,具有很方便的UI组件模块化开发能力,极大的提高工作效率。
  • 后处理器 例如:PostCSS, 通常被视为在完成的样式表中根据CSS规范处理CSS,让其更有效;目前最常做的 是给CSS属性添加浏览器私有前缀,实现跨浏览器兼容性的问题

# css预处理器

Less和sass等是 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性和嵌套写法,使 CSS 更易维护和扩展。

# Sass/Less/Stylus区别

  1. 什么事CSS预处理器?

    CSS预处理器是一种语言用来为CSS增加一些变成的特性,无需考虑浏览器兼容问题,例如你可以在CSS中使用变量,简单的程序逻辑、函数等在编程语言中的一些基本技巧,可以让CSS更加简洁,适应性更强,代码更直观等诸多好处

  2. 基本语法区别

    Sass是以.sass为扩展名,Less是以.less为扩展名,Stylus是以.styl为扩展名

  3. 变量的区别

    Sass 变量必须是以$开头的,然后变量和值之间使用冒号(:)隔开,和css属性是一样的

    Less 变量是以@开头的,其余sass都是一样的。

    Stylus 对变量是没有任何设定的,可以是以$开头或者任意字符,而且变量之间可以冒号,空格隔开,但是在stylus中不能用@开头

  4. 三种预处理器都有:嵌套、运算符、颜色函数、导入、继承、混入。Stylus还有一些高级特性。例如循环、判断等

# sass特性

嵌套语法、变量、@import、混入、继承、函数、逻辑控制

@import './variables.scss';
@import './mixin.scss';

@mixin clearfix { /*其他地方使用:@include clearfix;*/
  &:after {
    content: "";
    display: table;
    clear: both;
  }
}
$menuText:#bfcbd9;
1
2
3
4
5
6
7
8
9
10
11

# CSS, Sass, SCSS 关系

Sass(Syntactically Awesome Style Sheets) ,是一种css预处理器和一种语言, 它可以用来定义一套新的语法规则和函数,以加强和提升CSS. 它有很多很好的特性,但是 Sass 和 CSS 写法的确存在一定的差异,由于 Sass 是基于 Ruby 写出来,所以**其延续了 Ruby 的书写规范。在书写 Sass 时不带有大括号和分号,**其主要是依靠严格的缩进方式来控制的。

Sass它在书写规则,变量命名方面和CSS代码有着很大的区别。于是,后来官方在2010年推出了一个全新的语法,叫做SCSS, 意思是 Sassy CSS. 这个语法带来了对CSS友好的语法,试图弥合Sass和CSS之间的差别.

# scsssass的区别

简单来说,scsssass的区别,,就在于 文件扩展名不同:“.sass”和“.scss

  1. sass是以严格缩进式语法规则来书写的,不带大括号{}和分号;
  2. SCSS的语法和CSS书写语法类似
body
	color: #fff
    background: #f36

body{
    color:#fff;
    background:#f36;
}
1
2
3
4
5
6
7
8

# 连体符(&)

.clearfix:before,
.clearfix:after {
    content:"";
    display:table;
}
.clearfix:after {
    clear:both;
    overflow:hidden;
}
.clearfix {
    *zoom: 1;
1
2
3
4
5
6
7
8
9
10
11

那么在Sass中,使用&会变得更简单,更方便:

$lte-ie: true !default;
.clearfix {
    @if $lte-ie {
        *zoom: 1;
    }
 
    &:before,
    &:after {
        content: "";
        display: table;
    }
    &:after {
        clear: both;
        overflow: hidden;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# CSS Modules

为了让 CSS 也能适用软件工程方法,程序员想了各种办法,让它变得像一门编程语言。从最早的Less、SASS,到后来的 PostCSS,再到最近的 CSS in JS,都是为了解决这个问题。

CSS Modules不是将 CSS 改造成编程语言,而是功能很单纯,只加入了局部作用域和模块依赖,这恰恰是网页组件最急需的功能。

# 局部作用域

CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。

产生局部作用域的唯一方法,就是使用一个独一无二的class的名字,不会与其他选择器重名。这就是 CSS Modules 的做法。

# 全局作用域

CSS Modules 允许使用:global(.className)的语法,声明一个全局规则。凡是这样声明的class`,都不会被编译成哈希字符串。

# 定制哈希类名

css-loader默认的哈希算法是[hash:base64],这会将.title编译成._3zyde4l1yATCOkgn-DBWEL这样的字符串。

# Class 的组合

在 CSS Modules 中,一个选择器可以继承另一个选择器的规则,这称为"组合"("composition" (opens new window))。

# 输入其他模块

选择器也可以继承其他CSS文件里面的规则。

# 输入变量

CSS Modules 支持使用变量,不过需要安装 PostCSS 和 postcss-modules-values (opens new window)

# 解析原理相关

# 浏览器解析css流程

  • css 的解析是从上往下

  • 渲染顺序也是从上往下

  • 下载和渲染是同时进行的。

  • css的解析和js的解析是不能同时进行的

  • css选择器的解析是从右向左解析

    • (jQuery选择器解析方式同理)
    • 能先确定元素位置,减少匹配次数

# css放在位置

# 为什么css放在顶部而js写在后面?

  1. 浏览器预先加载css后,可以不必等待HTML加载完毕就可以渲染页面了
  2. 其实HTML渲染并不会等到完全加载完在渲染页面,而是一边解析DOM一边渲染
  3. js写在尾部,主要是因为js主要扮演事件处理的功能,一方面很多操作是在页面渲染后才执行的。另一方面可以节省加载时间,使页面能够更加的加载,提高用户的良好体验
  4. 但是随着JS技术的发展,JS也开始承担页面渲染的工作。比如我们的UI其实可以分被对待,把渲染页面的js放在前面,时间处理的js放在后面

# 兼容性

# 渐进增强与优雅降级的理解及区别

渐进增强(Progressive Enhancement):

一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。

优雅降级(Graceful Degradation):

一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。

狭义区别:渐进增强一般说的是使用CSS3技术,在不影响老浏览器的正常显示与使用情形下来增强体验,而优雅降级则是体现html标签的语义,以便在js/css的加载失败/被禁用时,也不影响用户的相应功能

.transition { /*渐进增强写法*/
  -webkit-transition: all .5s;
     -moz-transition: all .5s;
       -o-transition: all .5s;
          transition: all .5s;
}
.transition { /*优雅降级写法*/
          transition: all .5s;
       -o-transition: all .5s;
     -moz-transition: all .5s;
  -webkit-transition: all .5s;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 兼容性测试工具

  • IE Tester
  • Multibrowser

# 判断 IE 的方法

<p>===兼容问题及高效开发工具===</p>
<!--	<!--[if lt IE 8]>-->
<!--这是小于8的IE浏览器-->
<!--[if (gt IE 7)&(lt IE 10)]>
这是大于7小于9的IE浏览器
<![endif]-->
1
2
3
4
5
6

# 兼容问题

html5shiv.min.js 可在老式IE里创建main,header,footer等HTML5元素, 让IE6-8 支持 CSS3 Media Query respond.min.js 提供大量IE不支持的CSS选择器和属性,包括所有的last-child选择器。

<!--[if lt IE 9]>
 <script src="http://libs.useso.com/js/html5shiv/3.7/html5shiv.min.js"></script>
 <script src="http://libs.useso.com/js/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
1
2
3
4

# ZOOM:1的原理和作用

Zoom属性是IE浏览器的专有属性, 它可以设置或检索对象的缩放比例。

设置zoom:1可以在低版本IE下触发IE浏览器的haslayout,用于清除浮动,解决margin导致的重叠等问题

譬如外边距(margin)的重叠,譬如浮动的清除,譬如触发ie的 haslayout属性等等。

当设置了zoom的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变zoom值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题

用法:ie下子元素浮动时候父元素不随着自动扩大的问题,使用下面的CSS写法

.父元素 { overflow: auto; *zoom: 1 }

案例

例如,实现inline-block的兼容。在IE6、IE7下,只有设置在默认显示方式为inline的元素上才会生效。前面说过,当内联元素的hasLayout为true的时候,可以给这个内联元素设定高度和宽度并得到期望的效果,所以这样做可以达到兼容inline-block的效果。

display: inline-block; *display: inline; *zoom: 1;
1

*放在css属性前面,表示这个属性仅仅应用到Internet Explorer 7 以及以下版本。因为Internet Explorer 版本 7 以及以下承认非字母数字(除了下划线)前缀的属性。所以这里,IE7以上的版本作用的是display: inline-block;而在IE7及以下的版本中作用的是display:inline;zoom:1。

# 经常遇到的浏览器的兼容性

# 原因,解决方法是什么,常用hack的技巧

png24位的图片在iE6浏览器上出现背景,

解决方案是做成PNG8.

浏览器默认的margin和padding不同。

解决方案是**加一个全局的*{margin:0;padding:0;}**来统一。

IE下,可以使用获取常规属性的方法来获取自定义属性, 也可以使用getAttribute()获取自定义属性; Firefox下,只能使用getAttribute()获取自定义属性。

解决方法:统一通过getAttribute()获取自定义属性

IE下,even对象有x,y属性,但是没有pageX,pageY属性; Firefox下, event对象有pageX,pageY属性,但是没有x,y属性。

解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。

Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示;

可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决

超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了。

解决方法是改变CSS属性的排列顺序: L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}

# 问题

# 如何在页面上实现一个圆形的可点击区域?

  1. map+area或者svg
  2. border-radius
  3. 纯js实现 需要求一个点在不在圆上简单算法、获取鼠标坐标等等

# 单行和多行文字超出省略

  • 单行英文:
 overflow: hidden;
 text-overflow: ellipsis;
1
2
  • 单行中文 white-space: nowrap
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
1
2
3
  • 多行
display: -webkit-box;  
-webkit-line-clamp: 2;  
-webkit-box-orient: vertical;  
overflow: hidden;
1
2
3
4

# 内容重叠解决

第一种,取消高度height样式设置 即可实现不重叠,但内容会换行占位。 第二种,使用隐藏溢出样式单词overflow:hidden

<style> 
  ul,li{ list-style:none} 
  ul{ width:100px} 
  ul li{ float:left;width:100px; height:22px;line-height:22px; 
    text-align:left; overflow:hidden} 
</style> 
</head> 
<body> 
  <ul> 
    <li>标题一内容</li> 
    <li>测试文字多重叠标题二内容</li> 
    <li>标题三内容</li> 
  </ul> 
1
2
3
4
5
6
7
8
9
10
11
12
13

# 描述”reset”及"normalize.css"的CSS文件比较

Reset样式的目的就是清除某些浏览器的默认样式,方便css的书写:例如:*{margin:0;padding:0;list-style:none;}

normalize的理念与reset的不同,他并不是清除浏览器的默认样式,而是尽量将所有的浏览器的默认样式统一

# 为什么要初始化CSS样式

  • 因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。

  • 当然,初始化样式会对SEO有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。

  • 最简单的初始化方法: *{padding: 0; margin: 0;} (强烈不建议)

    淘宝的样式初始化代码:

body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; } body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; } h1, h2, h3, h4, h5, h6{ font-size:100%; } address, cite, dfn, em, var { font-style:normal; } code, kbd, pre, samp { font-family:couriernew, courier, monospace; } small{ font-size:12px; } ul, ol { list-style:none; } a { text-decoration:none; } a:hover { text-decoration:underline; } sup { vertical-align:text-top; } sub{ vertical-align:text-bottom; } legend { color:#000; } fieldset, img { border:0; } button, input, select, textarea { font-size:100%; } table { border-collapse:collapse; border-spacing:0; }


> #### 不使用 border 画出1px高的线,在不同浏览器的标准与怪异模式下都能保持一致效果

height(1) 及 overflow(hidden)

```html
<div style="height:1px;overflow:hidden;background:red"></div>
1
2
3
4
5
6
7

# 用纯CSS创建一个三角形的原理是什么

把上、左、右三条边隐藏掉(通过border 颜色设为 transparent

#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}
1
2
3
4
5
6
7

# margin和padding分别适合什么场景使用?

margin是用来隔开元素与元素的间距;padding是用来隔开元素与内容的间隔。 margin用于布局分开元素使元素与元素互不相干; padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段

# .css中可以让文字在垂直和水平方向上重叠的两个属性是什么?

垂直方向:line-height 水平方向: letter-spacing (单词间距) (inline-block的处理)

# 在网页中的应该使用奇数还是偶数的字体?为什么呢?

应该是用偶数字体。原因:像谷歌一些比较流行的浏览器一般会有个默认的最小字体,而且对奇数字体渲染的不太好看

# 元素竖向的百分比设定是相对于容器的高度吗?

是的,元素的百分比设置一般是根据父级元素的宽高决定的,如果父级元素没有宽高百分比是不起作用的

# CSS画圆半圆扇形三角梯形

div{
    margin: 50px;
    width: 100px;
    height: 100px;
    background: red;
}
/* 半圆 */
.half-circle{
    height: 50px;
    border-radius: 50px 50px 0 0;
}
/* 扇形 */
.sector{
    border-radius: 100px 0 0;
}
/* 三角 */
.triangle{
    width: 0px;
    height: 0px;
    background: none;
    border: 50px solid red;
    border-color: red transparent transparent transparent;
}
/* 梯形 */
.ladder{
    width: 50px;
    height: 0px;
    background: none;
    border: 50px solid red;
    border-color: red transparent transparent transparent;
}
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
31

# 参考链接

http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

上次更新: 2022/04/15, 05:41:26
×