阅读 188

css中的三种布局

居中布局

image.png

固定高宽div垂直居中

display:flex

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
        display: flex;
        justify-content: center;
        align-items: center
      }

      .child {
        width: 100px;
        height: 100px;
        background-color: #61C1E8;
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
复制代码


position: absolute

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        position: relative;
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
      }

      .child {
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: #61C1E8;
        left: 50%;
        top: 50%;
        margin-top: -50px;
        margin-left: -50px;
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
复制代码


position & transform

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        position: relative;
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
      }

      .child {
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: #61C1E8;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
复制代码


position & margin

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        position: relative;
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
      }

      .child {
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: #61C1E8;
        top: 0;
        right: 0;
        left: 0;
        bottom: 0;
        margin: auto;
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
复制代码


table

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        display: table-cell;
        text-align: center;
        vertical-align: middle;
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
      }

      .child {
        display: inline-block;
        width: 100px;
        height: 100px;
        background-color: #61C1E8;
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child">erer</div>
    </div>
  </body>
</html>
复制代码


不定宽高水平垂直居中

image.png

display:flex

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        height: 200px;
        background-color: #f3f3f3;
        display: flex;
        justify-content: center;
        align-items: center
      }

      .child {
        background-color: #61C1E8;
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child">布局</div>
    </div>
  </body>
</html>
复制代码


position & transform

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        position: relative;
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
      }

      .child {
        position: absolute;
        background-color: #61C1E8;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
复制代码


table

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

      .parent {
        display: table-cell;
        text-align: center;
        vertical-align: middle;
        height: 200px;
        width: 200px;
        background-color: #f3f3f3;
      }

      .child {
        display: inline-block;
        background-color: #61C1E8;
      }
    </style>
  </head>

  <body>
    <div class="parent">
      <div class="child">erer</div>
    </div>
  </body>
</html>
复制代码


问题点

不定高当中:positon:absolute & position & margin为什么不行?

positon:absolute
absolute当中是通过margin来控制偏移量,margin的百分比是相对于包含块的,所以这里既没法通过具体数值计算,也没法通过百分比处理。

position & margin
这里需要看之前文章说的问题:
juejin.cn/post/694508…
juejin.cn/post/694508…

对于绝对定位的计算公式为:

// 计算公式
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block ​
// 如果这三个值都不是auto,margin-top和margin-bottom都是auto,则将这两个值设置为相等,然后计算上面的方程式
If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra constraint that the two margins get equal values.

image.png

不定高当中:positon & transform为什么行?

transform的百分比是相对当前元素的,所以可以处理。


圣杯 & 双飞翼布局

  • 两侧宽度固定,中间宽度自适应
  • 中间部分在DOM结构上优先,以便先行渲染
  • 允许三列中的任意一列成为最高列
  • 只需要使用一个额外的
    标签

image.png

圣杯布局

<!-- 例子来源 https://blog.csdn.net/weimob258616/article/details/110110818 -->
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

        * {
            border-width: 0;
        }

        body {
            min-width: 350px;
        }

        #header,
        #footer {
            height: 100px;
            background: #ccc;
        }

        #container {
            padding-left: 200px;
            padding-right: 150px;
            box-sizing:border-box;
            min-width:550px;
        }

        #center {
            float: left;
            width: 100%;
            background: #f96d9f;
        }

        #left {
            width: 200px;
            float: left;
            margin-left: -100%;
            position: relative;
            left: -200px;
            background: aqua;
        }

        #right {
            width: 150px;
            float: left;
            margin-right: -150px;
            background: yellowgreen;
        }

        #left,
        #right,
        #center {
            min-height: 100px;
        }

        /* 外围样式 */
        #header,
        #footer,
        #center,
        #left,
        #right {
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Source Code Pro';
            font-size: 20px;
        }
        #footer {
            clear: both;
        }

    </style>
  </head>

  <body>
    <div id='header'>#header</div>
    <div id='container'>
        <div id='center'>#center</div>
        <div id='left'>#left</div>
        <div id='right'>#right</div>
    </div>
    <div id='footer'>#footer</div>
  </body>
</html>
复制代码

image.png

container设置

#container {
  padding-left: 200px;
  padding-right: 150px;
  box-sizing:border-box;
  min-width:550px;
}
复制代码


优先放置center

#center {
	float: left;
	width: 100%;
	background: #f96d9f;
}
复制代码


left 代码

#left {
  width: 200px;
  float: left;
  margin-left: -100%;
  position: relative;
  left: -200px;
  background: aqua;
}
复制代码

这里的positon其实不用也可以。

#left {
  width: 200px;
  float: left;
  margin-left: calc(-100% - 200px);
  background: aqua;
}
复制代码


说明一下这里margin-left代码的运用

现在我们看到的container和center的宽度都是638px; 这时如果想要将left放在center同行最少需要设置margin-left: 200px;
image.png
这里为了说明的更形象,现在我们修改一下container的宽度,设置成638 - 40 = 598px;

#center {
  float: left;
  width: 598px;
  background: #f96d9f;
}

#left {
  width: 200px;
  float: left;
  background: aqua;
}
复制代码

此时,想要将left放在同一行,需要设置margin-left: 160px;
image.png

屏幕录制2021-09-10 下午6.59.20.2021-09-10 19_01_53.gif
以这个为例:假设想将left和center放在同一行,需要200px的距离,但是目前剩余的只有40px,所以同行放不下。就会将left放在了下一行。假设同行可以放下,我们可以发现我们缺少了160px的空间,我们可以通过margin-left,将left元素放不下的部分,左移过来部分内容,完成left的整个内容都可以放置在container中。这里的margin

