CSS 常见布局

六种布局方式:圣杯布局、双飞翼布局、Flex 布局、绝对定位布局、表格布局、网格布局。

1. 圣杯布局

圣杯布局是指布局从上到下分为 header、container、footer,然后 container 部分定为三栏布局。这种布局方式同样分为 header、container、footer。圣杯布局的缺陷在于 center 是在 container 的 padding 中的,因此宽度小的时候会出现混乱。

圣杯布局是挺常见的三栏式布局。两边定宽,中间自适应的三栏布局。

这个布局方式的关键是怎么样才能使得在伸缩浏览器窗口的时候让中间的子元素宽度改变。可以适应浏览器的宽度变化使用百分比设置宽度再合适不过,所以我们要将中间子元素的宽度设置为 100%,左边和右边的子元素设置为固定的宽度。

<div class="container">
    <div class="middle">测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试</div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>

这里我们要注意的是,中间栏要在放在文档流前面以优先渲染。

1.1 给出每个子元素的样式

然后我们写 CSS,我们现将其三个元素的宽度和高度设置好,然后都设置为 float:left:

.middle{width: 100%;background: paleturquoise;height: 200px;float: left;}
.left{background:red; width:200px; height:200px; float:left; font-size:40px;color: #fff;}
.right{background:blue;width:200px;height:200px; float:left; font-size:40px; color:#fff;}

图片说明

1.2 使子元素在同一行显示

我们可以看出,现在三个子元素是在一排显示的,因为我们给中间的子元素设置的宽度是 100%,并且中间的子元素在文档流的最前面,最先被渲染。

那么我们要使得三个元素在同一排显示。接下来我们要将 .left 和 .right 向上提。实际上我们是使用 margin-left 为 负值来实现的,我们将 .left 的 margin-left 设置为 -100%(负的中间子元素的宽度),这样,左边的元素就会被“提升”到上一层。

然后就是右边子元素了,只需要设置 margin-left 设置为负的自身的宽度。

.middle{width: 100%;background: paleturquoise;height: 200px;float: left;}
.left{background:red; width:200px; height:200px; float:left; font-size:40px;color: #fff;
margin-left:-100%;}
.right{background:blue;width:200px;height:200px; float:left; font-size:40px; color:#fff;
margin-left:-200px;}

图片说明

1.3 使得中间子元素不被遮盖

从上一张截图显示中显示中间的子元素被遮挡了,所以说我们要解决这个问题,要怎么解决呢?只要使得中间的子元素显示的宽度刚好为左边元素和右边元素显示中间的宽度就可以。同时我们还必须保证是使用的百分比的布局方式。

这样的话有一种方式可以即使中间的宽度减少,又可以使中间的宽度仍然使用 100%,那就是设置父元素的 padding 值,将父元素的 padding-left 设置为左边子元素的宽度,将父元素的 padding-right 设置为右边子元素的宽度。

.container{padding-left:200px; padding-right:200px;}

显示效果如下:

图片说明

1.4 将左边和右边的子元素向两边移动

最终的 CSS 代码如下:

.container{ padding: 0 200px; }
.middle{ width: 100%; background: paleturquoise; height: 200px; float: left; }
.left{background:red; width:200px; height:200px; float:left; font-size:40px;color: #fff;
margin-left:-100%; position:relative; left:-200px;}
.right{background:blue;width:200px;height:200px; float:left; font-size:40px; color:#fff;
margin-left:-200px; position:relative; right:-200px;}

图片说明

2. 双飞翼布局

其实双飞翼布局是为了解决圣杯布局的弊端提出的,上面的圣杯布局有一个问题,当你将浏览器宽度缩短到一定程度的时候,会使得中间子元素的宽度比左右子元素宽度小的时候,这时候布局就会出现问题。所以首先,这提示了我们在使用圣杯布局的时候一定要设置整个容器的最小宽度。

图片说明

2.1 双飞翼布局与圣杯布局的区别

圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部 float 浮动,在左右两栏加上负 margin 让其跟中间栏 div 并排,以形成三栏布局。

不同在于解决”中间栏div内容不被遮挡“问题的思路不一样:圣杯布局,为了中间 div 内容不被遮挡,将中间 div 设置了左右 padding-left 和 padding-right 后,将左右两个 div 用相对布局 position: relative 并分别配合 right 和 left属 性,以便左右两栏 div 移动后不遮挡中间 div。

双飞翼布局,为了中间 div 内容不被遮挡,直接在中间 div 内部创建子 div 用于放置内容,在该子 div 里用 margin-left 和 margin-right 为左右两栏 div 留出位置。

所以只是一个小小的改动

<div class="container">
    <div class="middle-container">
        <div class="middle">
            测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测
            试测试测试测试测试测试测试测试测试
        </div>
    </div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>
.middle-container{ width: 100%; background: paleturquoise; height: 200px; float: left; }
.middle{ margin-left: 200px; margin-right: 200px; }
.left{ background: palevioletred; width: 200px; height: 200px; float: left;
 font-size: 40px; color: #fff; margin-left:-100%; }
.right{ background: purple; width: 200px; height: 200px; float: left;
 font-size: 40px; color: #fff; margin-left:-200px; }

图片说明

这样,在我们将中间元素宽度调到比两边元素小的时候,也是可以正常显示,但是如果总宽度小于左边元素或者右边元素的时候,还是会有问题。

图片说明

3. Flex 布局

flex 的使用方法很简单,只需要将其 display 属性设置为 flex 就可以。注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。

4. 绝对定位布局

绝对定位布局是给 container 设置 position: relative 和 overflow: hidden,因为绝对定位的元素的参照物为第一个 postion 不为 static 的祖先元素。left 向左浮动,right 向右浮动。center 使用绝对定位,通过设置left 和right 并把两边撑开。center 设置 top: 0 和 bottom:0 使其高度撑开。

5. 表格布局

表格布局的好处是能使三栏的高度统一

6. 网格布局

网格布局可能是最强大的布局方式了,使用起来极其方便,但目前而言,兼容性并不好。网格布局,可以将页面分割成多个区域,或者用来定义内部元素的大小,位置,图层关系。

注:当元素设置了网格布局,column、float、clear、vertical-align属性无效。

如果没有设置 grid-template-columns,那么默认只有一列,宽度为父元素的 100%,例如

比如我们设置如下的 HTML,

<div class="grid-container">
    <div class="item item1">1</div>
    <div class="item item2">2</div>
    <div class="item item3">3</div>
    <div class="item item4">4</div>
    <div class="item item5">5</div>
    <div class="item item6">6</div>
</div>

在 CSS 中,我们不设置 grid-template-columns,只设置 grid-template-rows

.grid-container{ display: grid; grid-template-rows: 50px 80px 100px; background: pink; }
.item{ border:2px solid palegoldenrod; color:#fff; text-align:center; font-size:20px; }

图片说明