前端八股文之html/css篇

1,652 阅读22分钟

题目加答案,每日更新5~10题

目录

已完结

  • meta 元素都有什么?
  • link 标签定义
  • DOCTYPE 的作用是什么?
  • SGML、HTML、XML和XHTML的区别?
  • 说一下对DTD的理解。
  • 如何处理HTML5新标签的浏览器兼容问题?
  • HTML5有哪些新特性、移除了哪些元素?
  • 说一下html布局元素的分类有哪些?以描述下每种布局元素的应用场景么?
  • 简单说下你理解的语义化,怎样来保证你写的符合语义化?HTML5语义化标签了解下?
  • 标准模式与兼容模式各有什么区别?
  • 前端需要注意哪些SEO?
  • 响应式布局用到的技术有几种方式?
  • 移动端需要注意什么
  • CSS选择符有哪些?
  • CSS多列等高如何实现?
  • CSS预处理器的好处
  • Css预处理器的概念
  • 请描述下css盒模型基本概念
  • CSS伪类和伪元素区别
  • margin和padding分别适合什么场景使用?
  • 说一下你理解margin重叠的问题.
  • 为什么不建议使用通配符初始化css样式?
  • position 定位有什么属性?
  • display、position和float的相互关系?
  • 布局都有什么方式,float和position有什么区别?
  • BFC是什么?触发BFC的条件是什么?有哪些应用场景?
  • 为什么CSS动画比JavaScript高效?
  • 什么情况下出现浏览器分层?(css部分)
  • 在css中link和@import的区别是什么?
  • 了解 CSS 模块吗?
  • DOMContentLoaded事件和Load事件的区别?
  • iframe有哪些缺点?
  • 简单介绍使用图片base64编码的优点和缺点

meta 元素都有什么?

1、指定字符集:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

2、向搜索引擎说明你的网页的关键字:

<meta name="keywords" content="关键字"/>

3、告诉搜索引擎你的站点的主要内容:

<meta name="description" content=""/>

4、告诉搜索引擎你的站点的制作的作者:

<meta name="author" content=""/>

5、定时让网页在指定的时间n内跳转

<meta http-equiv="refresh" content="n;url="/>

6、勇于设定网页的到期时间,一旦过期则必须到服务器上重新调用,需要注意的是必须使用GMT时间格式:

 <meta http-equiv="expires" content="Mon,12 May 2010 00:00:00 GMT"/>

7、禁用缓存:

 <meta http-equiv="pragma" content="no-cache"/>

8、cookie设定,如果网页过期,存盘的cookie将会被删除,需要注意的是也必须使用GMT时间格式:

<meta http-equiv="set-cookie" content="Mon,12 May 2010 00:00:00 GMT" />

link 标签定义

  • link 标签定义文档与外部资源的关系。
  • link 元素是空元素,它仅包含属性。 此元素只能存在于 head 部分,不过它可出现任何次数。
  • link 标签中的 rel 属性定义了当前文档与被链接文档之间的关系。常见的 stylesheet 指的是定义一个外部加载的样式表。

DOCTYPE 的作用是什么?

<!DOCTYPE> 声明位于 HTML 文档中的第一行,处于 <html> 标签之前。

告知浏览器的解析器用什么文档标准解析这个文档。

DOCTYPE 不存在或格式不正确会导致文档以兼容模式呈现。

<!DOCTYPE> 声明一般位于文档的第一行,它的作用主要是告诉浏览器以什么样的模式来解析文档。一般指定了之后会以标准模式来进行文档解析,否则就以兼容模式进行解析。在标准模式下,浏览器的解析规则都是按照最新的标准进行解析的。而在兼容模式下,浏览器会以向后兼容的方式来模拟老式浏览器的行为,以保证一些老的网站的正确访问。

在 html5 之后不再需要指定 DTD 文档,因为 html5 以前的 html 文档都是基于SGML 的,所以需要通过指定 DTD 来定义文档中允许的属性以及一些规则。而 html5 不再基于 SGML 了,所以不再需要使用 DTD。

SGML、HTML、XML和XHTML的区别?

  • SGML 是标准通用标记语言,是一种定义电子文档结构和描述其内容的国际标准语言,是所有电子文档标记语言的起源。
  • HTML 是超文本标记语言,主要是用于规定怎么显示网页。
  • XML 是可扩展标记语言是未来网页语言的发展方向,XML 和 HTML 的最大区别就在于XML 的标签是可以自己创建的,数量无限多,而 HTML 的标签都是固定的而且数量有限。
  • XHTML 也是现在基本上所有网页都在用的标记语言,他其实和 HTML 没什么本质的区别,标签都一样,用法也都一样,就是比 HTML 更严格,比如标签必须都用小写,标签都必须有闭合标签等。

image.png

说一下对DTD的理解。

  • DTD( Document Type Definition 文档类型定义)是一组机器可读的规则,它们定义 XML或 HTML 的特定版本中所有允许元素及它们的属性和层次关系的定义。在解析网页时,浏览器将使用这些规则检查页面的有效性并且采取相应的措施。
  • DTD 是对 HTML 文档的声明,还会影响浏览器的渲染模式(工作模式)。

