常见的CSS面试题(一)

208 阅读4分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

浏览器内核

  • IE Trident
  • Chrome Blink
  • Firefox Gecko
  • Safari Webkit

了解盒模型吗,现在给定一个 width:200px的盒子,他的width,padding,border,margin都是怎样的

Margin(外边距) - 清除边框外的区域,外边距是透明的。 Border(边框) - 围绕在内边距和内容外的边框。 Padding(内边距) - 清除内容周围的区域,内边距是透明的。 Content(内容) - 盒子的内容,显示文本和图像。

  • W3C的标准盒模型:width指content部分的宽度
  • IE盒模型:width表示content+padding+border这三个部分的宽度

如果想要切换盒模型也很简单,这里需要借助css3的box-sizing属性

box-sizing: content-box 是W3C盒子模型 box-sizing: border-box 是IE盒子模型 box-sizing的默认属性是content-box

两/三栏布局

  • 浮动布局

    <div id = "aside">
    </div>
    <div id = "main">
    </div>
    
    div{
      height:500px;
    }
    #aside{
      width:300px;
      background-color:yellow;
      float:left;
    }
    #main{
      background-color:aqua;
      margin-left:300px;
    }
    

    左侧栏固定宽度向左浮动,右侧主要内容则用margin-left留出左侧栏的宽度,默认宽度为auto,自动填满剩下的宽度。

float1.png

右侧固定宽度,左侧自适应则是同理,只要将固定栏右浮动,使用margin-right空出其宽度即可。

  • 浮动布局+负外边距(双飞翼布局的两栏版)

    这种方法是创建简单一列宽度固定,一列内容为宽度的100%的两列布局的好方法:

    <div id = "aside">
    </div>
    <div id = "main">
      <div id = "content"></div>
    </div>
    
    div{
      height:500px;
    }
    #aside{
      width:300px;
      background-color:yellow;
      float:left;
      margin-right:-100%;
    }
    #main{
      width:100%;
      float:left;
    }
    #content{
      margin-left:300px;
      background-color:aqua;
    }
    

    左侧固定栏指定一个右侧的100%的负外边距,为整个屏幕的宽度,这就使得main的最左侧可以与屏幕最左侧对齐。 此时main的宽度是100%,因此需要为其子内容content指定一个左侧的外边距用于空出左侧栏的位置,即左侧栏的宽度300px 这种方法要相对复杂一些,但也很常用。

  • 绝对定位

    <div id = "aside">
    </div>
    <div id = "main">
    </div>
    
    #aside{
        position:absolute;
        left:0;
        width:200px;
    }
    #main{
        margin-left:200px;
    }
    
  • flex

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

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

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

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

<div id="container">
  <div id = "aside"></div>
  <div id = "main"></div>
</div>

#container{
    display:flex;
}
#aside{
    flex:0 0 200px;
}
#main{
    flex: 1 1;
}

水平/垂直居中

  • 单行文字/行内元素:display: table;text-align:center;line-height:行高
  • 多行文字:display:table;text-align:center;table-cell;vertical-align:middle
  • 块级元素:margin:0 auto;
  • 使用absolute与transform配合实现
position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)
  • 使用flex实现
display:flex;justify-content:middle;align-items:center

对BFC规范的理解?有两个盒子,margin重叠的问题,怎么解决

场景1:垂直外边距重叠问题
  • 父子元素 margin 重叠问题

    <style>
        * {
          padding: 0;
          margin: 0;
        }
        .father{
          background: pink;
          height: 100px;
          width: 400px;
        }
        .son {
          margin-top: 50px;
          background: #000;
          height: 50px;
        }
    </style>
    <body>
      <div class="father">
        <div class="son"></div>
      </div>
    </body>
    

    这个例子: 预期:元素son与元素father会有一个50px的上margin 实际:然而并没有出现,此时就出现了父子margin重叠的现象,解决办法有: 使父元素形成一个BFC:在father元素中添加 overflow: hidden/auto; 或 display:flow-root;

  • 兄弟元素垂直外边距折叠问题

    <style>
      .gege {
        background: red;
        width: 100px;
        height: 100px;
        margin: 40px;
      }
      .didi {
        background: green;
        width: 100px;
        height: 100px;
        margin: 40px;
      }
    </style>
    <body>
      <div class="gege">gege</div>
      <div class="didi">didi</div>
    </body>
    

    这个例子:

    预期:元素gege与元素didi加起来会有一个80px的margin 实际:两元素间的垂直边距只有40px 原因:相邻垂直边距margin产生合并,并以最大的那个作为边距 解决办法:给元素didi外面包一个元素wrap,并触发wrap的BFC

浮动元素
  • 浮动元素造成父元素高度坍塌问题 浮动元素会脱离文档流,如果父元素的高度是由原本的浮动元素撑起的话,元素一旦浮动,就会造成父元素的高度坍塌,因为浮动元素脱离文档流,不参加高度计算。

    <style>
      .father{
        border: 5px solid;
        width: 400px;
      }
      .son {
        background: pink;
        width: 400px;
        height: 50px;
      }
    </style>
    <body>
      <div class="father">
        <div class="son"></div>
      </div>
    </body>
    
    
  • 兄弟间,浮动元素与不浮动元素界限不清,重叠

    <style>
    .left {
      float: left;
      border: 1px solid ;
      width: 300px;
      height: 100px;
    }
    .right {
      border: 1px solid red;
      height: 200px;
    }
    </style>
    <body>
      <div class="left">left</div>
      <div class="right">right</div>
    </body>
    
如何触发BFC

一个块格式化上下文由以下之一创建:

  • 根元素或其它包含它的元素
  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • 具有overflow 且值不是 visible 的块元素,
  • display: flow-root
  • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。

除了兼容性问题,用display: flow-root来触发BFC最佳,不会产生任何副作用