88

常见的布局类问题及面经

 6 years ago
source link: https://juejin.im/post/5a20141ef265da43085dd06e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

自己的地址
github.com/CodingMeUp/…

定期更新面经P5 P6面经、欢迎star

左边定宽、右边自适应(类似管理台)

  • 方案一 左边设置左浮动,右边宽度设置100% ()

      .left {
        float: left;
      }
      .right {
        width: 100%
      }复制代码
  • 方案二 左设置左浮动、右边也左浮动 但是使用calc去补宽度长度计算(方案一二没有完全分层)

      .left {
        float: left;
      }
      .right {
        width: calc(100vw-200px);
      }复制代码
    -【分析】
  1. 浮动。(注意:为了不影响其他元素,别忘了在父级上清除浮动)
  2. calc() = calc(四则运算) 用于在 css 中动态计算长度值,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
  3. vw: viewport width。1vw = viewport 宽度的 1%, 100vw = viewport width,
    同样的还有 vh: viewport height。1vw = viewport 高度的 1%, 100vh = viewport height。
    浏览器支持情况: 主流浏览器、IE10+
    vw 和 vh 会随着viewport 的变化而变化,因此十分适合于自适应场景来使用。
  • 方案三 父容器设置 display:flex;right部分设置 flex:1

      .contain {
        display: flex
      }
      .right {
        flex: 1
      }复制代码
  • 方案四 右边div套个包裹、并前置、左及包裹 双浮动左

     .contain{
       background: pink;
       float: left;
       width: 100%;
     }
    
     .left{
       height: 200px;
       width: 200px;
       float: left;
       margin-left: -100%;
       background: red;
     }
    
     .right {
       background: blue;
       height: 300px;
       margin-left: 200px;
     }复制代码
    <div class="contain">
     <div class="right">
       rrr
     </div>
    </div>
    <div class="left">lll </div>复制代码
  1. 首先设置左边部分和右边部分左浮动,并为自适应部分(Right)设置宽度100%。此时的效果是这样的:
  2. 设置左边部分左外边距为负100%,此时效果如下:
    但是右边部分的宽度仍然为100%,部分内容被 Left 所覆盖。
  3. 为 Right 部分添加左边距(即 Left 部分的宽度)
  • 关于左侧宽度固定,右侧宽度自适应两列布局的一种很常用的方法我相信大家都知道。就是利用左侧元素浮动,或者绝对定位的方式使其脱离常规文档流,让两个块级元素能够在同一行显示。然后右侧元素 margin-left 的值等于左侧元素宽度,这时右侧元素将紧挨着左侧元素,由于块元素的宽度会自动默认充满剩下的屏幕,所以就实现了右侧自适应的效果了。
  • 第二种方法,我利用的是创建一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。它可以通过以下任何一种方式来创建:
    float的值不为none
    position的值不为static或者relative
    display的值为 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一个
    overflow的值不为visible
      关于BFC,在w3c里是这样描述的:在BFC中,每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式化时,则为右边框紧挨)。即使在浮动里也是这样的(尽管一个包含块的边框会因为浮动而萎缩),除非这个包含块的内部创建了一个新的BFC。

    这样,当我们给右侧的元素单独创建一个BFC时,它将不会紧贴在包含块的左边框,而是紧贴在左元素的右边框。就像是箱子一个个排列 而不是叠上去

    <!DOCTYPE>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
      <link rel="stylesheet" href="test.css" type="text/css">
    </head>
    <style media="screen">
    .one {
    float: left;
    height: 100px;
    width: 300px;
    background-color: blue;
    }
    .two {
    overflow: auto;
    height: 200px;
    background-color: red;
    }
    </style>
    <body>
      <div class="one"></div>
      <div class="two">第二种方法</div>
    </body>
    </html>复制代码

左右定宽 中间自适应

  • position(绝对定位法) center的div需要放在最后面
    绝对定位法原理是将左右两边使用absolute定位,因为绝对定位使其脱离文档流,后面的center会自然流动到他们上面,然后使用margin属性,留出左右元素的宽度,既可以使中间元素自适应屏幕宽度。

    <div class='left'>left</div>
    <div class='right'>right</div>
    <div class='center'>center</div>
    .left,.right{
      position: absolute;
      width: 200px;
      height: 200px;
      background-color: #df8793;
      top:0;
    }
    .left{
      left:0px;
    }
    .right{
      right: 0px;
    }
    .center{
      margin: 0 210px;
      overflow: hidden;
      background-color: yellow;
      height: 200px;
    }复制代码
  • float:自身浮动法 center的div需要放在最后面
    自身浮动法的原理就是使用对左右使用分别使用float:left和float:right,float使左右两个元素脱离文档流,中间元素正常在正常文档流中,使用margin指定左右外边距对其进行一个定位。

    <div class='left'>left</div>
    <div class='right'>right</div>
    <div class='center'>center</div>
    .left,.right{
      width: 200px;
      height: 200px;
      background-color: #df8793;
    }
    .left{
      float: left;
    }
    .right{
      float: right;
    }
    .center{
      margin: 0 210px;
      overflow: hidden;
      background-color: yellow;
      height: 200px;
    }复制代码
  • 圣杯布局
    圣杯布局的原理是margin负值法。使用圣杯布局首先需要在center元素外部包含一个div,包含div需要设置float属性使其形成一个BFC,并设置宽度,并且这个宽度要和left块的margin负值进行配合

<div class='wrap'>
    <div class='center'>center</div>
</div>
<div class='left'>left</div>
<div class='right'>right</div>