如何处理HTML5新标签的浏览器兼容问题?

  • IE8/IE7/IE6 支持通过 document.createElement 方法产生的标签,可以利用这一特性让这些浏览器支持 HTML5 新标签,浏览器支持新标签后,还需要添加标签默认的样式。
  • 当然也可以直接使用成熟的框架,比如 html5shim <!--[if lt IE 9]> <script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script> <![endif]--> [if lte IE 9]……[endif] 判断 IE 的版本,限定只有 IE9 以下浏览器版本需要执行的语句。

HTML5有哪些新特性、移除了哪些元素?

HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

新增

  • 绘画 canvas;
  • 用于媒介回放的 video 和 audio 元素;
  • 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
  • sessionStorage 的数据在浏览器关闭后自动删除;
  • 语意化更好的内容元素,比如 article、footer、header、nav、section;
  • 表单控件,calendar、date、time、email、url、search;
  • 新的技术 webworker, websocket;
  • 新的文档属性 document.visibilityState

移除的元素

纯表现的元素:basefont,big,center,font, s,strike,tt,u; 对可用性产生负面影响的元素:frame,frameset,noframes;

说一下html布局元素的分类有哪些?以描述下每种布局元素的应用场景么?

分类

  • 内联元素 span a b strong i em br input textarea 本身属性为display:inline

和其他行内元素从左到右在一行显示,不可以直接控制宽度、高度等其他相关的css属性,但是可以直接设置内外边距的左右值

宽高是由本身内容大小决定的(文字、图片等)

只能容纳文本或者其他行内元素,不能嵌套块级元素

  • 块级元素

div h1-h6 hr menu ol ul li table from 本身属性为display:block

独占一行,每一个块级元素都会从新的一行重新开始,从上到下排布,可以直接控制宽度、高度等其他相关css属性

在不设置宽度的情况下,块级元素的宽度是它父级元素内容的宽度

在不设置高度的情况下,块级元素的高度是它本身内容的高度

  • 内联块状元素

内联块状元素综合以上两种的特性又有所不同

不能自动换行

能够识别width height line-height padding margin默认排列方式为从左到右

应用场景

  • 内联元素:用于不指定宽高,宽高由内容指定
  • 块状元素:用于指定宽高,标签占满一行
  • 内联块装元素:用于指定元素宽高,不占满一行

简单说下你理解的语义化,怎样来保证你写的符合语义化?HTML5语义化标签了解下?

很多时候我们写HTML,为了方便都会直接使用div和span标签,在通过class来确定具体样式。网站哪一部分为标题,哪一部分为导航,哪一部分为头部和尾部,都只能通过class来进行确定。 但是class命名规范却又没有一套统一的标准,依次导致很多时候无法确定整体网站的结构 因此,在HTML5出现后,添加了关于页面布局结构的新标签。而在html书写过程中,根据不同的内容使用合适的标签进行开发,即为语义化。

在编程中,语义指的是一段代码的含义(这个HTML的元素有什么作用,扮演了什么样的角色)。HTML语义元素清楚地向浏览器和开发者描述其意义,例如form、table以及img等

优点:

对搜索引擎友好

有了良好的结构和语义,网页内容自然容易被搜索引擎抓取

HTML5新增语义元素

article aside details figcaption figure footer> header main mark nav section summary time

为什么要语义化?

语义化的优势主要在于以下几点:

  • 其他开发者便于阅读代码,通过不同标签明白每个模块的作用和区别
  • 结构明确、语义清晰的页面能有更好的用户体验,在样式(css)没有加载前也有较为明确的结构,更如img这一类的,在图片无法加载的情况下有alt标签告知用户此处图片的具体内容;
  • 利于seo,语义化便于搜索引擎爬虫理解,和搜索引擎建立良好的沟通,能让爬虫爬取更多关键有效的信息
  • 方便其他设备阅读(如屏幕阅读器,盲人设备和移动设备等)

如何语义化?

一般的网站分为头部、导航、文章(或其他模块)、侧栏、底部,根据不同的部位,使用不同的标签进行书写。

表示页面不同位置的标签:header、nav、article、section、footer、aside

表示具体元素的作用或者意义的标签:a、abbr、address、audio、blockquote、caption、code、datalist、del、detail、ol、ul、figure、figuration、img、input、mark、p等

  • 尽可能少的使用无语义的标签div和span
  • 在语义不明显时,既可以使用div或者p时,尽量用p,因为p在默认情况下有上下间距,对兼容特殊终端有利;
  • 不要使用纯样式标签,如b、font、u等,改用css设置
  • 需要强调的文本,可以包含在strong或者em标签中(浏览器预设样式,能用css指定就不用他们),strong默认样式是加粗(不要加b),em是斜体(不用i)
  • 使用表格时,标题要用caption,表头用thead,主体部分用tbody包围,尾部用tfoot包围。表头和一般单元格要区分开,表头用th,,单元格用td
  • 表单域要用fieldset标签包起来,并用legend标签说明表单的用途
  • 每个input标签对应的说明文件都需要使用label标签。并且通过input设置为id属性,在label标签中设置for=someld来让说明文本和相对应的input关联起来

注意点

em、strong、dfn、code、samp、kbd、var、cite等,虽然这些标签定义的文本大多会呈现处特殊的样式,但实际上,这些标签都拥有确切的语义 我们并不反对使用它们,但是如果您只是为了达到某种视觉效果而使用这些标签的话,我们建议您可以使用样式表,那么做会达到更加丰富的效果。

标准模式与兼容模式各有什么区别?

标准模式的渲染方式和 JS 引擎的解析方式都是以该浏览器支持的最高标准运行。

在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。

前端需要注意哪些SEO?

  • 合理的title,description,keyswords 搜索引擎对这三项的权重逐个减小,title 值强调重点即可,重要的关键词出现不要超过两次,而且要靠前。

  • 不同页面的tilte要有所不同;description把页面的内容高度概括,长度合适,不可过分堆叠关键词,不同页面description有所不同。keyswords列举出重要的关键词即可。

  • 语义化的HTML代码,符合W3C 规范:语义化代码有利于搜索引擎理解网页。

  • 重要的内容HTML代码放在前面:搜索引擎抓取HTML 的顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取。

  • 重要的内容不要用js输出,爬虫不会执行js获取内容。

  • 尽量少用iframe ,搜索引擎不会抓取iframe中的内容。

  • 非装饰的图片必须加alt 。

  • 提高网站速度:网站速度是搜索引擎排序的一个重要指标。

响应式布局用到的技术有几种方式?

媒体查询

CSS3媒体查询可以让我们针对不同的媒体类型定义不同的样式,当重置浏览器窗口大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面

百分比布局

通过百分比单位,可以使得浏览器中组件的宽和高随着浏览器的高度的变化而变化,从而实现响应式的效果。Bootstrap里面的栅格系统就是利用百分比来定义元素的宽高,CSS3支持最大最小高,可以将百分比和min(max)一起结合使用来定义元素在不同设备下的宽高。

rem布局

rem是CSS3新增的单位,并且移动端的支持度很高,Android2.x+,ios5+都支持,rem单位都是相对于根元素html的font-size来决定大小的,根元素的font-size相当于一个基准,当页面的size发生改变时,只需要改变font-size值,那么以rem为固定单位元素的大小也会发生响应的变化。因此,如果通过rem来实现响应式的布局,只需要根据视图容器的大小,动态的改变font-size即可(而em是相对于父元素的)

rem响应式的布局思想

一般不要给元素设置具体的宽度,但是对于一些小图标可以设定具体宽度值 高度值可以设置固定值,设计稿有多大,我们就严格有多大 所有设置的固定值都用rem做单位(首先在html总设置一个基准值:px和rem的对应比例,然后在效果图上获取px值,布局的时候转化为rem值) js获取真实屏幕的宽度,让其除以设计稿的宽度,算出比例,把之前的基准值按照比例进行重新的设定,这样的项目就可以在移动端自适应了

rem布局的缺点

在响应式布局中,必须通过js来动态控制根元素font-size的大小,也就是说css样式和js代码有一定的耦合性,且必须将改变font-size的代码放在css样式之前

/* 这段代码是将视图容器分为10份,font-size用十分之一的宽度来表示
最后在header标签中执行这段代码,就可以动态定义font-size的大小
从而1rem在不同的视觉容器中表示不同的大小,用rem固定单位可以实现不同容器内布局的自适应 */

