CSS面试题加分方案

181 阅读5分钟

1. BFC到底是什么

BFC为 ‘块级格式化上下文’,简单理解为一个独立的空间,里面的元素不会影响到外界的布局。

1.触发BFC的条件

  • position:absolute / fixed
  • display:flex / inline-block / table-cell
  • overflow: hidden 2.BFC解决了什么问题
  • 高度塌陷
<div className="center">
  <div>
    <img src={img1} />
    <p>图片1</p>
  </div>
  <div>
    <img src={img2} />
    <p>图片2</p>
  </div>
  <div>
    <img src={img3} />
    <p>图片3</p>
  </div>
  <div>
    <img src={img4} />
    <p>图片4</p>
  </div>
</div>

.center {
    padding: 15px 17px 20px;
    div {
      width: 25%;
      float: left;
    }
    img {
      display: block;
      margin: 0 auto 10px;
      padding: 10px;
      border: 1px solid #00d39a;
      border-radius: 30px;
    }
    p {
      font-size: 12px;
      text-align: center;
      color: #535353;
    }
  }

效果:

image.png 如图 看到 父级元素center 的高度仅为 padding-top + padding-bottom 的高度 解决方案 只需要 父级元素 center 添加 overflow:hidden 即可

修改后的效果

image.png

  • 两栏布局
<div className="m">
  <div className="left">左侧导航区</div>
  <div className="right">右侧自适应取</div>
</div>

.m{
      overflow: hidden;
      .left{
        float: left;
        padding:20px;
        background:#00d39a;
      }
      .right{
        background:#fd7964;
        padding:30px;
      }
    }

效果:

image.png 如图 左侧浮动的导航区 覆盖右侧的自适应区 解决方案 .right 添加 display:flex; 修改后的效果

image.png

  • 边距重叠
<div className="m">
  <div className="left"></div>
  <div className="right"></div>
</div>
.m{
  overflow: hidden;
  .left{
    width:40px;
    height:40px;
    margin:10px;
    background:#00d39a;
  }
  .right{
    width:40px;
    height:40px;
    background:#fd7964;
    margin:10px;
  }
}

效果:

image.png

如图 每个盒子的边距为10px 所以上下两个盒子的间距因为为20px 但效果只有10px 明显的边距重叠了 解决方案 每个盒子渲染成独立的空间互不影响 .left 和 .right 都添加 float:left

2.垂直水平居中

垂直水平居中在面试中很常见,列举一些常用方案并说明应用场景,方案越多越加分哦 其中包括两类垂直水平居中问题 固定宽高/未知宽高

<div className="out">
    <div className="in"></div>
</div>

#方案1 负margin (固定宽高)
 .out{
    width: 60px;
    height:60px;
    background:#00d39a;
    position:relative;
  }
  .in{
    width:30px;
    height:30px;
    background:#fd7964;
    position:absolute;
    left: 50%;
    top:50%;
    margin-top:-15px;
    margin-left:-15px;
  }
  
 #方案2 transform (固定宽高/未知高度)
 .out{
    width: 60px;
    height:60px;
    background:#00d39a;
    position:relative;
  }
  .in{
    width:30px;
    height:30px;
    background:#fd7964;
    position:absolute;
    left: 50%;
    top:50%;
    transform: translate(-50%, -50%); 
  }
  
 #方案3 定位 + 上下左右0  (固定宽高/未知高度)
 .out{
        width: 60px;
        height:60px;
        background:#00d39a;
        position:relative;
      }
      .in{
        width:30px;
        height:30px;
        background:#fd7964;
        position:absolute;
        top: 0;
        right:0;
        bottom:0;
        left:0;
      }
      
 #方案4 flex (固定宽高/未知高度)
 .out{
    width: 60px;
    height:60px;
    background:#00d39a;
    display: flex;
    align-items: center; //垂直方向
    justify-content: center; //水平方向
  }
  .in{
    width:30px;
    height:30px;
    background:#fd7964;
  }
 
#方案5 table-cell 子元素需要设置为行内元素 (固定宽高/未知高度)
 .out{
    width: 60px;
    height:60px;
    background:#00d39a;
    display: table-cell;
    text-align: center;
    vertical-align: middle;
  }
  .in{
    width:30px;
    height:30px;
    background:#fd7964;
    display: inline-block;
  }
  

3. 关于flex布局

在flex布局之前 我们通常用 浮动 定位来做布局 比如上一题提到的垂直水平居中的问题 利用浮动和定位有多种解决方案,弊端是需要清楚的理解定位和脱离文档流概念非常不方便,flex 非常简便的处理了这些问题。

阮一峰的 Flex 布局教程 非常详细建议多看多理解

常问的面试题: flex:1 是什么意思?

flex布局中的子容器属性中有三个属性 flex-grow : 定义项目的放大比例 默认为0 即存在剩余空间也不放大 flex-shrink: 定义项目的缩小比例 默认为1 即空间不够项目缩小 flex-basis: 定义在分配多余空间前,项目占据的主轴空间 默认值为auto 即项目本来大小

还有一个flex属性 是以上三个属性的缩写 默认值为 0 1 auto 它有两个快捷值 auto (1 1 auto)放大缩小 none(0 0 auto)不放大不缩小

举个例子

 <div className="m">
    <div className="item">第一段落的内容比较长</div>
    <div className="item">第二段</div>
    <div className="item">第三段</div>
</div>
 .m{
  width:200px;
  margin:30px;
  display: flex;
  border: 1px solid #00d39a;
  .item{
    border: 1px solid #fd7964;
    flex:1;
  }

flex:1 如图所示为平均分配

image.png

flex:auto 根据内容分配

image.png

flex:none 为不放大不缩小 如图子元素内容超出父元素

image.png

flex:0 最小内容宽度

image.png

经典的圣杯布局 可以用flex很简单的实现

image.png

4.关于移动端1px问题

在实际开发中会有很多边框设置成1px 但效果总是看起来比1px粗一些,从而达不到UI预期 解决方案1:

<div className="m">
    <div className="item">第一段落的内容比较长</div>
    <div className="item">第二段</div>
    <div className="item">第三段</div>
</div>
.m{
  width:200px;
  margin:30px;
  display: flex;
  border: 1px solid transparent;
  border-image: linear-gradient(to bottom, transparent 50%, #00d39a 50%)  0 0 100%/1px  0;
  padding:10px;
  .item{
    border: 1px solid #fd7964;
    flex:1;
  }
}

image.png

如图 红色边框为正常1px 绿色边框为细1px

方案2:阴影 box-shadow: 0px 0.5px 0px 0px #00d39a;

方案3:相对定位 + 伪类

  position: relative;
      :before{
        content: '';
        position: absolute;
        left:0;           
        bottom: 0;
        width: 100%;
        height: 1px;
        background: #ee2c2c;
        transform: scaleY(0.5);
      }

以上整理了几个常见问题,后续还会补充。