css 常见知识整理

98 阅读40分钟

1. CSS引入

有哪些引入方式?通过link和@import引入有什么区别?

CSS引入方式有4种 内联、内嵌、外链、导入外链 link 除了可以加载css之外,还可以定义rss、rel等属性,没有兼容性问题,支持使用javascript改变样式导入@import 是css提供的,只能用于加载css,不支持通过javascript修改样式页面被加载的时候 link会被同时加载,而@import则需等到页面加载完后再加载,可能出现无样式网页

Style 标签写在 body 后和 body 前有什么区别?

一般情况下,页面加载时自上而下的。将style标签至于body之前,为的是先加载样式。若是写在body标签之后,由于浏览器以逐行方式对html文档进行解析,当解析到写在写在文档尾部的样式表时,会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后会重新渲染,在windows的IE下可能会出现FOUC现象(页面闪烁)。

什么是 FOUC(Flash of Unstyled Content)? 如何来避免 FOUC

当使用@import导入CSS时,会导致某些页面在IE出现奇怪的现象: 没有样式的页面内容显示瞬间闪烁,这种现象被称为“文档样式暂时失效”,简称FOUC。产生原因: 当样式表晚于结构性html加载时,加载到此样式表时,页面将会停止之前的渲染。等待此样式表被下载和解析后,再重新渲染页面,期间导致短暂的花屏现象。解决办法: 只要在之间加入一个或者元素即可。

2. 盒模型

盒模型分类 IE盒模型(怪异盒模型) width = border + padding + content 一个盒子的宽度 = width + margin

image.png

W3C盒模型(标准盒模型)

width = content 一个盒子的宽度 = width + padding + border + margin

image.png

盒模型转换

Css中默认的盒模型是W3C盒模型,两者间的转换可以通过设置属性box-sizing来转换 box-sizing: content-box; // W3C盒模型标准 box-sizing: border-box; // IE盒模型标准

盒子一些相关宽度

clientWidth = width+左右paddingoffsetWidth = width + 左右padding + 左右boderscrollWidth:获取指定标签内容层的真实宽度(可视区域宽度+被隐藏区域宽度)

边界塌陷

CSS 中存在一个 margin collapse,即边界塌陷或者说边界重叠。只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。

并排 DIV 边界塌陷(兄弟)

对于上下两个并排的 DIV 块而言,上面 DIV 的 margin-bottom 和下面 DIV 的 margin-top 会塌陷,会取上下两者 margin 里最大值作为显示值,只设置单个margin。

包含元素盒子塌陷(父子)

父级div中没有border,padding,inlinecontent,子级div的margin会一直向上找,直到找到某个标签包括border,padding,inline content(文本)中的其中一个,然后按此div 进行margin。

解决方法

为父盒子设置border,为外层添加border后父子盒子就不是真正意义上的贴合 (可以设置成透明:border: 1px solid transparent) 为父盒子添加overflow: hidden; 为父盒子设定padding值;为父盒子添加position:fixed;

3. 负值作用

负 marign实现元素的水平垂直居中 负 marign隐藏列表 li 首尾多余的边框 负 text-indent 实现文字的隐藏 负的 z-index 参与层叠上下文排序 定位中的left、right、top、bottom

4. css 的可以继承和不可以继承的属性有哪些

不可继承的比较多,所以主要可以记下可继承的, 不可以继承的可以记住几个常见的

可继承的

字体系列属性 font-family font-weight font-size 文本系列属性 text-align line-heightline-height color letter-spacing 元素可见性 visibility:控制元素显示隐藏 列表布局属性 list-style:列表风格,包括list-style-type、list-style-image等 cursor:光标显示为何种形态

不可以继承的

background 系列 background、background-color background-position display:规定元素应该生成的框的类型 盒子属性系列 border, padding, margin, width, height 文本系列 vertical-align white-space 定位属性:float position、top、right overflow

5. CSS选择器 以及权重

CSS选择器种类

image.png

id选择器 根据提供的唯一id号快速获取标签对象用于充当label标签for属性的值:用户名:,表示单击此label标签时,id为userid的标签获得焦点

类选择器 (class ) 标签选择器 (h1)

相邻选择器: 直接相邻元素选择器 (h1+p) 普通相邻元素选择器 (h2 ~ h2) 子选择器 (ul>li) 通配符选择器(*) 属性选择器(a[rel = "XXX"]) 伪类选择器( :hover :first-child ···) 伪元素选择器( :before :after ···)

CSS选择器优先级

网上有很多计算方法,我的看法就是 记住以下基本的排序, 其他的看实际的效果 比较准则: 优先级由高到低 !important > 内联style > ID选择器 > 类选择器 > 标签选择器 > 通配符选择器>继承

标签选择器、伪元素选择器:1 类选择器、伪类选择器、属性选择器:10 id 选择器:100 内联样式:1000

一般的比较方法

