CSS面试题整理

14,012 阅读14分钟

😂这只是个人笔记……我没想到居然有人看到……

题目来源: 前端开发面试题

答案基本是自己整理的。并不是全部题目都有。

会有很多自己的啰嗦,还有很多乱七八糟的补充,请见谅。

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

盒子模型有两种:IE 盒子模型(IE5.5及以下),W3C标准盒子模型。

  • 盒子模型(box model):

    内容(content)、填充(padding)、边框(border)、边界(margin) 。

  • 不同:

    W3C标准盒子模型的width和height,是content的宽高;

    IE盒模型的width和height,是content、padding、border三部分合起来的宽高。


  • 附加:

    outline(轮廓)绘制在元素框之上,其不占据空间(不影响元素大小和定位)【所以如果轮廓线很粗,会遮住其他内容demo,不是很懂轮廓的覆盖顺序,它居然可以盖住下一个元素的内容?轮廓本身是另一次元的吗?会覆盖内容,但后一个轮廓会覆盖前一个轮廓】。

    兼容性:IE8以上。

其他参考:关于外边距的一些实践上的细节, 解决盒模型的兼容性问题

如何居中div?

水平居中

  • 已知宽度, block元素:

    添加margin:0 auto属性。

    div{
    	width:200px;
    	margin:0 auto;
     }
    
  • 已知宽度, 绝对定位的div居中:

    div {
    	position: absolute;
    	width: 300px;
    	height: 300px;
    	margin: auto; /* 这一步很关键 */
    	top: 0;
    	left: 0;
    	bottom: 0;
    	right: 0;
    	background-color: pink;	/* 方便看效果 */
    }
    
  • 未知宽度,fit-content:

    兼容性很差。

    div {
        width: fit-content;
        margin: auto;
        background-color: pink;	/* 方便看效果 */
    }
    
  • 未知宽度,inline-block:

    .parent {
        text-align: center;
    }
    div {
        display: inline-block;
        background-color: pink;	/* 方便看效果 */
    }
    
  • 未知宽度/已知宽度,relative:

    参考:三、浮动实现水平居中的方法

    • 优点:兼容性强,扩展性强;
    • 缺点:实现原理较复杂。

    需要两个div,外层left 50%,内层left -50%。

    floatinline-block,使容器大小为内容大小,而非默认的100%。

    .outter {
        display: inline-block; /* or float: left; */
        position: relative;
        left: 50%;
    }
    .inner {
        position: relative;
        left: -50%;
    }
    
    • left的值为百分比时,为父容器的宽度的百分比(MDN)。

水平垂直居中

  1. 确定容器宽高:

    相对或绝对定位, 设置外边距margin。

    div {
    	position: relative / fixed; /* 相对定位或绝对定位均可 */
    	width:500px;
    	height:300px;
    	top: 50%;
    	left: 50%;
    	margin: -150px 0 0 -250px;  /* 外边距为自身宽高的一半 */
    	background-color: pink; /* 方便看效果 */
     }
    
  2. 不确定容器宽高:

    绝对定位,利用 transform 属性。

    div {
    	position: absolute/fixed; /* relative会让width变成100%,
                                     所以不行
                                   */
    	top: 50%;
    	left: 50%;
    	transform: translate(-50%, -50%);
    	background-color: pink; /* 方便看效果 */
    }
    
    
  3. flex 布局:

    宽高可以确定,也可以不确定。

    实际使用时应考虑兼容性。

    .container {
    	display: flex;
    	align-items: center; 		/* 垂直居中 */
    	justify-content: center;	/* 水平居中 */
    
    }
    .container div {
    	width: 100px; /* 可省 */
    	height: 100px; /* 可省 */
    	background-color: pink;	/* 方便看效果 */
    }  
    
  4. inline-block:

    宽高可以确定,也可以不确定。

    水平居中:text-align。

    垂直居中:父元素line-height与height同值,子元素 vertical-align。

    缺点:内层高度超出外层,无法垂直居中,会和父层同顶部(参见demo)。

    .container {
        height: 200px; /* 垂直居中 */
        line-height: 200px; /* 垂直居中 */
        text-align: center; /* 水平居中 */
    }
    .container div {
        display: inline-block; /* 核心:宽度自适应,高度可居中 */
        line-height: 20px; /* 会自动继承,必须设置不同的值来覆盖 */
        vertical-align: middle; /* 垂直居中 */
    }  
    