.wrap{
    width: 100%;    // .left  margin-left 同步
    float: left;
    height: 200px;
    background-color: #238978;
}
.center{
    margin: 0 210px;
}
.left{
    float: left;
    margin-left: -100%; // .wrap width同步
    width: 200px;
    height: 200px;
    background-color: #eee;
}
.right{
    float: left;
    margin-left: -200px;
    width: 200px;
    height: 200px;
    background-color: #eee;
}复制代码
  • flex布局
    在外围包裹一层div,设置为display:flex;中间设置flex:1;但是盒模型默认紧紧挨着,可以使用margin控制外边距。
    <div class='wrap'>
      <div class='left'>left</div>
      <div class='center'>center</div>
      <div class='right'>right</div>
    </div>
    .wrap{
      display: flex;
    }
    .center{
      flex:1;
      margin: 0 10px;
      background-color: pink;
    }
    .left{
      width: 200px;
      height: 200px;
      background-color: #eee;
    }
    .right{
      width: 200px;
      height: 200px;
      background-color: #eee;
    }复制代码
  • 行内元素的居中 (父元素 text-align: center ) 这样子元素如果为inline-block 就会居中
  • 块状元素居中 (块状没法用text-align)
    • 宽度一定: 我们使用对该元素margin: auto来实现 或 margin: 20px auto 并且一定要设置宽度值width 一起使用
      • 宽度不定 :
        1) 加table标签设置 margin:0 auto 将需要进行居中的元素,用一个大表格将其围起来(而且这个表格只有这一个单元格哦),然后设置表格的属性(如第2条方法)居中就行。不过缺点是加了不少的无用标签,代码看起来比较臃肿。
        2) display: inline 设置text-align:center 居中的块级元素的display属性设置为inline,这样的目的是先把块级元素变为行内元素,可以在一行内显示,然后将这些元素的父级元素text-align设置为:center即可。大概原理就是:块级->行内->居中(参照第1条方法),不过缺点也很明显,块级元素的一些特点没有了,例如高度、宽度设置等。
        3) 运用float属性,主要的思想也就是将所需要居中的元素先float到左边,这样就能在一行内显示,然后将整个列表float到父元素左边,然后设置left来设置居中。怎么设置呢?先设置父元素:left:50%,这样整个父元素就往右便宜50%,然后设置列表:right:50%,这样列表的东西再往左走父元素的50%,这样就达到了居中的目的 基本思想也就是将父元素(容器)先往右偏移父容器宽度的50%,然后再将列表的元素向左相对偏移50%,就可以得到居中的效果。

1) 固定高度

  • line-height + height 但是 固定高度,无法实现两行文本的垂直居中对齐
  • absolute 固定高度 无法自适应内容 元素脱离文档流
    <div class="container">Hello World!</div>复制代码
    .container {
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -150px;
        margin-top: -150px;
        width: 300px;
        height: 300px;
        border: 1px solid red;
    }
    // 支持calc 
    .container {
        position: absolute;
        left: calc(50% - 150px);
        top: calc(50% - 150px);
        width: 300px;
        height: 300px;
        border: 1px solid red;
    }复制代码
  • 空标签+float:left
    <div class="space"></div>
    <div class="container">
    <div class="inner">
        hello world!
    </div>
    </div>复制代码
    .space {
        float: left;
        height: 50%;
        margin-top: -150px;
    }
    .container {
        clear: both;
        height: 300px;
        border: 1px solid red;
        position: relative;
    }复制代码

2) 高度自适应

  • CSS3里使用transform里的translate()的两个百分比参数 如果两个参数都为百分比值,此时会基于自身宽度和高定进行移动。此函数移动的机制同position:relative相似
    <div class="container">Hello World!</div>
    .container {
     position: absolute;
     top: 50%;
     left: 50%;
     transform: translate(-50%, -50%); // 自身宽度和高度的一半
     border: 1px solid red;
    }
    优点:无需定高度。高度随内容自适应。
    缺点:元素脱离文档流。如果需要居中的元素已经在高度上超过了视口,那它的顶部会被视口裁切掉。复制代码
  • 摆脱maigin 百分比靠父元素宽度的问题 50%加上translate负值并不能实现垂直居中布局。 改用
    vh来做

    <div class="container">Hello World!</div>
    
     .container {
         width: 300px;
         margin: 50vh auto 0;
         transform: translateY(-50%);
         border: 1px solid red;
     }复制代码
  • flex布局
    <div class="container">
     <div class="inner">
         <p>hello world!</p>
     </div>
    </div>复制代码
     .container {
         display: flex;
         height: 100vh;
     }
     .inner {
         margin: auto;
     }复制代码
    当我们使父元素display: flex时,margin: auto不仅可以水平居中,也能够实现垂直居中。这是因为auto外边距会平分水平或垂直方向上的额外空间。
    当然,也可以使用justify-content: center来定义弹性项目主轴的对齐方式,align-items: center来定义弹性项目侧轴的对齐方式。
     .container {
         display: flex;
         justify-content: center;
         align-items: center;
         height: 100vh;
     }复制代码
  • 模拟表格 父display:table 子display: table-cell vertical-align: middle

    <div class="container">
      <div class="inner">
          hello world!
      </div>
    </div>复制代码
      .container {
          display: table;         /* 让div以表格的形式渲染 */
          width: 100%;
          border: 1px solid red;
      }
    
      .inner {
          display: table-cell;    /* 让子元素以表格的单元格形式渲染 */
          text-align: center;
          vertical-align: middle;
      }复制代码

作者:渺渺惜雨怀_
链接:https://juejin.cn/post/6844903517505716232
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK