Skip to content

CSS 面试题上

<font style="background:#F8CED3;color:#70000D">面试题</font> <font style="background:#DBF1B7;color:#2A4200">CSS</font>

1.介绍一下标准的 CSS 的盒子模型?低版本 IE 的盒子模型有什么不同的?

相关知识点

(1)有两种盒子模型:IE 盒模型(border-box)、W3C 标准盒模型(content-box)

(2)盒模型:分为内容(content)、填充(padding)、边界(margin)、边框(border)四个部分

IE 盒模型和 W3C 标准盒模型的区别:

(1)W3C 标准盒模型:属性 widthheight只包含内容content,不包含borderpadding

(2)IE 盒模型:属性 widthheight包含contentborderpadding,指的是content+padding+border

在 ie8+ 浏览器中使用哪个盒模型可以由 box-sizing(CSS 新增的属性)控制,默认值为 content-box,即标准盒模型;

如果将 box-sizing 设为 border-box 则用的是 IE 盒模型。如果在 ie6,7,8 中 DOCTYPE 缺失会将盒子模型解释为 IE 盒子模型。若在页面中声明了 DOCTYPE 类型,所有的浏览器都会把盒模型解释为 W3C 盒模型。

回答

盒模型都是由四个部分组成的,分别是 marginborderpaddingcontent

标准盒模型和 IE 盒模型的区别在于设置 widthheight时,所对应的范围不同。标准盒模型的widthheight属性的范围只包含了content,而 IE 盒模型的widthheight属性的范围包含了borderpaddingcontent

一般来说,可以通过修改元素的 box-sizing 属性来改变元素的盒模型。

2.CSS 选择符有哪些?