CSS选择符有哪些?

  1. id选择器( #myid)
  2. 类选择器(.myclassname)
  3. 标签选择器(div, h1, p)
  4. 紧邻同胞选择器 h1 + p(选的是h1后紧跟的那个p)
  5. 一般同胞选择器 h1 ~ p(选择所有跟在h1后的p)[css3]
  6. 子选择器(ul > li)
  7. 后代选择器(li a)
  8. 通配符选择器( * )
  9. 属性选择器(a[rel = "external"])
  10. 伪类选择器(a:hover, li:nth-child)

  • 伪元素 & 伪类:
    • 所有伪元素:
      ::after
      ::before
      ::first-letter
      ::first-line
      ::selection
      
    • 伪类:
      :active, :hover, :visited
      :any
      :any-link
      :checked
      :default
      :defined
      :dir()
      :disabled
      :empty
      :enabled
      :first
      :first-child
      :first-of-type
      :fullscreen
      :focus
      :focus-visible
      :host
      :host()
      :host-context()
      :indeterminate
      :in-range
      :invalid
      :lang()
      :last-child
      :last-of-type
      :left
      :link
      :not()
      :nth-child()
      :nth-last-child()
      :nth-last-of-type()
      :nth-of-type()
      :only-child
      :only-of-type
      :optional
      :out-of-range
      :read-only
      :read-write
      :required
      :right
      :root
      :scope
      :target
      :valid
      

通配符选择器有一个非常有意思的用法,即用它构成非子选择符,比如:

section * a {font-size:1.3em;}

任何是 section 孙子元素,而非子元素的 a 标签都会被选中。至于 a 的父元素是什么,没有关系。

哪些属性可以继承?

  • 所有元素可继承

    visibility
    
    cursor
    
  • 内联元素可继承:

    letter-spacing word-spacing
    
    white-space
    
    line-height
    
    color
    
    font font-family font-size font-style font-variant font-weight
    
    text-decoration text-transform
    
    direction
    

    font-variant:把段落设置为小型大写字母字体。

    text-transform: 控制文本中的字母的大小写。

  • 块状元素可继承:

    //文本块中首行文本的缩进
    text-indent 
    
    text-align
    
  • 列表元素可继承:

    list-style
    list-style-type
    list-style-position
    list-style-image
    
  • 表格元素可继承:

    /*
        1. separate	默认值。边框会被分开。
          不会忽略 border-spacing 和 empty-cells 属性。
        2. collapse	如果可能,边框会合并为一个单一的边框。
          会忽略 border-spacing 和 empty-cells 属性。
        3. inherit	规定应该从父元素继承 border-collapse 属性的值。
    */
    border-collapse
    
  • 不可继承的样式:

    display
    
    position left right top  bottom z-index
    
    height min-height max-height
    width min-width max-width
    
    padding border margin
    
    background
    
    overflow
    
    float clear
    
    vertical-align
    
    /*下面几个都没见过*/
    
    table-layout /*表格宽度是否自适应。值:automatic,fixed,inherit*/
    
    page-break-after page-break-before /*打印时强制分页*/
    
    unicode-bidi /*与direction合用,控制文字方向*/
    

CSS优先级算法如何计算?

  • 优先级就近原则,同权重情况下样式定义最近者为准;
  • 载入样式以最后载入的定位为准。

优先级为:

// 同权重下,权限由高到低: 
1.元素标签里(行内样式/内联样式)
2.写在<style>标签里(嵌入样式)
3.写在单独的 CSS 样式表中(链接样式)
4.在样式表中链接其他样式表:@import url(css/styles2.css)

// 不同权重计算
!important >  id > class > tag

// !important优先于一切
!important 比 内联优先级高

权重计算方法:

// 选择器的特殊性值表述为4个部分,用0,0,0,0表示。

行间样式的特殊性是1,0,0,0

ID选择器的特殊性值,加0,1,0,0。

类选择器、属性选择器或伪类,加0,0,1,0。

元素和伪元素,加0,0,0,1。

通配选择器 * 对特殊性没有贡献,即0,0,0,0。

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

more: 详细的优先级计算方法

image

CSS3新增伪类有哪些?

参考:MDN - CSS新特性

伪类 说明
:last-child 父元素的最后一个子元素。
:nth-child(an+b) 找到所有当前元素的子元素;
按照位置先后顺序从1开始排序,选择的结果为第 an+b 个元素的集合(n = 0, 1, 2, ...)。
:nth-last-child(an+b) :nth-child(an+b)类似,只是它从结尾处逆序计数,而不是从开头处。↪ MDN
:only-child 属于某个父元素的唯一一个子元素,即选择没有同胞的所有元素。


:first-of-type 父元素下,每个元素类型中,最靠前的那个。
:last-of-type 父元素下,每个元素类型中,最靠后的那个。
:nth-of-type(an+b) 父元素下,每个元素类型中,第n个。

找到当前元素下,同元素类型的所有子元素的集合,
对每个集合按照位置先后顺序排序,
选择的结果为第 an+b 个元素的集合。
:nth-last-of-type(an+b) 基本上和 :nth-of-type 一样,只是它从结尾处逆序计数,而不是从开头处。
:only-of-type 选择不同于其他同胞元素的tag类型的元素,就是说,这个元素类型的元素在其父元素下,同一级只有这一个。(类比家庭中的男孩和女孩)


:enabled 每个启用的的元素(主要用于表单元素)。
:disabled 禁用的元素(主要用于控制表单控件的禁用状态)。
:checked 单选框或复选框被选中。
:indeterminate 表示不确定状态。
1.<input type="checkbox"> 元素,其 indeterminate 属性被 JavaScript设置为 true;
2.<input type="radio"> 元素, 表单中拥有相同 name值的所有单选按钮都未被选中时;
3.处于不确定状态的 <progress> 元素
:target <a>跳转#锚点,可设置锚点目标的样式。MDN
:root 匹配文档树的根元素。
对于 HTML 来说,:root 表示 <html> 元素,除了优先级更高之外,与 html 选择器相同。
:empty 没有子元素的元素。
子元素只可以是元素节点或文本(包括空格)。MDN
注释不算在内,但注释周围有空格就算。
:not(X) 匹配不符合参数选择器X描述的元素。
X不能包含另外一个否定选择器
:not伪类的优先级即为它参数选择器的优先级。
:not伪类不像其它伪类,它不会增加选择器的优先级
:not(p) 将匹配任何非p元素,包括htmlbody。(所以用的时候千万小心,如果设置了什么color,可能会出现非自己预料的情况,比如全成一样的颜色。↪ bug demo)

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

display 说明
css1
none 元素不显示,并从文档流中移除。
inherit 从父元素继承 display 属性的值。
block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
list-item 像块类型元素一样显示,并添加样式列表标记。
css2
inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
table 作为块级表格来显示。
flex 弹性元素如何伸长或缩短以适应flex容器中的可用空间。
grid 网格布局

position的值relative和absolute定位原点是?

position 说明
static 默认值。
没有定位,元素出现在正常的流中
(忽略 top, bottom, left, right, z-index 声明)。
inherit 从父元素继承 position 属性的值。
absolute 绝对定位。
不为元素预留空间,
相对于最近的非 static 定位的祖先元素进行定位。
fixed (老IE不支持) 绝对定位。
不为元素预留空间,
相对于浏览器窗口进行定位。
元素的位置在屏幕滚动时不会改变。
relative 相对定位。
相对于其正常位置进行定位。
该关键字下,元素先放置在未添加定位时的位置,
再在不改变页面布局的前提下调整元素位置
(因此会在此元素未添加定位时所在位置留下空白)。

相对定位的元素并未脱离文档流,而绝对定位的元素则脱离了文档流。

CSS3有哪些新特性?

  1. 圆角 (border-radius:8px)

  2. 新增各种CSS选择器、伪类 (经常用到 :nth-child)

  3. 文字渲染 (Text-decoration)

    转化为简写属性,可设置text-decoration-color, text-decoration-style, text-decoration-line三个属性,默认值为currentcolor solid none

  4. 透明色 & 透明度(opacity)

  5. 旋转 (transform)

    旋转 rotate,缩放 scale,倾斜 skew,平移 translate

  6. 动画(animation) & 过渡效果(transition)

  7. 阴影(box-shadow, text-shadow)

    box-shadow: x-offset y-offset blur-radius spread-radius color;
    
    text-shadow: x-offset y-offset blur-radius color;
    
  8. 新的布局方式,如 多列布局 multi-columns 、 弹性布局 flexible box 与 网格布局 grid layouts

  9. 线性渐变(gradient)

  10. 多背景(background-image可以设置多个url或linear-gradient)

  11. 媒体查询(@media MDN) (可以看看这个)

  12. 边框可以设置图片(border-image)

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

MDN

什么是flexbox

CSS3新增布局。

Flexbox可以把列表放在同一个方向(从上到下排列,从左到右),并让列表能延伸到占用可用的空间。

较为复杂的布局还可以通过嵌套一个伸缩容器(flex container)来实现。

  • 采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。

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

常规布局是基于块和内联流方向,而Flex布局是基于flex-flow流可以很方便的用来做局中,能对不同屏幕大小自适应。

在布局上有了比以前更加灵活的空间。

具体:www.w3cplus.com/css3/flexbo…

应用场景

  1. 水平垂直居中

  2. 一边定宽,一边自适应

  3. 多列等分布局

  4. 圣杯布局

  5. sticky footer

我在项目中的应用

  1. sticky footer (demo)

    如果页面内容不够长的时候,footer固定在视窗底部;如果内容足够长时,footer会被内容向下推。

    <div class="detail-flex">
        <div class="detail-content">detail-content</div>
        <div class="detail-footer">detail-footer</div>
    </div>
    
    .detail-flex
        display: flex
        flex-direction: column
        position: fixed
        z-index: 100
        top: 0
        left: 0
        width: 100%
        height: 100%
        overflow: auto
        
        .detail-content
            flex: 1 0 auto
            
        .detail-footer
            flex: 0 0 auto
    

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

border

不同宽高下的border:详情请戳demo

border_diff

基础

把上、左、右三条边隐藏掉(颜色设为 transparent)。

div {
  width: 0;
  height: 0; /* div里没内容,可不写 */
  border-width: 20px;
  border-style: solid;
  border-color: transparent transparent red transparent;
}

/* 或者这样写 */
div {
  width: 0;
  border: 100px solid transparent;
  border-bottom-color: #343434;
}

等边三角形

显示部分的宽度 = transparent部分的宽度 * √3

√3 ≈ 1.732

div {
  width: 0;
  border: 100px solid transparent;
  border-bottom: 173px solid #343434;
}

直角三角形

设置两边的宽度为0。

/* 填充右下角的三角形 */
div {
  width: 0
  border: 0 solid transparent
  border-left: 100px solid transparent
  border-bottom: 100px solid #343434
}

带边框的三角形

pen demo

两个重叠。(但是不够智能)

<div id="col1"></div>
<div id="col2"></div>
body, html
  margin: 0
  background-color: #333
#col1, #col2
  width: 0
  border: 100px solid transparent
  border-bottom: 173px solid #fff
#col2
  position: absolute
  left: 0
  top: 2px
  border-bottom-color: #222
  transform: scale(0.98)

css多列等高如何实现?

参考:八种创建等高列布局

1. 背景图

  • 优点:

    实现方法简单,兼容性强,不需要太多的css样式就可以轻松实现。

  • 缺点:

    使用这种方法不适合流体布局等高列的布局;

    需要更换背景色或实现其他列数的等高列时,都需要重新制作过背景图。

2. div嵌套+position

demo

原理图:

image

  • 优点:

    不需要借助其他东西(javascript,背景图等),而是纯CSS和HTML实现的等高列布局;

    兼容所有浏览器(包括IE6),并且可以很容易创建任意列数。

  • 缺点:

    不像其他方法一样简单明了,给你理解会带来一定难度;

    复杂的div嵌套,html语义不清晰(你有多少列就需要多少个容器)。

3. 正padding和负margin正负值相抵

demo

  • 原理:

    利用padding-bottom|margin-bottom正负值相抵;

    设置父容器设置超出隐藏(overflow:hidden),这样子父容器的高度就还是它里面的列没有设定padding-bottom时的高度, 当它里面的任一列高度增加了,则父容器的高度被撑到里面最高那列的高度, 其他比这列矮的列会用它们的padding-bottom补偿这部分高度差。

  • 优点:

    可实现多列等高布局;

    能实现列与列之间分隔线效果;

    结构简单;

    兼容所有浏览器。

  • 缺点:

    若希望每列四周有边框,则底部(或顶部)边框无法显示。

  • 缺点解决办法:

    1. 用和边框一致的背景图(我不喜欢这种类型的方法,后续更改很麻烦)

    2. 使用div来模仿列的边框

      demo

      每列中添加一个div(可以直接用::after伪元素代替),设置定位为absolute;

      在列的上一级的wrapper中,定位relative;

      这样,就能让absolute根据wrapper的大小和位置进行定位了。

4. 边框 + 绝对定位/float “模拟”

绝对定位 demofloat demo

感觉思路上其实与“2. div嵌套+position”类似,都是在底部设置背景层,再在上面铺文字层。(我自己改了以下,这样也行 ↪ demo

  • 优点:

    结构简单,兼容各浏览器,容易掌握。

  • 缺点:

    受限于边框+内容最多三栏,所以无法实现三栏以上的效果。

5. 模拟表格布局

demo

  • 优点:

    这是一种非常简单,易于实现的方法。

  • 缺点:

    兼容性不好,在ie6-7无法正常运行。

6. flex布局

  • 优点:

    简单易用,适用于移动端。

  • 缺点:

    CSS3新功能,不兼容老的浏览器。