参考链接: 常见5大布局

  1. 单列布局
  2. 两列自适应布局
  3. 圣飞布局和双飞翼布局
  4. 伪等高布局
  5. 粘连布局

一、单列布局

图片说明

常见的单列布局有两种:

header,content和footer等宽的单列布局。
header和footer等宽,content略窄的单列布局。

实现:

  1. 等宽的单列布局

2.不等宽的单列布局

<div class="header"> 
        <div class="nav"></div> 
       </div> 
       <div class="content"></div> 
       <div class="footer"></div> 
.header{ 
 margin:0 auto; 
 max-width: 960px; 
 height:100px; 
  background-color: chocolate;
} 
.nav{ 
 margin: 0 auto; 
 max-width: 800px; 
  background-color: coral;
 height: 50px; 
} 
.content{ 
 margin: 0 auto; 
 max-width: 800px; 
 height: 400px; 
 background-color: cyan;

} 
.footer{ 
 margin: 0 auto; 
 max-width: 960px; 
 height: 100px; 
 background-color:darkorange;

} 

二、两列自适应布局

指一列由内容撑开,另一列撑满剩余宽度的布局方式

首先看不是自适应的布局:只需要一个浮动,一个设置margin即可

<!-- 普通布局只需要浮动加普通元素的margin就可以实现 -->
    <div class="left"></div>
    <div class="right"> </div>
.left{
    float:left;
    width: 100px;
    height: 1000px;
    background-color: darkorchid;
}
.right{
    margin-left:100px;
    height: 1000px;
    background-color: darkred;
}

1、float+overflow:hidden

BFC

    <!-- 两栏的自适应布局 float+overflow:hidden-->
    <!-- 通过overflow触发BFC,而BFC不会重叠浮动元素 -->
    <div class="parent">
        <div class="left">
            <p>left</p>
        </div>
        <div class="right">
            <p>right</p>
            <p>right</p>
        </div>

    </div>
.parent{
        overflow:hidden;
        background-color: darksalmon;
        width: 100px;
        height: 100px;
    }
    .left{
        float:left;
        background-color: darkslateblue;


    }
    .right{
        background-color: darkturquoise;
        overflow:hidden;
    }

图片说明
当删去left中的内容:
图片说明

三、三栏布局

特征:中间列自适应宽度,旁边两侧固定宽度。
注意:content要在最后面,不然浮动的元素会在其下面

1、浮动方法

<body>
    <div class="right">right</div>
    <div class="left">left</div>
    <div class="content">content</div>
</body>
<style>
.right{
    float:right;
    width: 100px;
    height: 100px;
    background-color: aqua;
}
.left{
    float:left;
    width: 100px;
    height: 100px;
    background-color: antiquewhite;
}

.content{
    margin-left: 100px;
    margin-right: 100px;
    background-color: black;
}

图片说明

2、定位方法

<body>

    <div class="left">left</div>
    <div class="content">content</div>
     <div class="right">right</div>
</body>
<style>
.right{
    position:absolute;
    right:0;
    width: 100px;
    height: 100px;
    background-color: aqua;
}
.left{
    position:absolute;
    left:0;
    width: 100px;
    height: 100px;
    background-color: antiquewhite;
}

.content{
    position:absolute;
    left:100px;
    right: 100px;
    background-color: black;
}

效果一致,但这种方法使用的有效性较差,因为整个容器都脱离了文档流。

3.flexbox布局

有关flex详情请看: css之flex属性(弹性布局)

<body>
   <div class="main">
    <div class="left">left</div>
    <div class="content">content</div>
     <div class="right">right</div>
    </div>
</body>
<style>
.main{
        display: flex; 
}
.right{

    width: 100px;
    height: 100px;
    background-color: aqua;
}
.left{

    width: 100px;
    height: 100px;
    background-color: antiquewhite;
}

.content{
    flex:1;
    background-color: blue;
}

flex布局的缺点是从ie10开始支持

4.表格布局

table是一种常见的布局方式,他可以将整个页面按照表格的方式设置为多行多列,但是书写table标签比较麻烦,所以可以用display:table的方法。子元素为display:table-cell

<body>
   <div class="main">
    <div class="left">left</div>
    <div class="content">content</div>
     <div class="right">right</div>
    </div>
</body>
<style>
.main{
        display:table; 
        width: 100%;
}
.main div{
    display: table-cell; 
}
.right{

    width: 100px;
    height: 100px;
    background-color: aqua;
}
.left{

    width: 100px;
    height: 100px;
    background-color: antiquewhite;
}

.content{

    background-color: blue;
}

图片说明
优点:兼容性好,内容溢出时会自动撑开父元素
缺点:

  • 无法设置栏边距
  • 对seo不友好
  • 当其中一个单元高度超过的时候,两侧的单元格也是会一起变高的

5.网格布局

网格布局将网页划分为一个个网格,可以任意组合不同的网格,做出各种各样的布局
将属性display值设为grid或inline-grid就创建了一个网格容器。
gird提供了 gird-template-columns、grid-template-rows属性让我们设置行和列的高、宽

<body>
    <div class="main">
        <div class="left">left</div>
        <div class="content">content</div>
        <div class="right">right</div>
    </div>
</body>
<style>
    .main {
        display: grid;
        width: 100%;
        grid-template-columns: 100px auto 100px;
        grid-template-rows: 150px;
    }

    .right {

        background-color: aqua;
    }

    .left {

        background-color: antiquewhite;
    }

    .content {
        background-color: blue;
    }
</style>

兼容性不好。
与表格不同的地方:网格布局没有内容结构

3、特殊的三栏结构:圣杯布局