function refreshRem(){
    var docEl = doc.documentElement;
    var width = docEl.getBoundingClientRect().width;
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
win.addEventListener('resize', refreshRem)

视口单位

CSS3中引入了一个新的单位vw/vh,与视图窗口有关,vw表示相对于视图窗口的宽度,vh表示相对于视图窗口的高度,除了vw和vh外,还有vmin和vmax两个相关的单位

vw: 相对于视图的宽度,1vw等于视口宽度的1%,即视图宽度是100vw
vh: 相对于视图的高度,1vh等于视口高度的1%,即视图高度是100vh
vmin: vw和vh中较小的值
vmax: vw和vh中较大的值

图片响应式

图片响应式包括两个方面,一个就是大小自适应,这样能够保证图片在不同的屏幕分辨率下出现压缩、拉伸的情况;一个就是根据不同的屏幕分辨率和设备像素比来尽可能选择高分辨率的图片,也就是当在小屏幕上不需要高清图或大图,这样我们用小图代替,就可以减少网络宽带了。

总结

响应式布局的实现可以通过媒体查询+px,媒体查询+百分比,媒体查询+rem+js,vw/vh,vw/vh+rem这几种方式来实现。但是每一种方式都是有缺点的

媒体查询需要选取主流设备宽度尺寸作为断点针对性写额外的样式进行适配,但是这样做会比较麻烦,只能在选取的几个主流设备尺寸下呈现完美匹配,另外用户体验也不友好,布局在响应断点范围内的分辨率下维持不变,而在响应断点切换的瞬间,布局带来断层式的切换变化,如同卡带的唱机般"咔咔咔"地一下

通过百分比来适配,首先式计算麻烦,第二各个属性中如果使用百分比,其相对的元素的属性并不是唯一的,这样就造成我们使用百分比单位容易使布局问题变得复杂

通过采用rem单位来动态计算弹性布局,则需要在头部内嵌一段脚本来进行监听分辨率的变化来动态改变根元素字体大小,使得css和js耦合了在一起

通过利用纯css视口单位实现适配的页面,是既能解决响应式断层问题,又能解决脚本依赖的问题,但是兼容性还没有完全接受

响应式布局成型方案

现在的css,ui框架等都已经考虑到了适配不同屏幕分辨率的问题,实际项目中我们可以直接使用这些新特性和框架来实现响应式布局,可以有以下方案解决:

  • 利用前面介绍的方法自己来实现,比如CSS3 media、rem等
  • flex弹性布局
  • Grid网格布局
  • Columns栅格系统,往往需要依赖某个ui库,Bootstrap

移动端需要注意什么

1.添加禁止浏览器主动缩放功能

涉及到网页开发历史遗留问题,最开始的手机浏览器网页是直接访问电脑网页或访问专门为诺基亚手机开发的WAP页面,对于电脑网页由于手机分辨率太低,浏览器会使用缩放页面的方式来展示原页面,这个也是为什么在手机页面上直接使用document.documentElement.clientWidth获取到值为980,所以为了避免浏览器的自动缩放,需要在手机端

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

2.移动端字体放大问题

当可视部分的宽度小于480px也就是iPhone横屏的时候,需要进行处理

  • 禁用html节点的字号自动调整。默认情况下,iPhone会将过小的字号放大,我们可以通过-webkit-text-size-adjust属性进行调整
  • 将main-nav中的字号设置为90%
@media screen and (max-width:480px){
    html{
        -webkit-text-size-adjust:none
    }
    .main-nav a{
        font-size:90%;
        padding:10px 6px;
    }
}

3.移动端1px的问题

在移动端web开发中,UI设计稿中设置边框为1px,前端在开发过程中如果出现:border:1px,测试会发现在某个机型上,1px会比较粗,即是经典的移动端1px问题

设备的物理像素(设备像素)和逻辑像素(css像素)可以使用 viewport+remtransform: scale(0.5) 来实现。

CSS选择符有哪些?

  • id 选择器(#myid)
  • 类选择器(.myclassname)
  • 标签选择器(div,h1,p)
  • 后代选择器(h1 p)
  • 相邻后代选择器(子)选择器(ul>li)
  • 兄弟选择器(li~a)
  • 相邻兄弟选择器(li+a)
  • 属性选择器(a[rel="external"])
  • 伪类选择器(a:hover,li:nth-child)
  • 伪元素选择器(::before、::after)
  • 通配符选择器(*)

CSS多列等高如何实现?

  1. 利用 padding-bottom|margin-bottom 正负值相抵,不会影响页面布局的特点。设置父容器设置超出隐藏(overflow:hidden),这样父容器的高度就还是它里面的列没有设定 padding-bottom 时的高度,当它里面的任一列高度增加了,则父容器的高度被撑到里面最高那列的高度,其他比这列矮的列会用它们的 padding-bottom补偿这部分高度差。
/* padding margin 实现样式 */
.test-1 ul {
    overflow: hidden;
}
.test-1 li {
    float: left;
    width: 33.33%;
    padding-bottom: 9999px;
    margin: 0 0 -9999px 0;
}
  1. 利用 table-cell 所有单元格高度都相等的特性,来实现多列等高。
/* table 实现样式 */
.test-2 ul {
    display: table;
}
.test-2 li {
    display: table-cell;
    width: 33.33%;
}
  1. 利用 flex 布局中项目 align-items 属性默认为 stretch,如果项目未设置高度或设为 auto,将占满整个容器的高度的特性,来实现多列等高。
/* flex 实现样式 */
.test-3 ul {
    display: box;
    display: -webkit-flex;
    display: flex;
}
.test-3 li {
    -webkit-box-flex: 1;
    -webkit-flex: 1;
    flex: 1;
    width: 0;
}

CSS预处理器的好处

  • css代码更加整洁,更易维护,代码量更少
  • 修改很快,基础颜色使用变量,一处动牵全身
  • 常用代码使用代码块,节省大量代码
  • CSS嵌套减少了大量的重复选择器,避免一些低级错误
  • 变量、混入大大提升了样式的复用性
  • 额外的工具类似颜色函数(lighten/darken/transparentize等等),mixins,loops,这些方法使css更像一个编程语言,让开发者能够有能力生成更加复杂的css样式。

Css预处理器的概念

  • 为css增加编程特性的扩展性语言,可以使用变量简单逻辑判断函数等基本编程技巧
  • CSS预处理器编译输出还是标准的CSS样式
  • Less、Sass都是动态的样式语言,是CSS预处理器,CSS上的一种抽象层。他们是一种特殊的语法/语言而编译成CSS
  • Less的变量符号是@,Sass变量符号是$

解决的问题

  • CSS语法不够强大,因为无法嵌套导致很多重复的选择器
  • 没有变量和合理的样式复用机制,导致逻辑上相关的属性值只能以字面量的形式重复输出,难以维护

常用规范

变量、嵌套语法、混入、@import、运算、函数、继承等

请描述下css盒模型基本概念

宽度和高度的计算方式不同

box-sizing = border-box / content-box

标准盒模型:

width = content-width
height = content-height 

怪异盒模型:

width = content-width + padding-width + border-width
height = content-height + padding-height + border-height

CSS伪类和伪元素区别

  • CSS 伪类用于向某些选择器添加特殊的效果。
  • CSS 伪元素用于将特殊的效果添加到某些选择器。

伪类

image.png

伪元素

image.png

伪元素和伪类之所以这么容易混淆,是因为他们的效果类似而且写法相仿,但实际上 css3 为了区分两者,已经明确规定了伪类用一个冒号来表示,而伪元素则用两个冒号来表示。

:Pseudo-classes
::Pseudo-elements

但因为兼容性的问题,所以现在大部分还是统一的单冒号,但是抛开兼容性的问题,我们在书写时应该尽可能养成好习惯,区分两者。

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

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

  • 何时应当使用 margin
需要在 border 外侧添加空白时。
空白处不需要背景(色)时。
上下相连的两个盒子之间的空白,需要相互抵消时。如 15px+20pxmargin,将得到 20px的空白。
  • 何时应当时用 padding
需要在 border 内测添加空白时。
空白处需要背景(色)时。
上下相连的两个盒子之间的空白,希望等于两者之和时。如 15px+20pxpadding,将得到35px 的空白.

说一下你理解margin重叠的问题

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

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

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

margin 合并的 3 种场景:

    1. 相邻兄弟元素 margin 合并。 解决办法:设置块状格式化上下文元素(BFC)
    1. 父级和第一个/最后一个子元素的 margin 合并。 解决办法:对于 margin-top 合并,可以进行如下操作(满足一个条件即可):
父元素设置为块状格式化上下文元素;
父元素设置 border-top 值;
父元素设置 padding-top 值;
父元素和第一个子元素之间添加内联元素进行分隔。

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

父元素设置为块状格式化上下文元素;
父元素设置 border-bottom 值;
父元素设置 padding-bottom 值;
父元素和最后一个子元素之间添加内联元素进行分隔;
父元素设置 height、min-height 或 max-height。
    1. 空块级元素的 margin 合并。 解决办法:
设置垂直方向的 border;
设置垂直方向的 padding;
里面添加内联元素(直接 Space 键空格是没用的);
设置 height 或者 min-height

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

采用*{pading:0;margin:0;}这样的写法好处是写起来很简单

但是是通配符,需要把所有的标签都遍历一遍,当网站较大时,样式比较多,这样写就大大的加强了网站运行的负载,会使网站加载的时候需要很长一段时间

因此一般大型的网站都有分层次的一套初始化样式。出于性能的考虑,并不是所有标签都会有 padding 和 margin,因此对常见的具有默认 padding和 margin 的元素初始化即可,并不需使用通配符来初始化。

position 定位有什么属性?

position 属性值

  • position 的属性值共有四个常用的:static、relative、absolute、fixed

  • 还有不常用的:inherit、initial、sticky

static

是 position 的默认值,一般不设置 position 属性时,元素会按照正常的文档流进行排列。

relative

只要弄清它是相对哪个对象来进行偏移的,答案是它原本的位置。需要注意的是,相对定位不会脱离文档流,原来的位置仍然被保留

absolute

它是相对不是 static 的最近一级元素来进行定位的,如果没有这样的元素,那么相对 body 元素来进行定位,被定位元素会脱离文档流,然后我们可以通过left、right、top、bottom来调整元素的位置。

fixed

固定定位是最好理解的,它相对浏览器的窗口进行定位并脱离文档流,即使拖动滚动条,元素的位置也是不变的,我们使用浏览器时一些广告效果就是这样的。

sticky 粘性定位

position 设置 sticky 的元素,在屏幕范围时该元素的位置并不受到定位影响(设置是 top、left 等属性无效),当该元素的位置将要移出偏移范围的时候,定位又会变成 fixed,根据设置的 left、top 等属性成为固定位置的效果。

sticky 属性有以下几个特点:

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

但是这个属性的兼容性还不是很友好,需要注意一下。

initial

initial 关键字用于设置 css 属性为它的默认值,可作用于任何 css 样式。(IE 不支持该关键字)

inherit

继承父元素的 position 属性,但需要注意的是 IE8 以及往前的版本都不支持 inherit 属性。

display、position和float的相互关系?

display: none => position: absolute(fixed) => float

  • 首先我们判断 display 属性是否为 none,如果为 none,则 position 和 float 属性的值不影响元素最后的表现。
  • 然后判断 position 的值是否为 absolute 或者 fixed,如果是,则 float 属性失效,并且display 的值应该被设置为 table 或者 block,具体转换需要看初始转换值。
  • 如果 position 的值不为 absolute 或者 fixed,则判断 float 属性的值是否为 none,如果不是,则 display的值则按上面的规则转换。注意,如果 position 的值为 relative 并且 float 属性的值存在,则relative 相对于浮动后的最终位置定位。
  • 如果 float 的值为 none,则判断元素是否为根元素,如果是根元素则 display 属性按照上面的规则转换,如果不是,则保持指定的 display 属性值不变。

总的来说,可以把它看作是一个类似优先级的机制,"position:absolute"和"position:fixed"优先级最高,有它存在的时候,浮动不起作用,'display'的值也需要调整;其次,元素的'float'特性的值不是"none"的时候或者它是根元素的时候,调整'display'的值;最后,非根元素,并且非浮动元素,并且非绝对定位的元素,'display'特性值同设置值。

布局都有什么方式,float和position有什么区别?

布局方式

  1. 静态块级
  2. 弹性布局(flex)
  3. 网络布局(grid)
  4. 自适应布局(根据当前访问设备进行多套样式来适配)
  5. 响应式布局(通过媒体查询进行适配,rem/em)
  6. 浮动布局(float)
  7. 定位布局(position)

float和position有什么区别?

float:none left right inherit 特性:

  • 浮动会脱离文档流,并且会随着分辨率和窗口尺寸的变化而变化
  • 浮动后面的元素如果是块级元素,会占据块级元素的文本位置,但会与块级元素背景和边框重叠
  • 多个浮动不会产生重叠现象
  • 会将块级元素和行内元素变为行内块元素

position:relative absolute fixed static 特性

  • relative和static不会脱离文档流
  • absolute和fixed会脱离文档流
  • absolute根据relative定位。fixed根据body定位
  • absolute和fixed会触发BFC
  • 定位的优先级高于浮动

BFC是什么?触发BFC的条件是什么?有哪些应用场景?

1. 概念

BFC(Box Formatting Context):Box是css布局的对象和基本单位,BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。 块级格式化上下文布局规则

1.内部的BOX会在垂直方向一个接一个的放置
2.属于同一个BFC的两个相邻BOX的margin会重叠;不同BFC就不会
3.是页面上一个隔离的独立容器,里面的元素不会影响到外面的元素;反之亦然
4.BFC的区域不会和float box重叠
5.计算BFC的高度,浮动元素也参与计算

2. 触发条件

根元素
float属性不为none
position为absolute或fixed
overflow不为visible
display为inline-block、table-cell、table-captionflex、inline-flex

3. 应用场景

1)清除内部的浮动,触发父元素的BFC属性,会包含float元素
  防止浮动导致父元素高度塌陷父级设置overflow:hidden,元素float:right
2)分属于不同的BFC,可以阻止margin重叠
  避免margin重叠,两个块相邻就会导致外边距被折叠,给中间的设置BFC就会避免,方法就是套个父级设置overflow:hindden