!important声明的样式的优先级最高; 如果优先级相同,则最后出现的样式生效; 继承得到的样式的优先级最低; 通用选择器(*)、子选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以它们的权值都为 0 ; 样式表的来源不同时,优先级顺序为:内联样式 > 内部样式 > 外部样式 > 浏览器用户自定义样式 > 浏览器默认样式。

6. 伪元素和伪类的区别和作用?

伪元素和伪类的概念和基本使用

伪元素:在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只在外部显示可见,但不会在文档的源代码中找到它们,因此,称为“伪”元素。例如:

p::before {content:"第一章:";}
p::after {content:"Hot!";}
p::first-line {background:red;}
p::first-letter {font-size:30px;}

伪类:将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素。例如:

a:hover {color: #FF00FF}
p:first-child {color: red}

伪元素和伪类 有哪些

CSS伪元素

::selection 选择被用户选取的元素部分 :first-line 选择元素中的第一行 :first-letter 选择元素中的第一个字符 :after 在元素在该元素之后添加内容:before 在元素在该元素之前添加内容

CSS伪类 :root 选择文档的根元素,等同于html元素 :empty 选择没有子元素的元素 :target 选取当前活动的目标元素 :not(selector) 选择除 selector 元素意外的元素 :enabled 选择可用的表单元素 :disabled 选择禁用的表单元素 :checked 选择被选中的表单元素 :first-child 选取当前选择器下第一个元素。 :last-child 和 first-child 相反,选取当前选择器下最后一个元素。 :only-child 选取唯一子元素。如果一个元素的父元素只有它一个子元素,这个伪类就会生效。如果一个元素还有兄弟元素,这个伪类就不会对它生效。 :only-of-type 选取唯一的某个类型的元素。如果一个元素的父元素里只有它一个当前类型的元素,这个伪类就会生效。这个伪类允许父元素里有其他元素,只要不和自己一样就可以。

动态伪类(使用时鼓励“LVHT”顺序) :focus 指示这个元素拥有输入“焦点”——即可以接受键盘输入,或通过某种方式可以激活 :hover 指示当鼠标停留在这个元素上时,外观可以作相应改变 :active 指示这个元素可以被用户输入“激活”,如,用户停留在一个超链接上,当点击鼠标时,这个链接就会“激活”

伪类和伪元素的根本区别

它们是否创造了新的元素(抽象)。从我们模仿其意义的角度来看,如果需要添加新元素加以标识的,就是伪元素,反之,如果只需要在既有元素上添加类别的,就是伪类。伪元素在一个选择器里只能出现一次,并且只能出现在末尾。伪类则是像真正的类一样发挥着类的作用,没有数量上的限制,只要不是相互排斥的伪类,也可以同时使用在相同的元素上。伪类用一个冒号表示 :first-child,伪元素则使用两个冒号表示 ::first-line(为了向下兼容,现在的浏览器中伪元素选择器用单冒号和双冒号都可以)。

7. BFC块级格式上下文

什么是BFC?

BFC直译为块级格式化上下文,它是一个独立的渲染区域,只有Block-level box参与,它规定了内部的Block-level Box如何布局,并且与外部毫不相干。 W3C对BFC的定义如下:浮动元素和绝对定位元素,非块级盒子的块级容器(例如,内联块,表单元格和表标题),以及溢出值不为“可见”的块级盒子,,都会为他们的内容创建新的BFC(阻止Fromatting上下文,即块级格式文本)。

注意:可以把BFC理解为一个大的盒子,其内部是由Block-level box组成的

如何触发BFC?

根元素 → 根元素(html)就是最大的BFC position设置为 fixed 或者 absolute display设置为 inline-block 、table-block 、table-caption overflow的值不为visiblefloat的值不为none

BFC布局规则:

内部的Box会在垂直方向,一个接一个地放置。Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠每个元素的margin box的左边, 与包含块的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。 BFC的区域不会与外部float box重叠。BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。计算BFC的高度时,浮动元素也参与计算

BFC的作用及原理:

自适应两栏布局清除内部浮动防止垂直 margin 重叠(将垂直方向上的盒子放在不同的 BFC 中,margin 就不会重叠了。) BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局, BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。

如何清除BFC

给 父级 overflow hidden

给 父级也变为 浮动 或者 position absolute

给 同级 末尾加空元素 clear both

给父级增加伪元素 然后clear both (比较好用的方法)

介绍下 BFC、IFC、GFC 和 FFC

  • BFC:块级格式上下文,指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。

  • IFC:行内格式化上下文,将一块区域以行内元素的形式来格式化。

  • GFC:网格布局格式化上下文,将一块区域以 grid 网格的形式来格式化

  • FFC:弹性格式化上下文,将一块区域以弹性盒的形式来格式化

8. 几个常见属性的讲解 position float display flex

position

relative: 元素的定位永远是相对于元素自身位置的,和其他元素没关系,也不会影响其他元素。 absolute: 元素的定位相对于前两者要复杂许多。如果为 absolute 设置了 top、left,浏览器会根据什么去确定它的纵向和横向的偏移量呢?答案是浏览器会递归查找该元素的所有父元素,如果找到一个设置了position:relative/absolute/fixed的元素,就以该元素为基准定位,如果没找到,就以浏览器边界定位。 fixed: 元素的定位是相对于 window (或者 iframe)边界的,和其他元素没有关系。但是它具有破坏性,会导致其他元素位置的变化。 static: 默认值,没有定位,元素出现在正常的文档流中,会忽略 top, bottom, left, right 或者 z-index 声明,块级元素从上往下纵向排布,⾏级元素从左向右排列。

sticky: 英文字面意思是粘贴,所以可以把它称之为粘性定位。语法:position: sticky; 基于用户的滚动位置来定位。 粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。

float浮动

有两个取值:left(左浮动)和right(右浮动)。浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

优点

最初的优点就是在图文混排的时候可以很好的使文字周围在图片周围。另外当元素浮动了起来之后,它具有块级元素的一些性质例如可以设置宽高等,但它与inline- block还是有一些区别的,第一个就是关于横向排序的时候,float可以设置方向而inline-block方向是固定的;还有一个就是inline-block在使用时有时会有空白间隙的问题。

缺点

最明显的缺点就是浮动元素一旦脱离了文档流,就无法撑起父元素,会造成父级元素高度塌陷为0(盒子塌陷)。▲ 注意:设置元素浮动后,该元素的display值会变为block

清除浮动(*)

盒子大小写死,给每个盒子设定固定的width和height,直到合适为止,非自适应父级元素设置高度父级元素触发BFC(Float,Overflow: Hidden | Visible,Display: Flex | Grid)

添加额外标签

<div class="parent">    //添加额外标签并且添加clear属性    
    <div class="f"></div>   
</div>
<div style="clear:both"></div>

建立伪类选择器清除浮动(推荐) //添加:after伪元素

.parent:after{    
    content: ''; /* 设置添加子元素的内容是空 */  
    display: block; /* 设置添加子元素为块级元素 */       
    height: 0; /* 设置添加的子元素的高度0 */     
    visibility: hidden; /* 设置添加子元素看不见 */     
    clear: both; /* 设置clear:both */
}
<div class="parent">    
    <div class="f"></div>
</div>

display

none 元素会被隐藏,不显示 inline 元素会被设置为内联元素,内部按行从左向右排列(元素前后没有换行符) block 元素会被设置为块级元素,内部按列从上到下排列(元素前后带有换行符) inline-block 元素会被设置为行内块级元素,不会独占一行的块级元素 list-item 元素会作为列表显示 table 元素会作为块级表格来显示(类似table),表格前后带有换行符 flex 元素会进入flex布局模式

inline、block、inline-block三者区别

block块级特点:

每个块级元素都从新的一行开始,并且其后的元素也另起一行。(一个块级元素独占一行)元素的高度、宽度、行高以及顶和底边距都可设置。元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。

inline内联特点:

和其他元素都在一行上;元素的高度、宽度及顶部和底部边距不可设置;元素的宽度就是它包含的文字或图片的宽度,不可改变。

inline-block 特点:

inline-block内联块状元素同时具备内联元素、块状元素的特点。和其他元素都在一行上;元素的高度、宽度、行高以及顶和底边距都可设置。

使用 display:inline-block 会产生什么问题?又如何解决?(*)

两个inline-block元素放到一起会产生一段空白。

产生空白的原因

元素被当成行内元素放置的时候,元素之间的空白符(空格,回车换行等)都会被浏览器处理,根据CSS中空白属性的处理方式(否则是正常,合并多余空白),原来HTML代码中的回车换行被转成一个空白符,在字体不为0的情况下,空白符较长一定长度,所以inline-block的元素之间就出现了空隙。

解决办法

将子元素标签的结束符和下一个标签的开始符写在同一行或把所有子标签写在同一行父元素中设置字体大小:0,在子元素上重置正确的字体大小为子元素设置float:left

flex布局

该布局提供了一种更高效的方法对容器中的项目进行布局、对齐和分配空间,他没有方向上的限制,可以由开发人员自由操作(子元素的 vertical-align、float、clear 属性会失效)。

容器属性(6个)

flex-direction 决定主轴方向(容器排列方向) flex-direction: row | row-reverse | column | column-reverse;

flex-wrap 如果一条轴线排不下,定义换行规则 flex-wrap: nowrap | wrap | wrap-reverse;

flex-flow flex-direction和flex-wrap的简写形式 flex-flow: flex-direction||flex-wrap;

justify-content 定义容器在主轴上的对齐方式 justify-content: flex-start | flex-end | center | space-between | space-around;

align-items 定义容器在交叉轴上的对齐方式 align-items: flex-start | flex-end | center | baseline | stretch;

align-content 定义多根轴线的对齐方式,如果容器只有一根轴线,该属性不起作用 align-content: flex-start | flex-end | center | space-between | space-around |;

项目属性(6个)

order 定义项目的排列顺序,数值越小,排列越靠前,默认为0

flex-grow 定义项目的放大比例,默认为0(即如果存在剩余空间,也不放大)

flex-shrink 定义项目的缩小比例,默认为1(即如果空间不足,该项目将缩小)

flex-basis 定义了在分配多余空间之前,项目占据的主轴空间。默认值为auto(项目本来大小)

align-self允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性,默认值为auto(表示继承父元素align-items属性,如果没有父元素,等同于stretch)

align-self: auto | flex-start | flex-end | center | baseline | stretch;

flex 是flex-grow、flex-shrink和flex-basis的简写,默认值为 0 1 auto flex: none | [ 'flex-grow' 'flex-shrink'? || 'flex-basis']该属性有两个快捷值: auto(1 1 auto) 和 none(0 0 auto)

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值

简单来说: flex布局是CSS3新增的一种布局方式,可以通过将一个元素的display属性值设置为flex从而使它成为一个flex容器,它的所有子元素都会成为它的项目。一个容器默认有两条轴:一个是水平的主轴,一个是与主轴垂直的交叉轴。可以使用flex-direction来指定主轴的方向。可以使用justify-content来指定元素在主轴上的排列方式,使用align-items来指定元素在交叉轴上的排列方式。还可以使用flex-wrap来规定当一行排列不下时的换行方式。对于容器中的项目,可以使用order属性来指定项目的排列顺序,还可以使用flex-grow来指定当排列空间有剩余的时候,项目的放大比例,还可以使用flex-shrink来指定当排列空间不足时,项目的缩小比例。

display、float、position的关系

(1)首先判断display属性是否为none,如果为none,则position和float属性的值不影响元素最后的表现。 (2)然后判断position的值是否为absolute或者fixed,如果是,则float属性失效,并且display的值应该被设置为table或者block,具体转换需要看初始转换值。 (3)如果position的值不为absolute或者fixed,则判断float属性的值是否为none,如果不是,则display的值则按上面的规则转换。注意,如果position的值为relative并且float属性的值存在,则relative相对于浮动后的最终位置定位。 (4)如果float的值为none,则判断元素是否为根元素,如果是根元素则display属性按照上面的规则转换,如果不是,则保持指定的display属性值不变。 总的来说,可以把它看作是一个类似优先级的机制,"position:absolute"和"position:fixed"优先级最高,有它存在的时候,浮动不起作用,'display'的值也需要调整;其次,元素的'float'特性的值不是"none"的时候或者它是根元素的时候,调整'display'的值;最后,非根元素,并且非浮动元素,并且非绝对定位的元素,'display'特性值同设置值。

9. 页面布局 两栏布局 三栏布局 双飞翼布局 圣杯布局

两栏布局的实现

左边一栏宽度固定,右边一栏宽度自适应,两栏布局的具体实现: 利用浮动,将左边元素宽度设置为200px,并且设置向左浮动。将右边元素的margin-left设置为200px,宽度设置为auto(默认为auto,撑满整个父元素)。

.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  background: tomato;
}
.right {
  margin-left: 200px;
  width: auto;
  background: gold;
}

利用flex布局,将左边元素设置为固定宽度200px,将右边的元素设置为flex:1。

.outer {
  display: flex;
  height: 100px;
}
.left {
  width: 200px;
  background: tomato;
}
.right {
  flex: 1;
  background: gold;
}

利用绝对定位,将父级元素设置为相对定位。左边元素宽度设置为200px,右边元素设置为绝对定位,左边定位为200px,其余方向定位为0。

三栏布局的实现

左右两栏宽度固定,中间自适应的布局,三栏布局的具体实现: 利用绝对定位,左右两栏设置为绝对定位,中间设置对应方向大小的margin的值。

利用flex布局,左右两栏设置固定大小,中间一栏设置为flex:1。

.outer {
  display: flex;
  height: 100px;
}

.left {
  width: 100px;
  background: tomato;
}

.right {
  width: 100px;
  background: gold;
}

.center {
  flex: 1;
  background: lightgreen;
}

利用浮动,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式**,中间一栏必须放到最后:**

.outer {
  height: 100px;
}

.left {
  float: left;
  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  float: right;
  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  height: 100px;
  margin-left: 100px;
  margin-right: 200px;
  background: lightgreen;
}

圣杯布局

1.经典方法 (浮动)

    * {
        margin: 0;
        padding: 0;
    }
    .header,.footer {
        height: 100px;
        background: #000;
        color:seashell;
    }
    .main {
        height: 400px;
        background: #ccc;
    }
    .content {
        height: 400px;
        background: #f90;
        float: left;
        width: 100%;
    }
    .left {
        width: 300px;
        height: 400px;
        background: purple;
        float: left;
        margin-left: -100%;
    }
    .right {
        width: 300px;
        height: 400px;
        background: seagreen;
        float: left;
        margin-left: -300px;
    }