参考链接:https://www.jianshu.com/p/81ef7e7094e8
同样也是两边固定宽度,中间自适应,唯一区别是 dom 结构必须是先写中间列部分,这样实现中间列可以优先加载。

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

标签

实现步骤:

1、三个部分都设定为左浮动,否则左右两边内容上不去,就不可能与中间列同一行。然后设置 center 的宽度为 100%(实现中间列内容自适应),此时,left 和 right 部分会跳到下一行
2、通过设置 margin-left 为负值让 left 和 right 部分回到与 center 部分同一行
3、通过设置父容器的 padding-left 和 padding-right,让左右两边留出间隙。
4、通过设置相对定位,让 left 和 right 部分移动到两边

Q:为什么设置margin—left为自身宽度可以回到第一行?

A:因为一开始元素在第二行的原因是第一行的宽度被center完全占满。但当left元素设置margin-left为负的自身宽度,此时这个元素的宽度为0,第一行可以容纳宽度为0的元素,所以回到了第一行。

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

<body>
    <!-- 首先定义出整个布局的dom结构 -->
    <div id="header"></div>
    <div id="container">
        <!-- center要定义在最前面 -->
        <div id="center" class="column"></div>
        <div id="left" class="column"></div>
        <div id="right" class="column"></div>
    </div>
    <div id="footer"></div>
</body>
<style>
    #container{
        padding-left:100px;
        padding-right:100px;
    }
    #container .column{
        float:left;
    }
    #left {
        background-color: chartreuse;
        width: 100px;
        height: 100px;
        /* 使其回到第一行 */
        margin-left:-100%;
        /* 定位元素让他到预留的位置 */
        position:relative;
        right:100px;
    }

    #right {
         margin-right:-100%;
        background-color: coral;
        width: 100px;
        height: 100px;
    }

    #center {
        height: 100px;
        width: 100%;
        background-color: cyan;
    }
    #footer{
        clear:both;
    }
</style>

双飞翼布局

<body>
    <body>
        <div id="header"></div>
        <div id="container" class="column">
          <div id="center"></div>
        </div>
        <div id="left" class="column"></div>
        <div id="right" class="column"></div>
        <div id="footer"></div>
      <body>
</body>
<style>
    body{
        max-width:500px;
    }
#container {
  width: 100%;
}

.column {
  float: left;
}

#center {
  margin-left: 200px;
  margin-right: 150px;
  height: 100px;
  background-color: darkorange;
}

#left {
  width: 200px; 
  height: 100px;
  background-color: darkgreen;
  margin-left:-100%;
}

#right {
  width: 150px;
  height: 100px; 
  background-color: darkmagenta;
  margin-left:-150px;

}

#footer {
  clear: both;
}

② 实现步骤(前两步与圣杯布局一样)

三个部分都设定为左浮动,然后设置 center 的宽度为 100%,此时,left 和 right 部分会跳到下一行;
通过设置 margin-left 为负值让 left 和 right 部分回到与 center 部分同一行;
center 部分增加一个内层 div,并设 margin: 0 200px;
③ 缺点

多加一层 dom 树节点,增加渲染树生成的计算量。

④ 圣杯布局和双飞翼布局实现方式对比:

两种布局方式都是把主列放在文档流最前面,使主列优先加载。
两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。
两种布局方式的不同之处在于如何处理中间主列的位置: 圣杯布局是利用父容器的左、右内边距+两个从列相对定位; 双飞翼布局是把主列嵌套在一个新的父级块中利用主列的左、右外边距进行布局调整

粘连布局

<body>
    <div class="wrap">
        <div class="main">
            main<br />
            main<br />
        </div>
    </div>
    <div class="footer"></div>
</body>
<style>
html,body{
    height: 100%;
    margin:0;

}
.wrap{
    width: 100%;
    min-height: 100%;
}
/* 让出一部分区域,防止内容被遮盖 */
.main{
    padding-bottom:30px;
}
.footer{
    width: 100%;
    height: 30px;
    background-color: darkorchid;
    /*main已经为100%,此时设置负值使其上移*/
    margin-top:-30px;
}
</style>

---------补充margin为负值时--------

参考链接:https://blog.csdn.net/weixin_38912024/article/details/88837111

①元素本身没有宽度,会增加元素宽度

<body>
    <div class="parent">
        <div class="child">
            设置margin-left为负值
        </div>
    </div>
</body>
<style>
.parent{
    width: 100px;
    height: 100px;
    background-color: cyan;
    margin-left:20px;
}
.child{
    background-color: darkgreen;
    margin-left:-20px;
}
</style>

图片说明

②元素本身有宽度,会产生位移

<body>
    <div class="parent">
        <div class="child">
            设置margin-left为负值
        </div>
    </div>
</body>
<style>
.parent{
    width: 100px;
    height: 100px;
    background-color: cyan;
    margin-left:20px;
}
.child{
    width: 50px;
    background-color: darkgreen;
    margin-left:-20px;
}
</style>

图片说明

margin-top为负值,不管是否设置高度,都不会增加高度,而是会产生向上的位移

margin-bottom为负值的时候不会位移,而是会减少自身供css读取的高度.

图片说明
图片说明

对文档流的影响

元素如果使用了margin-left为负,则自身会向左偏移。且在其后面的元素会补位,后面的行内元素会津贴在此元素的后面。即如果不脱离文档流不使用float的话,负margin元素是不会破坏页面的文档流。
如果使用负margin上移一个元素,所有跟随的元素都会被上移

对绝对定位影响

对于绝对定位元素,负margin会基于其绝对定位目标再偏移