3)阻止元素被浮动元素覆盖,各自是独立的渲染区域;
4)自适应两栏布局

为什么CSS动画比JavaScript高效?

显示器是怎么显示图像的?

每个显示器都有固定的刷新频率,通常是 60HZ,也就是每秒更新 60 张图片,更新的图片都来自于显卡中一个叫前缓冲区的地方。

显卡

显卡的职责就是合成新的图像,并将图像保存到后缓冲区中。

怎么保证显示器能读取到最新显卡合成的图像?

当显卡把合成的图像写到后缓冲区,系统就会让后缓冲区和前缓冲区互换

通常情况下,显卡的更新频率和显示器的刷新频率是一致的。但有时候,在一些复杂的场景中,显卡处理一张图片的速度会变慢,这样就会造成视觉上的卡顿。

帧 VS 帧率

  • 帧就是影像动画中最小单位的单幅影像画面。 一帧就是一副静止的画面,连续的帧就形成动画,如电视图像等。 通常说帧数,简单地说,就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次,通常用FPS(Frames Per Second)表示。每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。高的帧率可以得到更流畅、更逼真的动画。每秒钟帧数 (fps) 越多,所显示的动作就会越流畅。

  • 帧率(Frame rate)是以帧称为单位的位图图像连续出现在显示器上的频率(速率)。该术语同样适用于胶片和摄像机,计算机图形和动作捕捉系统。帧速率也可以称为帧频率,并以赫兹(Hz)表示。

