前言
不论是寒冬还是暖冬, 找工作之前都需要做好充足的准备, 面试的时候才能做到游刃有余. 此文是把我最近找工作准备的以及笔试面试中涉及到的手写题做一个总结. 给自己, 也给需要的同学.
CSS 是前端必须要掌握的技能之一. 一般面试也都会从 CSS 开始. 所以 CSS 问题答的好坏会直接影响你在面试官心中的形象.
本文主要介绍面试中常会遇到的 CSS 问题及给出建议性的答案.
往期
"寒冬" 三年经验前端面试总结(含头条, 百度, 饿了么, 滴滴等)
"寒冬" 三年经验前端面试总结 (含头条, 百度, 饿了么, 滴滴等) 之手写题(一)
"寒冬" 三年经验前端面试总结 (含头条, 百度, 饿了么, 滴滴等) 之手写题(二)
"寒冬" 三年经验前端面试总结 (含头条, 百度, 饿了么, 滴滴等) 之手写题(promise 篇)
盒模型
盒模型感觉是刚学前端的时候就会接触到的问题. 元素都是按照盒模型的规则布局在页面中的. 盒模型由 margin + border + padding + content 四个属性组成, 分为两种: W3C 的标准盒模型和 IE 盒模型.
W3C 的标准盒模型
width = content, 不包含 border + padding
IE 盒模型
width = border + padding + content
相互转换
二者之间可以通过 CSS3 的 box-sizing 属性来转换.
box-sizing: content-box 是 W3C 盒模型
box-sizing: border-box 是 IE 盒模型
垂直居中的方法
垂直居中的方法, 如果全写出来, 有 10 多种. 面试的时候一般都会说比较常用的几种. flex,position + transform,position + 负 margin 是最常见的三种情况.
- <div class="outer">
- <div class="inner"></div>
- </div>
方法一: flex
- .outer{
- display: flex;
- justify-content: center;
- align-items: center
- }
方法二: position + transform, inner 宽高未知
- .outer{
- position:relative;
- }
- .inner{
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%,-50%);
- }
方法三: position + 负 margin, inner 宽高已知
- .outer{
- position: relative;
- }
- .inner{
- width: 100px;
- height: 100px;
- position: absolute;
- left: 50%;
- top: 50%;
- margin-left: -50px;
- margin-top: -50px;
- }
方法四: 设置各个方向的距离都是 0, 再将 margin 设为 auto, 也可以实现, 前提是 inner 宽高已知
- .outer {
- position: relative;
- }
- .inner {
- width: 100px;
- height: 100px;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- margin: auto;
- }
三栏布局
三栏布局是很常见的一种页面布局方式. 左右固定, 中间自适应. 实现方式有很多种方法.
第一种: flex
- <div class="container">
- <div class="left">left</div>
- <div class="main">main</div>
- <div class="right">right</div>
- </div>
- .container{
- display: flex;
- }
- .left{
- flex-basis:200px;
- background: green;
- }
- .main{
- flex: 1;
- background: red;
- }
- .right{
- flex-basis:200px;
- background: green;
- }
第二种: position + margin
- <div class="container">
- <div class="left">left</div>
- <div class="right">right</div>
- <div class="main">main</div>
- </div>
- body,html{
- padding: 0;
- margin: 0;
- }
- .left,.right{
- position: absolute;
- top: 0;
- background: red;
- }
- .left{
- left: 0;
- width: 200px;
- }
- .right{
- right: 0;
- width: 200px;
- }
- .main{
- margin: 0 200px ;
- background: green;
- }
第三种: float + margin
- <div class="container">
- <div class="left">left</div>
- <div class="right">right</div>
- <div class="main">main</div>
- </div>
- body,HTML{
- padding:0;
- margin: 0;
- }
- .left{
- float:left;
- width:200px;
- background:red;
- }
- .main{
- margin:0 200px;
- background: green;
- }
- .right{
- float:right;
- width:200px;
- background:red;
- }
CSS 权重计算方式
CSS 基本选择器包含 ID 选择器, 类选择器, 标签选择器, 通配符选择器.
正常情况下, 一般都能答出! important> 行内样式> ID 选择器> 类选择器> 标签选择器> 通配符选择器.
但如果这几种选择器同时作用于一个元素时, 该元素最后应用哪个样式呢? 这就涉及到权重计算的问题.
关于权重计算, 有两种不同的计算方式: 一种是以二进制的规则计算, 一种是以 1,10,100,1000 这种的计算方式. 我更倾向于二进制的这种方式.
各选择器权值:
内联样式, 权值为 1000
ID 选择器, 权值为 0100
类, 伪类和属性选择器, 权值为 0010
标签选择器和伪元素选择器, 权值为 0001
通配符, 子选择器, 相邻选择器等, 权值为 0000
继承的样式没有权值
比较方式:
如果层级相同, 继续往后比较, 如果层级不同, 层级高的权重大, 不论低层级有多少个选择器.
BFC
BFC 的全称为 Block Formatting Context, 也就是块级格式化上下文的意思.
以下方式都会创建 BFC:
根元素(HTML)
浮动元素(元素的 float 不是 none)
绝对定位元素(元素的 position 为 absolute 或 fixed)
行内块元素(元素的 display 为 inline-block)
表格单元格(元素的 display 为 table-cell,HTML 表格单元格默认为该值)
表格标题(元素的 display 为 table-caption,HTML 表格标题默认为该值)
匿名表格单元格元素 (元素的 display 为 table,table-row,table-row-group,table-header-group,table-footer-group(分别是 HTML table,row,tbody,thead,tfoot 的默认属性) 或 inline-table)
overflow 值不为 visible 的块元素
display 值为 flow-root 的元素
contain 值为 layout,content 或 paint 的元素
弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
多列容器(元素的 column-count 或 column-width 不为 auto, 包括 column-count 为 1)
column-span 为 all 的元素始终会创建一个新的 BFC, 即使该元素没有包裹在一个多列容器中(标准变更, Chrome bug).
BFC 布局规则:
内部的 box 会在垂直方向, 一个接一个的放置.
box 垂直方向的距离有 margin 决定. 属于同一个 BFC 的两个相邻 box 的 margin 会发生重叠. 3. 每个元素的左外边距与包含块的左边界相接触, 即使浮动元素也是如此.
BFC 的区域不会与 float 的元素区域重叠.
计算 BFC 的高度时, 浮动子元素也参与计算.
BFC 就是页面上一个隔离的独立容器, 容器里面的子元素不会影响到外面的元素, 反之亦然.
BFC 能解决的问题:
父元素塌陷
外边距重叠
清除浮动
清除浮动的方法
清除浮动主要是为了防止父元素塌陷. 清除浮动的方法有很多, 常用的是 clearfix 伪类.
方法一: clearfix
- <div class="outer clearfix">
- <div class="inner">inner</div>
- </div>
- .outer{
- background: blue;
- }
- .inner{
- width: 100px;
- height: 100px;
- background: red;
- float: left;
- }
- .clearfix:after{
- content: "";
- display: block;
- height: 0;
- clear:both;
- visibility: hidden;
- }
方法二: 额外加一个 div,clear:both
- <div class="container">
- <div class="inner"></div>
- <div class="clear"></div>
- </div>
- .container{
- background: blue;
- }
- .inner {
- width: 100px;
- height: 100px;
- background: red;
- float: left;
- }
- .clear{
- clear:both;
- }
方法三: 触发父盒子 BFC,overflow:hidden
- <div class="outer">
- <div class="inner">inner</div>
- </div>
- .outer{
- background: blue;
- overflow: hidden;
- }
- .inner {
- width: 100px;
- height: 100px;
- background: red;
- float: left;
- }
flex 布局
flex 布局现在已经很普及的在用了. 垂直居中用 flex 实现起来很简单. 关于 flex 的属性也不是很多, 父容器和子容器各 6 个, 一共 12 个, 比较好记.
下面是我复习 flex 属性时的一张导图.
position 属性
position 属性的重要性应该没啥可说的了. 想必谁都回答的上来.
absolute 绝对定位, 相对于 static 定位以外的第一个父元素进行定位.
relative 相对定位, 相对于其自身正常位置进行定位.
fixed 固定定位, 相对于浏览器窗口进行定位.
static 默认值. 没有定位, 元素出现在正常的流中.
inherit 规定应该从父元素继承 position 属性的值.
但是要注意一个问题, absolute 是相对于父元素的哪个属性进行定位的? 通过下面的例子我们来看一看.
- .container{
- position: relative;
- width: 30px;
- height: 30px;
- margin: 20px;
- border: 10px solid red;
- padding: 10px;
- background: blue;
- }
- .inner {
- position: absolute;
- width: 10px;
- height: 10px;
- top: 0;
- left: 0;
- background: pink;
- }
从上图可以看出, 是相对于 static 定位以外的第一个父元素的 padding 来定位的.
CSS3 中新增了一个 position:sticky 属性, 该属性的作用类似 position:relative 和 position:fixed 的结合. 元素在跨越特定阈值前为相对定位, 之后为固定定位. 必须指定 top, right, bottom 或 left 四个阈值其中之一, 才可使粘性定位生效. 否则其行为与相对定位相同. 但 sticky 尚在实验性阶段.
如何实现一个自适应的正方形
方法 1: 利用 CSS3 的 vw 单位
vw 会把视口的宽度平均分为 100 份
- .square {
- width: 10vw;
- height: 10vw;
- background: red;
- }
方法 2: 利用 margin 或者 padding 的百分比计算是参照父元素的 width 属性
- .square {
- width: 10%;
- padding-bottom: 10%;
- height: 0; // 防止内容撑开多余的高度
- background: red;
- }
如何用 CSS 实现一个三角形
方法 1: 利用 border 属性
利用盒模型的 border 属性上下左右边框交界处会呈现出平滑的斜线这个特点, 通过设置不同的上下左右边框宽度或者颜色即可得到三角形或者梯形.
- .triangle {
- height:0;
- width:0;
- border-color:red blue green pink;
- border-style:solid;
- border-width:30px;
- }
如果想实现其中的任一个三角形, 把其他方向上的 border-color 都设置成透明即可.
- .triangle {
- height:0;
- width:0;
- border-color:red transparent transparent transparent;
- border-style:solid;
- border-width:30px;
- }
方法二: 利用 CSS3 的 clip-path 属性
不了解 clip-path 属性的可以先看看 MDN 上的介绍: chip-path
- .triangle {
- width: 30px;
- height: 30px;
- background: red;
- clip-path: polygon(0px 0px, 0px 30px, 30px 0px); // 将坐标 (0,0),(0,30),(30,0) 连成一个三角形
- transform: rotate(225deg); // 旋转 225, 变成下三角
- }
写在最后
有错误之处还请小伙伴们及时指出, 以免误人子弟. 想看往期内容, 翻到页面最上面有链接~
来源: https://segmentfault.com/a/1190000020966360