这个方法中首先在main这个父盒子中不按常规的思维,将content放在最上面(常规思维应该是left在最上面),这也是这个方法的妙处之一。首先main里面的三个盒子都设置为左浮动,然后设置content的width为100%,最后用margin-left将left和right两个盒子分列content左右,也就实现了圣杯布局。

2.flex布局

    * {
        margin: 0;
        padding: 0;
    }
    .header,.footer {
        height: 100px;
        background: #000;
        color:seashell;
    }
    .main {
        height: 400px;
        background: #ccc;
        display: flex;
    }
    .content {
        height: 400px;
        background: #f90;
        flex: auto;
    }
    .left {
        width: 300px;
        height: 400px;
        background: purple;
        flex: none;
    }
    .right {
        width: 300px;
        height: 400px;
        background: seagreen;
        flex: none;
    }

相比于第一种方法,用flex符合属性来做就轻松很多,就加了四行代码,main变为伸缩盒子,content,left,right依次设为flex:auto; flex:none; flex:none;

3.觉得可以绝对定位实现

4. float + position

或者 float left float right 然后 center position absolute left :200px right :200px

个人觉得 flex 布局超好用

双飞翼布局

双飞翼布局的实现 left、center、right三种都设置左浮动 设置center宽度为100% 设置负边距,left设置负边距为100%,right设置负边距为自身宽度 设置content的margin值为左右两个侧栏留出空间,margin值大小为left和right宽度