举个例子:

为什么当你通过滚动条滚动页面,或者通过手势缩放页面时,屏幕上就会产生动画的效果?

因为在滚动或者缩放操作时,渲染引擎会通过渲染流水线生成新的图片,并发送到显卡的后缓冲区

如果在一次动画过程中,渲染引擎生成某些帧的时间过久,那么就会感受到页面卡顿,那么怎么处理这种卡顿问题?

要解决卡顿问题,就要解决每帧生成时间过久的问题,为此 Chrome 对浏览器渲染方式做了大量的工作,其中最卓有成效的策略就是引入了分层和合成机制。分层和合成机制代表了当今最先进的渲染技术。

如何生成一帧图像

重排

image.png

重绘

image.png

合成

相较于重排和重绘,合成操作的路径就显得非常短了,并不需要触发布局和绘制两个阶段,如果采用了 GPU,那么合成的效率会非常高。

image.png

这三种方式的渲染路径是不同的,通常渲染路径越长,生成图像花费的时间就越多

分层和合成

分层和合成通常是一起使用的。

  • 分层:将素材分解为多个图层的操作
  • 合成:将这些图层合并到一起的操作

Chrome 是怎么实现分层和合成机制的?

在 Chrome 的渲染流水线中,分层体现在生成布局树之后,渲染引擎会根据布局树的特点将其转换为层树(Layer Tree)

绘制列表

  • 层树是渲染流水线后续流程的基础结构
  • 层树中的每个节点都对应着一个图层,下一步的绘制阶段就依赖于层树中的节点
  • 绘制阶段其实并不是真正地绘出图片,而是将绘制指令组合成一个列表

光栅化阶段

光栅化就是按照绘制列表中的指令生成图片。

每一个图层都对应一张图片,合成线程有了这些图片之后,会将这些图片合成为“一张”图片,并最终将生成的图片发送到后缓冲区。

image.png

注意:能直接在合成线程中实现的是整个图层的几何变换,透明度变换,阴影等,这些变换都不会影响到图层的内容。

合成操作是在合成线程上完成的,这也就意味着在执行合成操作时,是不会影响到主线程执行的。

分块

合成线程会将每个图层分割为大小固定的图块,然后优先绘制靠近视口的图块,这样就可以大大加速页面的显示速度。

不过有时候, 即使只绘制那些优先级最高的图块,也要耗费不少的时间,因为涉及到一个很关键的因素——纹理上传,这是因为从计算机内存上传到 GPU 内存的操作会比较慢。

为了解决这个问题,Chrome 又采取了一个策略:在首次合成图块的时候使用一个低分辨率的图片

比如可以是正常分辨率的一半,分辨率减少一半,纹理就减少了四分之三。在首次显示页面内容的时候,将这个低分辨率的图片显示出来,然后合成器继续绘制正常比例的网页内容,当正常比例的网页内容绘制完成后,再替换掉当前显示的低分辨率内容。

如何利用分层技术优化代码 ?

如果涉及到一些可以使用合成线程来处理 CSS 特效或者动画的情况,就尽量使用 will-change 来提前告诉渲染引擎,让它为该元素准备独立的层。但同时占用的内存也会大大增加,因为从层树开始,后续每个阶段都会多一个层结构。

例子:使用 will-change 来告诉渲染引擎你会对该元素做一些特效变换,CSS 代码如下:

.box {
	will-change: transform, opacity;
}

这段代码就是提前告诉渲染引擎 box 元素将要做几何变换和透明度变换操作,这时候渲染引擎会将该元素单独实现一层,等这些变换发生时,渲染引擎会通过合成线程直接去处理变换,这些变换并没有涉及到主线程,这样就大大提升了渲染的效率。这也是 CSS 动画比 JavaScript 动画高效的原因。

什么情况下出现浏览器分层?(css部分)

分层和合成

通常页面的组成是十分复杂的,有的页面里要实现一些复杂的动画效果,比如点击菜单时弹出菜单的动画特效,滚动鼠标滚轮时页面滚动的动画效果,以及还有一些比较炫酷的3D动画效果。如果没有采用分层机制,从布局树直接生成目标图片的话,那么每次页面有很小的变化时,都会触发重排或者重绘机制,这种"牵一发而动全身"的绘制策略会严重影响页面的渲染效率。

为了提升每帧的渲染效率,Chrome引入了分层和合成的机制

你可以把一张网页想象成是由很多个图片叠加在一起的,每个图片就对应着一个图层,Chrome合成器最终将这些图层合成了用于显示页面的图片。如果你比较熟悉PS的话,就很好的理解这个过程,PS中一个项目是由很多图层构成的,每个图层都可以是一张单独的图片,可以设置透明度、边框阴影,可以旋转或者设置图层的上下位置,将这些图层叠加在一起后,就能呈现出最终的图片了

在这个过程中,将素材分解为多个图层操作的就称之为分层,最后将这些图层合并在一起的操作就称为合成。所以,分成和合成通常是一起使用的

考虑一个页面被划分为两个层,当进行到下一帧的渲染时,上面的一帧可能需要实现某些变换,如平移、旋转、缩放、阴影或者渐变,这个时候合成器只需要将两个层进行相应的变化操作就可以,显卡处理这些操作驾轻就熟,所以合成时间非常短

生成层的方式

在某些特定的条件下,浏览器会主动将渲染层提至合成层,那么影响这个合成因素有哪些?

  • 3D transforms: translate3d, translateZ等
  • video,canvas,iframe等
  • 通过Element.animate()实现的opacity动画转化
  • 通过CSS动画实现的opacity动画转换
  • position: fixed
  • will-change
  • filter
  • 有合成层后代同时本身overflow不为visible(如果本身是因为明确的定位因素产生的SelfPaintingLayer,则需要z-index不为auto)

在css中link和@import的区别是什么?

  • 1.从属关系区别:

    link是属于html标签,而@import是css提供的

  • 2.加载顺序区别:

    页面被加载时,link会同时加载,而@import引用的css会等到页面被加载完再加载

  • 3.兼容性区别:

    import只在IE5以上才能识别,而link是html标签,无兼容问题

  • 4.dom可操作性的区别:

    可以通过js操作dom,插入link标签来改变样式;由于dom方法是基于文档的,无法使用@import的方式插入样式

  • 5.权重区别:

    在.css文件用import引入时,如果已经存在相同样式,@import引入的这个样式将被该css文件本身的样式层叠掉,表现出link方式的样式权重高于@import的权重这样的直观效果

简而言之:link和@import,谁写在后面,谁的样式就被应用,后面的样式覆盖前面的样式