(1)id 选择器(#myid

(2)类选择器(.myclassname

(3)标签选择器(divh1p

(4)后代选择器(h1 p

(5)相邻后代选择器(子)选择器(ul>li

(6)兄弟选择器(li~a

(7)相邻兄弟选择器(li+a

(8)属性选择器(a[rel="external"]

(9)伪类选择器(a:hover,li:nth-child

(10)伪元素选择器(::before::after

(11)通配符选择器(*

3.::before:after 中双冒号和单冒号有什么区别?解释一下这 2 个伪元素的作用。

相关知识点

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

想让插入的内容出现在其它内容前,使用 ::before,否者,使用::after;在代码顺序上,::after生成的内容也比::before 生成的内容靠后。

如果按堆栈视角,::after生成的内容会在 ::before 生成的内容之上。

回答

在 css3 中使用单冒号来表示伪类,用双冒号来表示伪元素。但是为了兼容已有的伪元素的写法,在一些浏览器中也可以使用单冒号来表示伪元素。

伪类一般匹配的是元素的一些特殊状态,如 hoverlink等,而伪元素一般匹配的特殊的位置,比如afterbefore 等。

4.伪类与伪元素的区别

css 引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说,伪类和伪元素是用来修饰不在文档树中的部分,比如,一句话中的第一个字母,或者是列表中的第一个元素。

伪类用于当已有的元素处于某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,可以通过 :hover 来描述这个元素的状态。

伪元素用于创建一些不在文档树中的元素,并为其添加样式。它们允许为元素的某些部分设置样式。比如说,可以通过 ::before 来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。

有时会发现伪元素使用了两个冒号(::)而不是一个冒号(:)。这是 CSS3 的一部分,并尝试区分伪类和伪元素。大多数浏览器都支持这两个值。按照规则应该使用(::)而不是(:),从而区分伪类和伪元素。但是,由于在旧版本的 W3C 规范并未对此进行特别区分,因此目前绝大多数的浏览器都支持使用这两种方式表示伪元素。

5.CSS 中哪些属性可以继承?

相关资料

每个 CSS 属性定义的概述都指出了这个属性是默认继承的,还是默认不继承的。这决定了当没有为元素的属性指定值时该如何计算值。

当元素的一个继承属性没有指定值时,则取父元素的同属性的计算值。只有文档根元素取该属性的概述中给定的初始值(这里的意思应该是在该属性本身的定义中的默认值)。

当元素的一个非继承属性(在 Mozilla code 里有时称之为 reset property)没有指定值时,则取属性的初始值 initial value(该值在该属性的概述里被指定)。

有继承性的属性:

(1)字体系列属性

fontfont-familyfont-weightfont-sizefont-stylefont-variantfont-stretchfont-size-adjust

(2)文本系列属性

text-indenttext-aligntext-shadowline-heightword-spacingletter-spacing

text-transformdirectioncolor

(3)表格布局属性

caption-side border-collapse empty-cells

(4)列表属性

list-style-typelist-style-imagelist-style-positionlist-style

(5)光标属性

cursor

(6)元素可见性

visibility

(7)还有一些不常用的;speak,page,设置嵌套引用的引号类型 quotes 等属性

注意:当一个属性不是继承属性时,可以使用 inherit 关键字指定一个属性应从父元素继承它的值,inherit 关键字用于显式地指定继承性,可用于任何继承性/非继承性属性。

回答

每一个属性在定义中都给出了这个属性是否具有继承性,一个具有继承性的属性会在没有指定值的时候,会使用父元素的同属性的值来作为自己的值。

一般具有继承性的属性有,字体相关的属性,font-sizefont-weight等。文本相关的属性,colortext-align 等。

表格的一些布局属性、列表属性如 list-style 等。还有光标属性cursor、元素可见性visibility

当一个属性不是继承属性的时候,也可以通过将它的值设置为 inherit 来使它从父元素那获取同名的属性值来继承。

6.CSS 优先级算法如何计算?

相关知识点

CSS 的优先级是根据样式声明的特殊性值来判断的。

选择器的特殊性值分为四个等级,如下:

(1)标签内选择符 x,0,0,0

(2)ID 选择符 0,x,0,0

(3)class 选择符/属性选择符/伪类选择符 0,0,x,0

(4)元素和伪元素选择符 0,0,0,x

计算方法:

(1)每个等级的初始值为 0

(2)每个等级的叠加为选择器出现的次数相加

(3)不可进位,比如 0,99,99,99

(4)依次表示为:0,0,0,0

(5)每个等级计数之间没关联

(6)等级判断从左向右,如果某一位数值相同,则判断下一位数值

(7)如果两个优先级相同,则最后出现的优先级高,!important 也适用

(8)通配符选择器的特殊性值为:0,0,0,0

(9)继承样式优先级最低,通配符样式优先级高于继承样式

(10)!important(权重),它没有特殊性值,但它的优先级是最高的,为了方便记忆,可以认为它的特殊性值为 1,0,0,0,0。

计算实例:

(1)#demo a{color: orange;}/特殊性值:0,1,0,1/

(2)div#demo a{color: red;}/特殊性值:0,1,0,2/

注意:

(1)样式应用时,css 会先查看规则的权重(!important),加了权重的优先级最高,当权重相同的时候,会比较规则的特殊性。

(2)特殊性值越大的声明优先级越高。

(3)相同特殊性值的声明,根据样式引入的顺序,后声明的规则优先级高(距离元素出现最近的)

(4) 部分浏览器由于字节溢出问题出现的进位表现不做考虑

回答

判断优先级时,首先会判断一条属性声明是否有权重,也就是是否在声明后面加上了 !important。一条声明如果加上了权重,那么它的优先级就是最高的,前提是它之后不再出现相同权重的声明。如果权重相同,则需要去比较匹配规则的特殊性。

一条匹配规则一般由多个选择器组成,一条规则的特殊性由组成它的选择器的特殊性累加而成。选择器的特殊性可以分为四个等级,第一个等级是行内样式,为 1000,第二个等级是 id 选择器,为 0100,第三个等级是类选择器、伪类选择器和属性选择器,为 0010,第四个等级是元素选择器和伪元素选择器,为 0001。规则中每出现一个选择器,就将它的特殊性进行叠加,这个叠加只限于对应的等级的叠加,不会产生进位。选择器特殊性值的比较是从左向右排序的,也就是说以 1 开头的特殊性值比所有以 0 开头的特殊性值要大。

比如说特殊性值为 1000 的的规则优先级就要比特殊性值为 0999 的规则高。如果两个规则的特殊性值相等的时候,那么就会根据它们引入的顺序,后出现的规则的优先级最高。

7.关于伪类 LVHA 的解释?

a 标签有四种状态:链接访问前、链接访问后、鼠标滑过、激活,分别对应四种类 :link:visited:hover:active

当链接未访问过时:

(1)当鼠标滑过 a 链接时,满足 :link:hover两种状态,要改变 a 标签的颜色,就必须将:hover伪类在:link 伪类后面声明;

(2)当鼠标点击激活 a 链接时,同时满足 :link:hover、:active 三种状态,要显示 a 标签激活时的样式(:active),

必须将 :active声明放到:link:hover 之后。因此得出 LVHA 这个顺序。

当链接访问过时,情况基本同上,只不过需要将 :link 换成:visited

这个顺序能不能变?可以,但也只有 :link:visited 可以交换位置,因为一个链接要么访问过要么没访问过,不可能同时满足,也就不存在覆盖的问题。

8.CSS3 新增伪类有哪些?

(1)elem:nth-child(n) 选中父元素下的第 n 个子元素,并且这个子元素的标签名为 elem,n 可以接受具体的数值,也可以接受函数。

(2)elem:nth-last-child(n) 作用同上,不过是从后开始查找。

(3)elem:last-child 选中最后一个子元素。

(4)elem:only-child 如果 elem 是父元素下唯一的子元素,则选中之。

(5)elem:nth-of-type(n) 选中父元素下第 n 个 elem 类型元素,n 可以接受具体的数值,也可以接受函数。

(6)elem:first-of-type 选中父元素下第一个 elem 类型元素。

(7)elem:last-of-type 选中父元素下最后一个 elem 类型元素。

(8)elem:only-of-type 如果父元素下的子元素只有一个 elem 类型元素,则选中该元素。

(9)elem:empty 选中不包含子元素和内容的 elem 类型元素。

(10)elem:target 选择当前活动的 elem 元素。

(11):not(elem) 选择非 elem 元素的每个元素。

(12):enabled 控制表单控件的禁用状态。

(13):disabled 控制表单控件的禁用状态。

(14):checked 单选框或复选框被选中。

9.如何居中 div?

-水平居中:给 div 设置一个宽度,然后添加 margin:0 auto 属性

css
div {
  width: 200px;
  margin: 0 auto;
}

-水平居中,利用 text-align:center 实现

css
.container {
  background: rgba(0, 0, 0, 0.5);
  text-align: center;
  font-size: 0;
}
.box {
  display: inline-block;
  width: 500px;
  height: 400px;
  background-color: pink;
}

-让绝对定位的 div 居中

css
div {
  position: absolute;
  width: 300px;
  height: 300px;
  margin: auto;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: pink; /*方便看效果*/
}

-水平垂直居中一

css
/*确定容器的宽高宽500高300的层设置层的外边距*/
div{
  position: absolute;/*绝对定位*/
  width: 500px;
  height: 300px;
  top: 50%;
  left: 50%;
  margin: -150px00-250px;/*外边距为自身宽高的一半*/
  background-color: pink;/*方便看效果*/
}

-水平垂直居中二

css
/*未知容器的宽高,利用`transform`属性*/
div {
  position: absolute; /*相对定位或绝对定位均可*/
  width: 500px;
  height: 300px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: pink; /*方便看效果*/
}

-水平垂直居中三

css
/*利用flex布局实际使用时应考虑兼容性*/
.container {
  display: flex;
  align-items: center; /*垂直居中*/
  justify-content: center; /*水平居中*/
}
.containerdiv {
  width: 100px;
  height: 100px;
  background-color: pink; /*方便看效果*/
}

-水平垂直居中四

css
/*利用text-align:center和vertical-align:middle属性*/
.container {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: 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;
}
.box {
  display: inline-block;
  width: 500px;
  height: 400px;
  background-color: pink;
  white-space: normal;
  vertical-align: middle;
}

回答

一般常见的几种居中的方法有:

对于宽高固定的元素

(1)可以利用 margin:0 auto 来实现元素的水平居中。

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

(3)利用绝对定位,先将元素的左上角通过 top:50%left:50%定位到页面的中心,然后再通过margin 负值来调整元素的中心点到页面的中心。

(4)利用绝对定位,先将元素的左上角通过 top:50%left:50%定位到页面的中心,然后再通过translate 来调整元素的中心点到页面的中心。

(5)使用 flex布局,通过align-items:centerjustify-content:center 设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。

对于宽高不定的元素,上面的后面两种方法,可以实现元素的垂直和水平的居中。

10.display 有哪些值?说明他们的作用。

block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。

none 元素不显示,并从文档流中移除。

inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。

inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。

list-item 像块类型元素一样显示,并添加样式列表标记。

table 此元素会作为块级表格来显示。

inherit 规定应该从父元素继承 display 属性的值。

11.position 的值 relativeabsolute 定位原点是?

相关知识点

absolute

生成绝对定位的元素,相对于值不为 static 的第一个父元素的 padding box 进行定位,也可以理解为离自己这一级元素最近的一级 position设置为absolute或者relative 的父元素的 padding box 的左上角为原点的。

fixed(老 IE 不支持)

生成绝对定位的元素,相对于浏览器窗口进行定位。

relative

生成相对定位的元素,相对于其元素本身所在正常位置进行定位。

static

默认值。没有定位,元素出现在正常的流中(忽略 top,bottom,left,right,z-index 声明)。

inherit规定从父元素继承 position 属性的值。

回答

relative 定位的元素,是相对于元素本身的正常位置来进行定位的。

absolute定位的元素,是相对于它的第一个 position值不为static的祖先元素的 padding box 来进行定位的。这句话可以这样来理解,首先需要找到绝对定位元素的一个position的值不为static的祖先元素,然后相对于这个祖先元素的 padding box 来定位,也就是说在计算定位距离的时候,padding 的值也要算进去。

12.CSS3 有哪些新特性?(根据项目回答)

新增各种 CSS 选择器 (:not(.input):所有 class 不是“input”的节点)

圆角  (border-radius:8px

多列布局 (multi-column layout)

阴影和反射 (Shadow\Reflect)

文字特效  (text-shadow

文字渲染  (Text-decoration)

线性渐变  (gradient

旋转   (transform

缩放,定位,倾斜,动画,多背景

例如:transform:\scale(0.85,0.90)\translate(0px,-30px)\skew(-9deg,0deg)\Animation

13.请解释一下 CSS3 的 Flex box(弹性盒布局模型),以及适用场景?

相关知识点

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

任何一个容器都可以指定为 Flex 布局。行内元素也可以使用 Flex 布局。注意,设为 Flex 布局以后,子元素的 floatclearvertical-align 属性将失效。

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称 " 容器 "。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称 " 项目 "。

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis),项目默认沿主轴排列。

以下 6 个属性设置在容器上。

flex-direction 属性决定主轴的方向(即项目的排列方向)。

flex-wrap 属性定义,如果一条轴线排不下,如何换行。

flex-flow属性是 flex-direction属性和flex-wrap 属性的简写形式,默认值为 row nowrap。

justify-content 属性定义了项目在主轴上的对齐方式。

align-items 属性定义项目在交叉轴上如何对齐。

align-content 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

以下 6 个属性设置在项目上。

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

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

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

flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为 auto,即项目的本来大小。

flex属性是 flex-growflex-shrinkflex-basis 的简写,默认值为 0 1 auto。

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

回答

flex布局是 CSS3 新增的一种布局方式,可以通过将一个元素的 display属性值设置为flex从而使它成为一个flex 容器,它的所有子元素都会成为它的项目。

一个容器默认有两条轴,一个是水平的主轴,一个是与主轴垂直的交叉轴。可以使用 flex-direction 来指定主轴的方向。

可以使用 justify-content来指定元素在主轴上的排列方式,使用align-items来指定元素在交叉轴上的排列方式。还可以使用flex-wrap 来规定当一行排列不下时的换行方式。

对于容器中的项目,可以使用 order属性来指定项目的排列顺序,还可以使用flex-grow来指定当排列空间有剩余的时候,项目的放大比例。还可以使用flex-shrink 来指定当排列空间不足时,项目的缩小比例。

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

采用的是相邻边框连接处的均分原理。将元素的宽高设为 0,只设置 border,把任意三条边隐藏掉(颜色设为transparent),剩下的就是一个三角形。

css
#demo {
  width: 0;
  height: 0;
  border-width: 20px;
  border-style: solid;
  border-color: transparent transparent red transparent;
}

15.一个满屏品字布局如何设计?

简单的方式:

上面的 div 宽 100%,

下面的两个 div 分别宽 50%,

然后用 float或者inline 使其不换行即可

16.CSS 多列等高如何实现?

(1)利用 padding-bottom|margin-bottom正负值相抵,不会影响页面布局的特点。设置父容器设置超出隐藏(overflow:hidden),这样父容器的高度就还是它里面的列没有设定padding-bottom时的高度,当它里面的任一列高度增加了,则父容器的高度被撑到里面最高那列的高度,其他比这列矮的列会用它们的padding-bottom 补偿这部分高度差。

(2)利用 table-cell 所有单元格高度都相等的特性,来实现多列等高。

(3)利用 flex布局中项目align-items 属性默认为stretch,如果项目未设置高度或设为auto,将占满整个容器的高度的特性,来实现多列等高。

17.经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用 hack 的技巧?

(1)png24 位的图片在 iE6 浏览器上出现背景

解决方案:做成 PNG8,也可以引用一段脚本处理。

(2)浏览器默认的 marginpadding 不同

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

(3)IE6 双边距 bug:在 IE6 下,如果对元素设置了浮动,同时又设置了 margin-leftmargin-rightmargin 值会加倍。

css
#box{float:left;width:10px;margin:0 0 0 10px;}

这种情况之下 IE 会产生 20px 的距离

解决方案:在 float的标签样式控制中加入_display:inline; 将其转化为行内属性。(_ 这个符号只有 ie6 会识别)

(4)渐进识别的方式,从总体中逐渐排除局部。

首先,巧妙的使用 "\9" 这一标记,将 IE 游览器从所有情况中分离出来。

接着,再次使用 "+" 将 IE8 和 IE7、IE6 分离开来,这样 IE8 已经独立识别。

css
.bb{
  background-color:#f1ee18;/*所有识别*/
  .background-color:#00deff\9;/*IE6、7、8识别*/
  +background-color:#a200ff;/*IE6、7识别*/
  _background-color:#1e0bd1;/*IE6识别*/
}

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

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

(6)IE 下,event 对象有 xy属性,但是没有pageXpageY属性;Firefox 下,event 对象有pageXpageY属性,但是没有xy 属性。

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

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

解决方法:

  1. 可通过加入 CSS 属性 -webkit-text-size-adjust:none; 解决。但是,在 chrome 更新到 27 版本之后就不可以用了。
  2. 还可以使用 -webkit-transform:scale(0.5); 注意-webkit-transform:scale(0.75);

收缩的是整个 span 的大小,这时候,必须要将 span 转换成块元素,可以使用 display:block/inline-block/...;

(8)超链接访问过后 hover 样式就不出现了,被点击访问过的超链接样式不再具有 hoveractive

解决方法:改变 CSS 属性的排列顺序 L-V-H-A

(9)怪异模式问题:漏写 DTD 声明,Firefox 仍然会按照标准模式来解析网页,但在 IE 中会触发怪异模式。为避免怪异模式带来不必要的麻烦,最好养成书写 DTD 声明的好习惯。

18.lili 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

浏览器会把 inline元素间的空白字符(空格、换行、Tab 等)渲染成一个空格。而为了美观。通常是一个<li>放在一行,这导致<li> 换行后产生换行字符,它变成一个空格,占用了一个字符的宽度。

解决办法:

(1)为 <li> 设置float:left。不足:有些容器是不能设置浮动,如左右切换的焦点图等。

(2)将所有 <li> 写在同一行。不足:代码不美观。

(3)将 <ul>内的字符尺寸直接设为 0,即font-size:0。不足:<ul> 中的其他字符尺寸也被设为 0,需要额外重新设定其他字符尺寸,且在 Safari 浏览器依然会出现空白间隔。

(4)消除 <ul>的字符间隔letter-spacing:-8px,不足:这也设置了<li>内的字符间隔,因此需要将<li> 内的字符间隔设为默认letter-spacing:normal

19.为什么要初始化 CSS 样式?

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

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

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

淘宝的样式初始化代码:

html
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;}

20.什么是包含块,对于包含块的理解?

包含块(containing block)就是元素用来计算和定位的一个框。

(1)根元素(很多场景下可以看成是 <html>)被称为“初始包含块”,其尺寸等同于浏览器可视窗口的大小。

(2)对于其他元素,如果该元素的 positionrelative 或者static,则“包含块”由其最近的块容器祖先盒的 content box 边界形成。

(3)如果元素 position:fixed,则“包含块”是“初始包含块”。

(4)如果元素 position:absolute,则“包含块”由最近的position不为static 的祖先元素建立,具体方式如下:

如果该祖先元素是纯 inline 元素,则规则略复杂:

  • 假设给内联元素的前后各生成一个宽度为 0 的内联盒子(inline box),则这两个内联盒子的 padding box 外面的包围盒就是内联元素的“包含块”;
  • 如果该内联元素被跨行分割了,那么“包含块”是未定义的,也就是 CSS2.1 规范并没有明确定义,浏览器自行发挥。否则,“包含块”由该祖先的 padding box 边界形成。如果没有符合条件的祖先元素,则“包含块”是“初始包含块”。

21.CSS 里的 visibility 属性有个 collapse 属性值有什么用?在不同浏览器下以后什么区别?

(1)对于一般的元素,它的表现跟 visibility:hidden; 是一样的。元素是不可见的,但此时仍占用页面空间。

(2)但例外的是,如果这个元素是 table 相关的元素,例如 table 行,table group,table 列,table column group,它的表现却跟 display:none 一样,也就是说,它们占用的空间也会释放。

在不同浏览器下的区别:

在谷歌浏览器里,使用 collapse值和使用hidden 值没有什么区别。

在火狐浏览器、Opera 和 IE11 里,使用 collapse 值的效果就如它的字面意思:table 的行会消失,它的下面一行会补充它的位置。

22.width:autowidth:100% 的区别

一般而言

width:100% 会使元素 box 的宽度等于父元素的 content box 的宽度。

width:auto会使元素撑满整个父元素,marginborderpaddingcontent 区域会自动分配水平空间。

23.绝对定位元素与非绝对定位元素的百分比计算的区别

绝对定位元素的宽高百分比是相对于临近的 position不为static 的祖先元素的 padding box 来计算的。

非绝对定位元素的宽高百分比则是相对于父元素的 content box 来计算的。

24.简单介绍使用图片 base64 编码的优点和缺点。

base64 编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的 url 属性。

使用 base64 的优点是:

(1)减少一个图片的 HTTP 请求

使用 base64 的缺点是:

(1)根据 base64 的编码原理,编码后的大小会比原文件大小大 1/3,如果把大图片编码到 html/css 中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对 html 或 css 文件解析渲染的时间。

(2)使用 base64 无法直接缓存,要缓存只能缓存包含 base64 的文件,比如 HTML 或者 CSS,这相比域直接缓存图片的效果要差很多。

(3)兼容性的问题,ie8 以前的浏览器不支持。

一般一些网站的小图标可以使用 base64 图片来引入。

25.'display''position''float' 的相互关系?

(1)首先判断 display属性是否为none,如果为none,则positionfloat 属性的值不影响元素最后的表现。

(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' 特性值同设置值。

26.margin 重叠问题的理解。

相关知识点

块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为“margin 合并”。

产生折叠的必备条件:margin 必须是邻接的!

而根据 w3c 规范,两个 margin 是邻接的必须满足以下条件:

  • 必须是处于常规文档流(非 float 和绝对定位)的块级盒子,并且处于同一个 BFC 当中。
  • 没有线盒,没有空隙,没有 paddingborder 将他们分隔开
  • 都属于垂直方向上相邻的外边距,可以是下面任意一种情况
  • 元素的 margin-top 与其第一个常规文档流的子元素的margin-top
  • 元素的 margin-bottom 与其下一个常规文档流的兄弟元素的margin-top
  • height 为 auto 的元素的 margin-bottom 与其最后一个常规文档流的子元素的margin-bottom
  • 高度为 0 并且最小高度也为 0,不包含常规文档流的子元素,并且自身没有建立新的 BFC 的元素的 margin-topmargin-bottom

margin 合并的 3 种场景:

(1)相邻兄弟元素 margin 合并。

解决办法:

  • 设置块状格式化上下文元素(BFC)

(2)父级和第一个/最后一个子元素的 margin 合并。

解决办法:

对于 margin-top 合并,可以进行如下操作(满足一个条件即可):

  • 父元素设置为块状格式化上下文元素;
  • 父元素设置 border-top 值;
  • 父元素设置 padding-top 值;
  • 父元素和第一个子元素之间添加内联元素进行分隔。

对于 margin-bottom 合并,可以进行如下操作(满足一个条件即可):

  • 父元素设置为块状格式化上下文元素;
  • 父元素设置 border-bottom 值;
  • 父元素设置 padding-bottom 值;
  • 父元素和最后一个子元素之间添加内联元素进行分隔;
  • 父元素设置 heightmin-heightmax-height

(3)空块级元素的 margin 合并。

解决办法:

  • 设置垂直方向的 border
  • 设置垂直方向的 padding
  • 里面添加内联元素(直接 Space 键空格是没用的);
  • 设置 height 或者min-height

回答

margin重叠指的是在垂直方向上,两个相邻元素的 margin 发生重叠的情况。

一般来说可以分为四种情形:

第一种是相邻兄弟元素的 marin-bottommargin-top 的值发生重叠。这种情况下可以通过设置其中一个元素为 BFC 来解决。

第二种是父元素的 margin-top和子元素的margin-top发生重叠。它们发生重叠是因为它们是相邻的,所以可以通过这一点来解决这个问题。可以为父元素设置border-toppadding-top 值来分隔它们,当然也可以将父元素设置为 BFC 来解决。

第三种是高度为 auto的父元素的margin-bottom和子元素的margin-bottom发生重叠。它们发生重叠一个是因为它们相邻,一个是因为父元素的高度不固定。因此可以为父元素设置border-bottompadding-bottom来分隔它们,也可以为父元素设置一个高度,max-heightmin-height 也能解决这个问题。当然将父元素设置为 BFC 是最简单的方法。

第四种情况,是没有内容的元素,自身的 margin-topmargin-bottom发生的重叠。可以通过为其设置borderpadding 或者高度来解决这个问题。

27.对 BFC 规范(块级格式化上下文:block formatting context)的理解?

相关知识点

块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视化 CSS 渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。

通俗来讲

  • BFC 是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。
  • 如果一个元素符合触发 BFC 的条件,则 BFC 中的元素布局不受外部影响。

创建 BFC

(1)根元素或包含根元素的元素

(2)浮动元素 float=left|rightinherit(≠none)

(3)绝对定位元素 position=absolutefixed

(4)display=inline-block|flex|inline-flex|table-celltable-caption

(5)overflow=hidden|autoscroll(≠visible)

回答

BFC 指的是块级格式化上下文,一个元素形成了 BFC 之后,那么它内部元素产生的布局不会影响到外部元素,外部元素的布局也不会影响到 BFC 中的内部元素。一个 BFC 就像是一个隔离区域,和其他区域互不影响。

一般来说根元素是一个 BFC 区域,浮动和绝对定位的元素也会形成 BFC,display属性的值为 inline-blockflex这些属性时也会创建 BFC。还有就是元素的overflow的值不为visible 时都会创建 BFC。

28.IFC 是什么?

IFC 指的是行级格式化上下文,它有这样的一些布局规则:

(1)行级上下文内部的盒子会在水平方向,一个接一个地放置。

(2)当一行不够的时候会自动切换到下一行。

(3)行级上下文的高度由内部最高的内联盒子的高度决定。

29.请解释一下为什么需要清除浮动?清除浮动的方式

浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”。

清除浮动是为了清除使用浮动元素产生的影响。浮动的元素,高度会塌陷,而高度的塌陷使页面后面的布局不能正常显示。

清除浮动的方式

(1)使用 clear 属性清除浮动。参考 28。

(2)使用 BFC 块级格式化上下文来清除浮动。参考 26。

因为 BFC 元素不会影响外部元素的特点,所以 BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违 BFC 元素的子元素不会影响外部元素的设定。

30.使用 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:leftclear:right 这两个声明就没有任何使用的价值,至少在 CSS 世界中是如此,直接使用clear:both

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

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

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

31.zoom:1 的清除浮动原理?

清除浮动,触发 hasLayout;

zoom属性是 IE 浏览器的专有属性,它可以设置或检索对象的缩放比例。解决 ie 下比较奇葩的 bug。譬如外边距(margin)的重叠,浮动清除,触发 ie 的 haslayout 属性等。

来龙去脉大概如下:

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

zoom属性是 IE 浏览器的专有属性,火狐和老版本的 webkit 核心的浏览器都不支持这个属性。然而,zoom 现在已经被逐步标准化,出现在 CSS3.0 规范草案中。

目前非 ie 由于不支持这个属性,它们又是通过什么属性来实现元素的缩放呢?可以通过 css3 里面的动画属性 scale 进行缩放。

32.移动端的布局用过媒体查询吗?

假设现在正用一台显示设备来阅读这篇文章,同时也想把它投影到屏幕上,或者打印出来,而显示设备、屏幕投影和打印等这些媒介都有自己的特点,CSS 就是为文档提供在不同媒介上展示的适配方法。

当媒体查询为真时,相关的样式表或样式规则会按照正常的级联规被应用。当媒体查询返回假,标签上带有媒体查询的样式表仍将被下载(只不过不会被应用)。

包含了一个媒体类型和至少一个使用宽度、高度和颜色等媒体属性来限制样式表范围的表达式。CSS3 加入的媒体查询使得无需修改内容便可以使样式应用于某些特定的设备范围。

33.使用 CSS 预处理器吗?喜欢哪个?

SASS(SASS、LESS 没有本质区别,只因为团队前端都是用的 SASS)

34.CSS 优化、提高性能的方法有哪些?

加载性能:

(1)css 压缩:将写好的 css 进行打包压缩,可以减少很多的体积。

(2)css 单一样式:当需要下边距和左边距的时候,很多时候选择:margin:top 0 bottom 0; 但 margin-bottom:bottom;margin-left:left; 执行的效率更高。

(3)减少使用 @import,而建议使用link,因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载。

选择器性能:

(1)关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分)。CSS 选择符是从右到左进行匹配的。当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等;

(2)如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。

(3)避免使用通配规则,如*{}计算次数惊人!只对需要用到的元素进行选择。

(4)尽量少的去对标签进行选择,而是用 class。

(5)尽量少的去使用后代选择器,降低选择器的权重值。后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素。

(6)了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则。

渲染性能:

(1)慎重使用高性能属性:浮动、定位。

(2)尽量减少页面重排、重绘。

(3)去除空规则:{}。空规则的产生原因一般来说是为了预留样式。去除这些空规则无疑能减少 css 文档体积。

(4)属性值为 0 时,不加单位。

(5)属性值为浮动小数 0.**,可以省略小数点之前的 0。

(6)标准化各种浏览器前缀:带浏览器前缀的在前。标准属性在后。

(7)不使用 @import 前缀,它会影响 css 的加载速度。

(8)选择器优化嵌套,尽量避免层级过深。

(9)css 雪碧图,同一页面相近部分的小图标,方便使用,减少页面的请求次数,但是同时图片本身会变大,使用时,优劣考虑清楚,再使用。

(10)正确使用 display 的属性,由于 display 的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能。

(11)不滥用 web 字体。对于中文网站来说 WebFonts 可能很陌生,国外却很流行。web fonts 通常体积庞大,而且一些浏览器在下载 web fonts 时会阻塞页面渲染损伤性能。

可维护性、健壮性:

(1)将具有相同属性的样式抽离出来,整合并通过 class 在页面中进行使用,提高 css 的可维护性。

(2)样式与内容分离:将 css 代码定义到外部 css 中。

35.浏览器是怎样解析 CSS 选择器的?

样式系统从关键选择器开始匹配,然后左移查找规则选择器的祖先元素。只要选择器的子树一直在工作,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该规则。

试想一下,如果采用从左至右的方式读取 CSS 规则,那么大多数规则读到最后(最右)才会发现是不匹配的,这样做会费时耗能,最后有很多都是无用的;而如果采取从右向左的方式,那么只要发现最右边选择器不匹配,就可以直接舍弃了,避免了许多无效匹配。

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

(1)偶数字号相对更容易和 web 设计的其他部分构成比例关系。比如:当用了 14px 的正文字号,可能会在一些地方用 14×0.5=7px的 margin,在另一些地方用14×1.5=21px 的标题字号。

(2)浏览器缘故,低版本的浏览器 ie6 会把奇数字体强制转化为偶数,即 13px 渲染为 14px。

(3)系统差别,早期的 Windows 里,中易宋体点阵只有 12 和 14、15、16px,唯独缺少 13px。

37.marginpadding 分别适合什么场景使用?

margin是用来隔开元素与元素的间距;padding 是用来隔开元素与内容的间隔。

margin 用于布局分开元素使元素与元素互不相干。

padding 用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段距离。

何时应当使用 margin:

•需要在 border 外侧添加空白时。

•空白处不需要背景(色)时。

•上下相连的两个盒子之间的空白,需要相互抵消时。如 15px+20px 的 margin,将得到 20px 的空白。

何时应当时用 padding:

•需要在 border 内测添加空白时。

•空白处需要背景(色)时。

•上下相连的两个盒子之间的空白,希望等于两者之和时。如 15px+20px 的 padding,将得到 35px 的空白。

38.抽离样式模块怎么写,说出思路,有无实践经验?[阿里航旅的面试题]

把常用的 css 样式单独做成 css 文件……通用的和业务相关的分离出来,通用的做成样式模块儿共享,业务相关的,放进业务相关的库里面做成对应功能的模块儿。

39.简单说一下 css3 的 all 属性。

all属性实际上是所有 CSS 属性的缩写,表示,所有的 CSS 属性都怎样怎样,但是,不包括 unicode-bididirection 这两个 CSS 属性。支持三个 CSS 通用属性值,initial,inherit,unset

initial是初始值的意思,也就是该元素元素都除了 unicode-bididirection 以外的 CSS 属性都使用属性的默认初始值。

inherit是继承的意思,也就是该元素除了 unicode-bididirection 以外的 CSS 属性都继承父元素的属性值。

unset 是取消设置的意思,也就是当前元素浏览器或用户设置的 CSS 忽略,然后如果是具有继承特性的 CSS,如 color,则使用继承值;如果是没有继承特性的 CSS 属性,如background-color,则使用初始值。

40.为什么不建议使用通配符初始化 css 样式。

采用 {padding:0;margin:0;}这样的写法好处是写起来很简单,但是是通配符,需要把所有的标签都遍历一遍,当网站较大时,样式比较多,这样写就大大的加强了网站运行的负载,会使网站加载的时候需要很长一段时间,因此一般大型的网站都有分层次的一套初始化样式。出于性能的考虑,并不是所有标签都会有paddingmargin,因此对常见的具有默认paddingmargin的元素初始化即可,并不需使用通配符* 来初始化。

41.absolute 的 containingblock(包含块)计算方式跟正常流有什么不同?

(1)内联元素也可以作为“包含块”所在的元素;

(2)“包含块”所在的元素不是父块级元素,而是最近的 position不为static 的祖先元素或根元素;

(3)边界是 padding box 而不是 content box。

42.对于 hasLayout 的理解?

hasLayout是 IE 特有的一个属性。很多的 IE 下的 css bug 都与其息息相关。在 IE 中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。当一个元素的 hasLayout 属性值为 true 时,它负责对自己和可能的子孙元素进行尺寸计算和定位。虽然这意味着这个元素需要花更多的代价来维护自身和里面的内容,而不是依赖于祖先元素来完成这些工作。

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

如果是 height 的话,是相对于包含块的高度。

如果是 padding或者margin 竖直方向的属性则是相对于包含块的宽度。

44.全屏滚动的原理是什么?用到了 CSS 的哪些属性?

原理:有点类似于轮播,整体的元素一直排列下去,假设有 5 个需要展示的全屏页面,那么高度是 500%,只是展示 100%,容器及容器内的页面取当前可视区高度,同时容器的父级元素 overflow 属性值设为hidden,通过更改容器可视区的位置来实现全屏滚动效果。主要是响应鼠标事件,页面通过 CSS 的动画效果,进行移动。

css
overflow:hidden;transition:all 1000 ms ease;

45.什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的 IE?

响应式网站设计是一个网站能够兼容多个终端,而不是为每一个终端做一个特定的版本。基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理。页面头部必须有 meta 声明的viewport

46.视差滚动效果,如何给每页做不同的动画?(回到顶部,向下滑动要再次出现,和只出现一次分别怎么做?)

视差滚动是指多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。

47.如何修改 chrome 记住密码后自动填充表单的黄色背景?

chrome 表单自动填充后,input 文本框的背景会变成黄色的,通过审查元素可以看到这是由于 chrome 会默认给自动填充的 input 表单加上 input:-webkit-autofill 私有属性,然后对其赋予以下样式:

css
{
  background-color:rgb(250,255,189)!important;
  background-image:none!important;
  color:rgb(0,0,0)!important;
}

对 chrome 默认定义的 background-colorbackground-imagecolor使用important 是不能提高其优先级的,但是其他属性可使用。

使用足够大的纯色内阴影来覆盖 input 输入框的黄色背景,处理如下

css
input:-webkit-autofill,textarea:-webkit-autofill,select:-webkit-autofill{
  -webkit-box-shadow:000px 1000px white inset;
  border:1px solid #CCC !important;
}

48.怎么让 Chrome 支持小于 12px 的文字?

在谷歌下 css 设置字体大小为 12px 及以下时,显示都是一样大小,都是默认 12px。

解决办法:

(1)可以使用 Webkit 的内核的 -webkit-text-size-adjust的私有 CSS 属性来解决,只要加了-webkit-text-size-adjust:none;字体大小就不受限制了。但是 chrome 更新到 27 版本之后就不可以用了。所以高版本 chrome 谷歌浏览器已经不再支持-webkit-text-size-adjust 样式,所以要使用时候慎用。

(2)还可以使用 css3 的 transform 缩放属性 -webkit-transform:scale(0.5);注意-webkit-transform:scale(0.75); 收缩的是整个元素的大小,这时候,如果是内联元素,必须要将内联元素转换成块元素,可以使用 display:block/inline-block/...;

(3)使用图片:如果是内容固定不变情况下,使用将小于 12px 文字内容切出做图片,这样不影响兼容也不影响美观。

49.让页面里的字体变清晰,变细用 CSS 怎么做?

webkit 内核的私有属性:-webkit-font-smoothing,用于字体抗锯齿,使用后字体看起来会更清晰舒服。

在 MacOS 测试环境下面设置 -webkit-font-smoothing:antialiased; 但是这个属性仅仅是面向 MacOS,其他操作系统设置后无效。

50.font-style 属性中 italicoblique 的区别?

italicoblique 这两个关键字都表示“斜体”的意思。

它们的区别在于,italic 是使用当前字体的斜体字体,而 oblique 只是单纯地让文字倾斜。如果当前字体没有对应的斜体字体,则退而求其次,解析为 oblique,也就是单纯形状倾斜。

51.设备像素、css 像素、设备独立像素、dpr、ppi 之间的区别?

设备像素指的是物理像素,一般手机的分辨率指的就是设备像素,一个设备的设备像素是不可变的。

css 像素和设备独立像素是等价的,不管在何种分辨率的设备上,css 像素的大小应该是一致的,css 像素是一个相对单位,它是相对于设备像素的,一个 css 像素的大小取决于页面缩放程度和 dpr 的大小。

dpr 指的是设备像素和设备独立像素的比值,一般的 pc 屏幕,dpr=1。在 iphone4 时,苹果推出了 retina 屏幕,它的 dpr 为 2。屏幕的缩放会改变 dpr 的值。

ppi 指的是每英寸的物理像素的密度,ppi 越大,屏幕的分辨率越大。

52.layout viewport、visual viewport 和 ideal viewport 的区别?

相关知识点

如果把移动设备上浏览器的可视区域设为 viewport 的话,某些网站就会因为 viewport 太窄而显示错乱,所以这些浏览器就决定默认情况下把 viewport 设为一个较宽的值,比如 980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。

ppk 把这个浏览器默认的 viewport 叫做 layout viewport。

layout viewport 的宽度是大于浏览器可视区域的宽度的,所以还需要一个 viewport 来代表浏览器可视区域的大小,ppk 把这个 viewport 叫做 visual viewport。

ideal viewport 是最适合移动设备的 viewport,ideal viewport 的宽度等于移动设备的屏幕宽度,只要在 css 中把某一元素的宽度设为 ideal viewport 的宽度(单位用 px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为 100% 的效果。ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对 ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。

回答

移动端一共需要理解三个 viewport 的概念的理解。

第一个视口是布局视口,在移动端显示网页时,由于移动端的屏幕尺寸比较小,如果网页使用移动端的屏幕尺寸进行布局的话,那么整个页面的布局都会显示错乱。所以移动端浏览器提供了一个 layout viewport 布局视口的概念,使用这个视口来对页面进行布局展示,一般 layout viewport 的大小为 980px,因此页面布局不会有太大的变化,可以通过拖动和缩放来查看到这个页面。第二个视口指的是视觉视口,visual viewport 指的是移动设备上可见的区域的视口大小,一般为屏幕的分辨率的大小。visual viewport 和 layout viewport 的关系,就像是通过窗户看外面的风景,视觉视口就是窗户,而外面的风景就是布局视口中的网页内容。

第三个视口是理想视口,由于 layout viewport 一般比 visual viewport 要大,所以想要看到整个页面必须通过拖动和缩放才能实现。所以又提出了 ideal viewport 的概念,ideal viewport 下用户不用缩放和滚动条就能够查看到整个页面,并且页面在不同分辨率下显示的内容大小相同。ideal viewport 其实就是通过修改 layout viewport 的大小,让它等于设备的宽度,这个宽度可以理解为是设备独立像素,因此根据 ideal viewport 设计的页面,在不同分辨率的屏幕下,显示应该相同。

更新: 2021-01-14 10:12:41
原文: <https://www.yuque.com/fcant/notes/an2op2&gt;

最近更新