10. 元素居中的 几种方法

translate

利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心。该方法需要考虑浏览器兼容问题。

.parent {    position: relative;} .child {    position: absolute;    left: 50%;    top: 50%;    transform: translate(-50%,-50%);}

margin 为auto

利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。该方法适用于盒子有宽高的情况

.parent {
    position: relative;
}
 
.child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

flex align-items:center justify-content:center

使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。该方法要考虑兼容的问题,该方法在移动端用的较多:

11. 常见的实现 画正方形 三角形

三角形

CSS绘制三角形主要用到的是border属性,也就是边框。

平时在给盒子设置边框时,往往都设置很窄,就可能误以为边框是由矩形组成的。实际上,border属性是右三角形组成的,下面看一个例子:

div {
    width: 0;
    height: 0;
    border: 100px solid;
    border-color: orange blue red green;
}

image.png

所以可以根据border这个特性来绘制三角形: (1)三角1

div {
    width: 0;
    height: 0;
    border-top: 50px solid red;
    border-right: 50px solid transparent;
    border-left: 50px solid transparent;
}

正方形

1. 伪元素设置 margin-top

伪元素设置 margin-top

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .inner {
        width: 100px;
        overflow: hidden;
        background: blue;
      }

      .inner::after {
        content: "";
        margin-top: 100%;
        display: block;
      }
    </style>
  </head>
  <body>
    <div class="outer">
      <div class="inner"></div>
    </div>
  </body>
</html>

写好宽高

.inner {
    width: 1vw;
    height: 1vw;
    background: blue;
    }

padding 撑高画正方形

.outer {
        width: 400px;
        height: 600px;
        background: blue;
      }

      .inner {
        width: 100%;
        height: 0;
        padding-bottom: 100%;
        background: red;
      }

12. 媒体查询

属性简介

基于一个或多个 媒体查询 的结果来应用样式表的一部分。就是可以根据不同的媒体类型定义不同的样式。 当页面需要响应式布局时,@media 是非常有用的。因为浏览器重置大小时,页面也会根据浏览器的宽度和高度重新渲染页面,使@media重新计算是否加载样式。

样例:

/* screen 当设备是 电脑屏幕,平板电脑,智能手机等。并且 width > 900px 使用 .article 样式块  */
@media screen and (min-width: 900px) {
  .article {
    padding: 1rem 3rem;
  }
}

@media 规则可置于您代码的顶层或位于其它任何@条件规则组内。

媒体类型

描述了设备的类别。媒体类型是可选的,默认是all类型。

all 所有设备上都加载。 print 在打印预览模式下在屏幕上查看的分页材料和文档中加载。 screen 电脑屏幕,平板电脑,智能手机等,中加载。 speech 屏幕阅读器等发声设备中加载。

CSS2.1和媒体查询3定义了几种其他媒体类型(tty,tv,projection,handheld,braille,embossed,和aural),现在基本上已经弃用。

逻辑运算符

逻辑运算符 not,and以及only可以被用于组成一个复杂的媒体查询。还可以通过用逗号分隔多个媒体查询来将它们合并为一个规则。

not 用于媒体查询取反值,如果媒体查询返回 false,则返回 true。如果出现在以逗号分隔的查询列表中,它只会在当前范围中取反。如果使用not运算符,还必须指定媒体类型。

    /* 在 screen 类型 加载  */
    @media screen {
      .box {
        background-color: red;
      }
    }
    /* 取反 */
    @media not screen {
      .box1 {
        background-color: red;
      }
    }