了解 CSS 模块吗?

CSS 发展的历程:

1. 手写原始CSS
2. 使用预处理器:Sass、Less
3. 使用后处理器:PostCss
4. 使用Css Modules
5. 使用Css in Js


随着 react、vue 等基于模块化框架的普及使用,我们编写原生 css 的机会也越来越少。我们常常将页面拆分成许多个小组件,然后像搭积木一样将多个小组件组成最终呈现出的页面。

但是我们知道的是,css 是根据类名去匹配元素的,如果有两个组件使用了一个相同的类名,后者就会把前者的样式给覆盖掉,看来解决样式命名的冲突是个大问题。为了解决这个问题,产生了 css 模块化的概念。

BEM 的意思是:块(block)、元素(element)、修饰符(modifier),是由 Yandex 团队提出的一种前端命名方法论。这种巧妙的命名方法让你的 css 类对其他开发者来说更加透明且更有意义。

CSS Modules 指的是:我们像 js 中 import 一样去引入 css 代码,代码中的每一个类名都是引入对象的一个属性,通过这种方式,即可在使用时明确指定所引用的 css 样式

并且 CSS Modules 在打包的时候会自动将类名转换成 hash 值,完全杜绝 css 类名冲突的问题。

    1. 定义 css 文件
.className {
  color: green;
}
/* 编写全局样式 */
:global(.className) {
  color: red;
}

/* 样式复用 */
.otherClassName {
  composes: className;
  color: yellow;
}

.otherClassName {
  composes: className from "./style.css";
}
    1. 在 js 模块中导入 css 文件
import styles from "./style.css";

element.innerHTML = '<div class="' + styles.className + '">';
    1. 配置 css-loader 打包

CSS Modules 不能直接使用,而是需要进行打包,一般通过配置 css-loader 中的 modules 属性即可完成 css Modules 的配置

    1. 配置 css-loader 打包

CSS Modules 不能直接使用,而是需要进行打包,一般通过配置 css-loader 中的 modules 属性即可完成 css Modules 的配置

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        use:{
          loader: 'css-loader',
          options: {
            modules: {
              // 自定义 hash 名称
              localIdentName: '[path][name]__[local]--[hash:base64:5]',
            }
          }
       }
    ]
  }
};
    1. 最终打包出来的 css 类名就是由一长串 hash 值生成
._2DHwuiHWMnKTOYG45T0x34 {
  color: red;
}

._10B-buq6_BEOTOl9urIjf8 {
  background-color: blue;
}
  • CSS in JS

css in js :使用 js 语言写 css,完全不需要写单独的 css 文件,所用的 css 代码全部放在组件内部来实现 css 的模块化。常用的库是styled-components

import React from "react";
import styled from "styled-components";

// 创建一个带样式的 h1 标签
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// 创建一个带样式的 section 标签
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// 通过属性动态定义样式
const Button = styled.button`
  background: ${(props) => (props.primary ? "palevioletred" : "white")};
  color: ${(props) => (props.primary ? "white" : "palevioletred")};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

// 样式复用
const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

<Wrapper>
  <Title>Hello World, this is my first styled component!</Title>
  <Button primary>Primary</Button>
</Wrapper>;

可以得知:在 js 中直接编写 css,在定于原生 html 时就创建好了样式,在使用的时候就可以渲染出带样式的组件了

  • CSS Modules 与 CSS in JS优缺点分析
CSS Modules
  书写方式和原生 css 一样,只有在使用的时候变成了模块化引入,主要目的提供 css 作用域,避免全局样式污染,缺点:难以和外部样式进行混合使用

CSS in JS
  书写方式全部变成内联样式,完全在js中书写 css ,主要目的:和css Modules 一样,能够无缝使用 js 变量,简单高效,缺点:违背了 js css 分离原则,不能使用预处理器,对编辑器不友好

DOMContentLoaded事件和Load事件的区别?

当开始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发而无需等待样式表、图像和子框架的加载完成。

Load 事件是当所有资源加载完成后触发的。

iframe有哪些缺点?

iframe 元素会创建包含另外一个文档的内联框架(即行内框架)


主要缺点有:
(1iframe 会阻塞主页面的 onload 事件。windowonload 事件需要在所有 iframe加载完毕后(包含里面的元素)才会触发。在 SafariChrome 里,通过 JavaScript 动态设置 iframesrc 可以避免这种阻塞情况。
(2) 搜索引擎的检索程序无法解读这种页面,不利于网页的 SEO 。
(3iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的
并行加载。
(4) 浏览器的后退按钮失效。
(5) 小型的移动设备无法完全显示框架。

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

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

使用 base64 的优点是:减少一个图片的 HTTP 请求 

使用 base64 的缺点是:

-   1.根据 base64 的编码原理,编码后的大小会比原文件大小大 1/3,如果把大图片编码到html/css 中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对 html 或 css 文件解析渲染的时间。
-   2.使用 base64 无法直接缓存,要缓存只能缓存包含 base64 的文件,比如 HTML 或者 CSS,这相比域直接缓存图片的效果要差很多。
-   3.兼容性的问题,ie8 以前的浏览器不支持。

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