margin-left相对哪里?

修改代码:将left和right的margin相关的代码去掉。

<!-- https://blog.csdn.net/weimob258616/article/details/110110818 -->
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

        * {
            border-width: 0;
        }

        body {
            min-width: 350px;
        }

        #header,
        #footer {
            height: 100px;
            background: #ccc;
        }

        #container {
            padding-left: 200px;
            padding-right: 150px;
            box-sizing:border-box;
            min-width:550px;
 
        }

        #center {
            float: left;
            width: 100%;
            background: #f96d9f;
        }

        #left {
            width: 200px;
            float: left;
            background: aqua;
        }

        #right {
            width: 150px;
            float: left;
            background: yellowgreen;
        }

        #left,
        #right,
        #center {
            min-height: 100px;
        }

        /* 外围样式 */
        #header,
        #footer,
        #center,
        #left,
        #right {
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Source Code Pro';
            font-size: 20px;
        }
        #footer {
            clear: both;
        }

    </style>
  </head>

  <body>
    <div id='header'>#header</div>
    <div id='container'>
        <div id='center'>#center</div>
        <div id='left'>#left</div>
        <div id='right'>#right</div>
         <div id='left'>#left</div>
        <div id='right'>#right</div>
    </div>
    <div id='footer'>#footer</div>
  </body>
</html>
复制代码

image.png
手动给最后一个right设置margin-left: -20px;
image.png
这可一看到当前margin-left相对的是当前排列行的包含块的内边距。这时候如果我们想将第二个right放置到container的左边。需要margin-left:calc(-100%- 50px - 50px);

image.png
首先明确,通过margin-left最多只能移动到上一浮动层,如上图,只能移动在第二层。第二这个margin-left的数值怎么计算出来的: header总长度为1000px。

第二层原先存在空白区域:100px;所以第二个right只需要在移动-50px就会到达第二层。
image.png

在原先的基础上继续移动100%;
image.png

因为right比left少50px,所以继续添加50px的距离就可以了。

right代码

#right {
  width: 150px;
  float: left;
  margin-right: -150px;
  background: yellowgreen;
}
复制代码

这里的代码如果参照left的代码也可以实现。但是这里用的是margin-right。

margin-right相对哪里?

继续使用上面的代码进行测试:
image.png

修改第二个right,添加margin-right: -50px;
image.png
第二层原先有空余空间100px,此时通过margin-right:-50px,相当于向右侧移动50px。假设原先第二层我们可以放置第二个right,但是会有50px的空间重叠,这在float当中不行。所以为了不占有前一个浮动元素的50px,我们通过margin-right向右侧移动50px。就好比,你说我占了50px,不让我在这一行,那我往右侧移动50px,不占用你的空间好了。


这里为什么用margin-right,不用margin-left

image.png
通过图中可以看到,margin-left移动到第二行的时候,右侧边界为包含块的内右边距。这种方法也不是不行,就是需要加相对定位在定位一下。

双飞翼布局

center添加float属性,inner使用margin。不需要使用relative。

<!-- https://blog.csdn.net/weimob258616/article/details/110110818 -->
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      html,
      body {
        margin:0;
        height: 100%;
      }

           * {
            border-width: 0;
        }

        body {
            min-width: 350px;
        }

        #header,
        #footer {
            height: 100px;
            background: #ccc;
        }

        #container {
            padding-left: 200px;
            padding-right: 150px;
            box-sizing: border-box;
            min-width: 550px;
        }

        #center {  
            float: left;
            width: 100%;
            background: #f96d9f;
        }
        #inner{
            margin-left:200px;
            margin-right:150px;
        }

        #left {
            width: 200px;
            float: left;
            margin-left: -100%;
            background: aqua;
        }

        #right {
            width: 150px;
            float: left;
            margin-left: -150px;
            background: yellowgreen;
        }

        #left,
        #right,
        #center {
            min-height: 100px;
        }

        /* 外围样式 */
        #header,
        #footer,
        #center,
        #inner,
        #left,
        #right {
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Source Code Pro';
            font-size: 20px;
        }

        #footer {
            clear: both;
        }


    </style>
  </head>

  <body>
    <div id='header'>#header</div>
    <div id='center'> 
        <div id='inner'>center</div>
    </div>
    <div id='left'>#left</div>
    <div id='right'>#right</div>
    <div id='footer'>#footer</div>
  </body>
</html>
复制代码

image.png

圣杯布局 & 双飞翼布局

圣杯布局:
image.png
双飞翼布局:
image.png

圣杯布局在DOM结构上显得更加直观和自然;
双飞翼布局省去了很多css,而且由于不用使用定位,可以获得比圣杯布局更小最小宽度;
说到这里需要注意一下 由于双飞翼布局会一直随着浏览器可视区域宽度减小从而不断挤压中间部分宽度。

自适应两栏布局

  • 每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      .left {
        width: 100px;
        height: 150px;
        float: left;
        background: gray;
      }

      .right {
        height: 300px;
        background: rgb(170, 54, 236);
        background: yellowgreen;
      }
    </style>
  </head>
  <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
  </body>
</html>

复制代码

image.png

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      .left {
        width: 100px;
        height: 150px;
        float: left;
        background: gray;
      }

      .right {
        overflow: hidden;
        height: 300px;
        background: rgb(170, 54, 236);
        background: yellowgreen;
      }
    </style>
  </head>
  <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
  </body>
</html>
复制代码


image.png


文章分类
前端
文章标签