and 用于将多个媒体特征组合到一个媒体查询中。它还用于将媒体功能与媒体类型连接起来。

    /* 在 screen 类型 大于960px 加载  */
    @media screen and (min-width: 560px) {
      .box {
        background-color: red;
      }
    }
    /* 在 screen 类型 大于960px 小于 1200px 加载 */
    @media screen and (min-width: 560px) and (max-width: 700px) {
      .box1 {
        background-color: burlywood;
      }
    }

and 用于将多个媒体特征组合到一个媒体查询中。它还用于将媒体功能与媒体类型连接起来。

    /* 在 screen 类型 大于960px 加载  */
    @media screen and (min-width: 560px) {
      .box {
        background-color: red;
      }
    }
    /* 在 screen 类型 大于960px 小于 1200px 加载 */
    @media screen and (min-width: 560px) and (max-width: 700px) {
      .box1 {
        background-color: burlywood;
      }
    }

, (逗号) 逗号用于将多个媒体查询组合成一个规则。逗号分隔列表中的每个查询都与其他查询分开处理。因此,如果列表中的任何查询为真,则整个媒体语句返回真。换句话说,列表的行为就像一个逻辑or运算符。

    /* 在 screen 类型 小于240px 或 大于240px 加载  */
    @media screen and (min-width: 560px), (max-width: 240px) {
      .box {
        background-color: red;
      }
    }
    /* 在 screen 类型 小于 240px 或 大于360px 小于 700px 加载 */
    @media screen and (max-width: 240px), (min-width: 360px) and (max-width: 700px) {
      .box1 {
        background-color: burlywood;
      }
    }

媒体功能

根据属性判断当前使用 css 所在的设备,或是浏览环境的具体特征。表达式是可选的,它负责判断这些特性或特征是否存在、值为多少。每条媒体特性表达式都必须用括号括起来。

常用媒体:

height 输出设备中的页面可见区域高度。 width 输出设备中的页面可见区域宽度。 max-aspect-ratio 输出设备的屏幕可见宽度与高度的最大比率。 max-device-aspect-ratio 输出设备的屏幕可见宽度与高度的最大比率。 max-device-height 输出设备的屏幕可见的最大高度。 max-device-width 输出设备的屏幕最大可见宽度。 max-height 输出设备中的页面最大可见区域高度。 max-width 输出设备中的页面最大可见区域宽度。 min-height 输出设备中的页面最小可见区域高度。 min-width 输出设备中的页面最小可见区域宽度。

其他加载方式

style标签上加载

<style media="(min-width: 500px)">
  .box {
    background-color: red;
  }
</style>
<style media="(max-width: 500px">
  .box {
    background-color: burlywood;
  }
</style>

根据media属性定义的媒体查询判断加载那个样式。

@import 使用时加载

@import url(./index.css) (min-width:350px); @import url(./home.css) (max-width:750px); 复制代码

在加载最后添加()定义媒体查询判断加载那个样式。

<picture>标签
<picture>
  <source media="(min-width: 650px)" srcset="demo1.jpg">
  <source media="(min-width: 465px)" srcset="demo2.jpg">
  <img src="img_girl.jpg">
</picture>

根据屏幕匹配的不同尺寸显示不同图片,如果没有匹配到或浏览器不支持 picture 属性则使用 img 元素:

13. 介绍下粘性布局(sticky)

position 中的 sticky 值是 CSS3 新增的,设置了 sticky 值后,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。 sticky 属性值有以下几个特点:

该元素并不脱离文档流,仍然保留元素原本在文档流中的位置。 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动。 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量

14. CSS3 中 transition 和 animation 的属性分别有哪些

transition 过渡动画:

transition-property:指定过渡的 CSS 属性 transition-duration:指定过渡所需的完成时间 transition-timing-function:指定过渡函数 transition-delay:指定过渡的延迟时间

animation 关键帧动画:

animation-name:指定要绑定到选择器的关键帧的名称 animation-duration:动画指定需要多少秒或毫秒完成 animation-timing-function:设置动画将如何完成一个周期 animation-delay:设置动画在启动前的延迟间隔 animation-iteration-count:定义动画的播放次数 animation-direction:指定是否应该轮流反向播放动画 animation-fill-mode:规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式 animation-play-state:指定动画是否正在运行或已暂停

15. 重排和重绘

如何触发重排和重绘?

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

添加、删除、更新DOM节点 通过display: none隐藏一个DOM节点-触发重排和重绘 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化 移动或者给页面中的DOM节点添加动画 添加一个样式表,调整样式属性 用户行为,例如调整窗口大小,改变字号,或者滚动。

重绘与重排的区别?

重排: 部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素 重绘: 由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变 单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分 重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。 『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。

16. 如何优化图片

  1. 对于很多装饰类图片,尽量不用图片,因为这类修饰图片完全可以用 CSS 去代替。

  2. 对于移动端来说,屏幕宽度就那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应裁剪好的图片。

  3. 小图使用 base64 格式

  4. 将多个图标文件整合到一张图片中(雪碧图)

  5. 选择正确的图片格式:

对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好 小图使用 PNG,其实对于大部分图标这类图片,完全可以使用 SVG 代替 照片使用 JPEG

17.CSS3 新增东西

这里列举出一些关键的新增内容:

选择器

盒子模型属性:border-radius、box-shadow、border-image

背景:background-size、background-origin、background-clip

文本效果:text-shadow、word-wrap

颜色:新增 RGBA,HSLA 模式

渐变:线性渐变、径向渐变

字体:@font-face

2D/3D转换:transform、transform-origin

过渡与动画:transition、@keyframes、animation

多列布局

媒体查询

18. 居中为什么要使用 transform(为什么不使用 marginLeft/Top)(阿里)

transform 属于合成属性(composite property),对合成属性进行 transition/animation 动画将会创建一个合成层(composite layer),这使得被动画元素在一个独立的层中进行动画。通常情况下,浏览器会将一个层的内容先绘制进一个位图中,然后再作为纹理(texture)上传到 GPU,只要该层的内容不发生改变,就没必要进行重绘(repaint),浏览器会通过重新复合(recomposite)来形成一个新的帧。 top/left属于布局属性,该属性的变化会导致重排(reflow/relayout),所谓重排即指对这些节点以及受这些节点影响的其它节点,进行CSS计算->布局->重绘过程,浏览器需要为整个层进行重绘并重新上传到 GPU,造成了极大的性能开销。

19. 对 CSS 工程化的理解

CSS 工程化是为了解决以下问题:

宏观设计:CSS 代码如何组织、如何拆分、模块结构怎样设计? 编码优化:怎样写出更好的 CSS? 构建:如何处理我的 CSS,才能让它的打包结果最优? 可维护性:代码写完了,如何最小化它后续的变更成本?如何确保任何一个同事都能轻松接手?

以下三个方向都是时下比较流行的、普适性非常好的 CSS 工程化实践:

预处理器:Less、 Sass 等; 重要的工程化插件: PostCss; Webpack loader 等 。

基于这三个方向,可以衍生出一些具有典型意义的子问题,这里我们逐个来看:

(1)预处理器:为什么要用预处理器?它的出现是为了解决什么问题?

预处理器,其实就是 CSS 世界的“轮子”。预处理器支持我们写一种类似 CSS、但实际并不是 CSS 的语言,然后把它编译成 CSS 代码:

那为什么写 CSS 代码写得好好的,偏偏要转去写“类 CSS”呢?这就和本来用 JS 也可以实现所有功能,但最后却写 React 的 jsx 或者 Vue 的模板语法一样——为了爽!要想知道有了预处理器有多爽,首先要知道的是传统 CSS 有多不爽。随着前端业务复杂度的提高,前端工程中对 CSS 提出了以下的诉求:

宏观设计上:我们希望能优化 CSS 文件的目录结构,对现有的 CSS 文件实现复用; 编码优化上:我们希望能写出结构清晰、简明易懂的 CSS,需要它具有一目了然的嵌套层级关系,而不是无差别的一铺到底写法;我们希望它具有变量特征、计算能力、循环能力等等更强的可编程性,这样我们可以少写一些无用的代码; 可维护性上:更强的可编程性意味着更优质的代码结构,实现复用意味着更简单的目录结构和更强的拓展能力,这两点如果能做到,自然会带来更强的可维护性。

这三点是传统 CSS 所做不到的,也正是预处理器所解决掉的问题。预处理器普遍会具备这样的特性:

嵌套代码的能力,通过嵌套来反映不同 css 属性之间的层级关系 ; 支持定义 css 变量; 提供计算函数; 允许对代码片段进行 extend 和 mixin; 支持循环语句的使用; 支持将 CSS 文件模块化,实现复用。

(2)PostCss:PostCss 是如何工作的?我们在什么场景下会使用 PostCss?

它和预处理器的不同就在于,预处理器处理的是 类CSS,而 PostCss 处理的就是 CSS 本身。Babel 可以将高版本的 JS 代码转换为低版本的 JS 代码。PostCss 做的是类似的事情:它可以编译尚未被浏览器广泛支持的先进的 CSS 语法,还可以自动为一些需要额外兼容的语法增加前缀。更强的是,由于 PostCss 有着强大的插件机制,支持各种各样的扩展,极大地强化了 CSS 的能力。 PostCss 在业务中的使用场景非常多:

提高 CSS 代码的可读性:PostCss 其实可以做类似预处理器能做的工作; 当我们的 CSS 代码需要适配低版本浏览器时,PostCss 的 Autoprefixer 插件可以帮助我们自动增加浏览器前缀; 允许我们编写面向未来的 CSS:PostCss 能够帮助我们编译 CSS next 代码;

(3)Webpack 能处理 CSS 吗?如何实现?

Webpack 能处理 CSS 吗:

Webpack 在裸奔的状态下,是不能处理 CSS 的,Webpack 本身是一个面向 JavaScript 且只能处理 JavaScript 代码的模块化打包工具; Webpack 在 loader 的辅助下,是可以处理 CSS 的。

如何用 Webpack 实现对 CSS 的处理:

Webpack 中操作 CSS 需要使用的两个关键的 loader:css-loader 和 style-loader 注意,答出“用什么”有时候可能还不够,面试官会怀疑你是不是在背答案,所以你还需要了解每个 loader 都做了什么事情:

css-loader:导入 CSS 模块,对 CSS 代码进行编译处理; style-loader:创建style标签,把 CSS 内容写入标签。

在实际使用中,css-loader 的执行顺序一定要安排在 style-loader 的前面。因为只有完成了编译过程,才可以对 css 代码进行插入;若提前插入了未编译的代码,那么 webpack 是无法理解这坨东西的,它会无情报错。

20. 如何判断元素是否到达可视区域

以图片显示为例:

window.innerHeight 是浏览器可视区的高度; document.body.scrollTop || document.documentElement.scrollTop 是浏览器滚动的过的距离; imgs.offsetTop 是元素顶部距离文档顶部的高度(包括滚动条的距离); 内容达到显示区域的:img.offsetTop < window.innerHeight + document.body.scrollTop;

image.png

21. 常见的其他面试题

Q1: 使用 clear 属性清除浮动的原理?

使用clear属性清除浮动,其语法如下: clear:none|left|right|both

如果单看字面意思,clear:left 是“清除左浮动”,clear:right 是“清除右浮动”,实际上,这种解释是有问题的,因为浮动一直还在,并没有清除。 官方对clear属性解释:“元素盒子的边不能和前面的浮动元素相邻”,对元素设置clear属性是为了避免浮动元素对该元素的影响,而不是清除掉浮动。 还需要注意 clear 属性指的是元素盒子的边不能和前面的浮动元素相邻,注意这里“前面的”3个字,也就是clear属性对“后面的”浮动元素是不闻不问的。考虑到float属性要么是left,要么是right,不可能同时存在,同时由于clear属性对“后面的”浮动元素不闻不问,因此,当clear:left有效的时候,clear:right必定无效,也就是此时clear:left等同于设置clear:both;同样地,clear:right如果有效也是等同于设置clear:both。由此可见,clear:left和clear:right这两个声明就没有任何使用的价值,至少在CSS世界中是如此,直接使用clear:both吧。

一般使用伪元素的方式清除浮动:

.clear::after{ content:''; display: block; clear:both;}

clear属性只有块级元素才有效的,而::after等伪元素默认都是内联水平,这就是借助伪元素清除浮动影响时需要设置display属性值的原因。

Q2: display:none 与 visibility:hidden 的区别是什么?

display:none  隐藏对应的元素,在文档布局中不再分配空间(导致重排)visibility:hidden  隐藏对应的元素,在档布局中保留原来的空间(导致重绘)前者会使元素及其后代全部隐藏;后者具有继承性,子代会保持 hidden 的状态,但也可以单独设置为 visibility: visible 进行显示。

Q3:border:none;与border:0;有什么区别?

性能差异:

{border:0;}: 把border设置为0像素,虽然在页面上看不到,但是按border默认值理解,浏览器依然对border-width/border-color进行了渲染,即已经占用内存值;{border:none;}被理解为border-style:none。boder:0;比border:none多渲染了一个border-width:0,也就是为什么border:none的性能要比border:0高;

兼容性差异:

{border:none;}当border为“none”时似乎对IE6/7无效边框依然存在当border为“0”时,感觉比“none”更有效,所有浏览器都一致把边框隐藏。

Q4:px | em| REM 有什么区别?

PXpx像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。EMem的值并不是固定的, em会继承父级元素的字体大小。(浏览器body中1em=16px)

body选择器中声明Font-size=62.5%;将你的原来的px数值除以10,然后换上em作为单位;重新计算那些被放大的字体的em数值。避免字体大小的重复声明。 REM(css3新增)使用rem相对的只是HTML根元素。集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。 EX(不推荐)

ex 是一个相对长度单位,1ex 被定义为一种给定字体的小写字母 “x” 的高度。因此,这个值会随字体的不同而变化。然而,很多浏览器都没有内置 ex 高度值,只是简单的取 em 的值,再取其一半作为 ex 的值。所以,一般不推荐使用 ex 这个长度单位。 选择使用什么字体单位主要由你的项目来决定,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者两者同时使用。

Q5:视口单位 vw、vh、vmin、vmax

vw 视口宽度的1/100。vh 视口高度的1/100。vmin vw 和 vh 中的最小值。vmax vw 和 vh 中的最大值。

好文链接

juejin.cn/post/685457…

juejin.cn/post/690553…

参考

juejin.cn/post/690553… juejin.cn/post/709868… juejin.cn/post/714971…