CSS三栏布局的经典实现方法

2019-03-15 admin

三栏是CSS布局中常见的一种布局模式,顾名思义,就是将网页内容以三列的形式呈现。通常,三栏布局中的左栏和右栏是固定宽度的,中栏随着窗口宽度的变化而变化。本文探讨栏三栏的基本实现思路和经典方法,对其中涉及到的知识点进行梳理。

目的:实现一个左栏和右栏宽300px,中间栏宽度自适应的三栏布局

三栏布局示意图.png

基本实现思路

首先,常规思路,我们写出3个div的HTML和CSS,分别是leftColumn(左栏)、middleColumn(中栏)和rightColumn(右栏)。

HTML:

<body>    
    <div id="leftDiv">左栏</div>
    <div id="middleDiv">中栏</div>
    <div id="rightDiv">右栏</div>
</body>

CSS:

#leftDiv {
    height: 300px;  /*高度设为300像素,下同*/
    background-color: rgb(60,139,176);  /*设置背景颜色*/
}

#middleDiv {
    height: 300px;
    background-color: rgb(225,236,214);
}

#rightDiv {
    height: 300px;
    background-color: rgb(122,122,122);
}

此时,得到的网页如下图所示: 示意图.png

这是因为div的特性:默认宽度最大化(页面的100%),默认高度最小化(根据内容自适应)。

上面的CSS中,只指定栏高度height:300px,未指定宽度,所以每个div都以宽度width:100%填满所在行。

注意:此时若尝试指定每个div的宽度,例如给每个div的CSS添加语句:

width: 100px;

得到的页面如下图左图,而非右图。

示意图.png

这是因为div属于块级(block)元素,默认情况下,块级元素总是会另起一行。

为了使块级元素能位于同一行,最简单的方法是使用float属性。我们对每个div的CSS新增语句:

#leftDiv,#middleDiv,#rightDiv {
    float: left;  /*向左浮动*/
    height: 300px;  
}

使其向左浮动,得到的效果如下图所示:

示意图.png

可以看到,对CSS设置float:left属性后,三栏位于了同一行,宽度为其内容的适应宽度。此时,我们将左栏和右栏宽度设置为300px:

#leftDiv,#rightDiv {
    width: 300px;  /*设置宽度为300像素*/
    ... 
}
#middleDiv {
    ...
}

得到的效果如下图所示:

示意图.png

此时,中栏的宽度仍为其内容的适应宽度,我们为middleDiv添加如下语句:

width: calc(100% - 600px);  /*设置middleDiv宽度*/

calc()的作用为动态计算长度值,允许各种单位混合运算,运算符前后需有空格。

于是我们得到了最终效果。左栏和右栏各300px宽,中栏根据浏览器窗口大小进行动态调整。但需要注意的是,当浏览器窗口宽度小于600px时,中栏的宽度将小于0。为此,我们可以为浏览其设置最小调整宽度,避免页面混乱:

body {
    min-width: 700px;
}

至此,一个三栏布局就完成了。这种实现思路比较符合人的思维定势,但也存在一定的缺陷:浏览器加载和渲染页面遵循从上到下的原则,这种方法中,HTML的middleDiv(中栏)位列于leftDiv(左栏)之后,所以会在leftDiv之后加载,而middleDiv往往是页面的核心,需要优先加载展示给用户。

于是,我们思考将middleDiv放在HTML中的首位:

<body>    
    <div id="middleDiv">中栏</div>
    <div id="leftDiv">左栏</div>
    <div id="rightDiv">右栏</div>
</body>

CSS中,我们仍然设置middleDiv(中栏)的宽度为100% - 600px:


#middleDiv {
    width: calc(100% - 600px);
    ...
}

此时的界面如图所示:

示意图.png

可以看到,由于我们在HTML中将middleDiv(中栏)放在栏首位,所以浏览器窗口中,中栏显示在最前面。这时,我们需要为leftDiv(左栏)腾出空间,可以使用margin-left或padding-left。

margin和padding分别为盒模型的外边距和内边距,此处使用两者皆可,此处唯一的区别是padding会被底色填充而margin不会。因为background-color的填充区域为content+padding+border。

还有一点需要注意的是,padding值不能为负,对于需要取负值时,仅可使用margin。

为middleDiv(中栏)添加以下语句:


margin-left: 300px;

此时效果如下图所示:

示意图.png

可以看到,由于增加了300px的外边距,第一行的横向空间被middleDiv(中栏)和leftDiv(左栏)填满,rightDiv(右栏)被迫位列第二行。

此时,我们使用relative属性对左栏和右栏进行处理:

#leftDiv {
    position: relative;  /*相对定位*/
    left: calc(300px - 100%);  /*左移*/
    ...
}

#rightDiv {
    position: relative;
    top: -300px;  /*上移*/
    left: calc(100% - 300px);  /*右移*/
    ...
}

至此,我们在保证middleDiv(中栏)先行加载渲染的条件下,完成了三栏布局。基本思路为通过相对定位实现。

经典方法

CSS三栏布局的方法有很多种,其中最经典的方法莫过于圣杯布局和双飞翼布局。圣杯布局因形似圣杯而得名,即中栏为杯身,左右两栏为杯耳。双飞翼布局则是圣杯布局的一种改进,去掉了relative属性,并为主体部分增加了内容嵌套。

圣杯布局和双飞翼布局都需要在HTML中为div增加一层“容器(container)”。这个容器的目的主要是为了利用padding对中栏进行调整。

<body>  
    <div id="container">  
        <div id="middleDiv">中栏</div>
        <div id="leftDiv">左栏</div>
        <div id="rightDiv">右栏</div>
    </div>
</body>

首先,仍然设置float:left属性使div浮动,使其位于一行。

#leftDiv,#middleDiv,#rightDiv {
   float: left;
   ...
}

然后,将middleDiv(中栏)的宽度width设为100%:

#middleDiv {
    width: 100%;
    ...
}

得到如下图所示的布局:

示意图.png

此时,需要将leftDiv置于第一行左侧:

margin-left: -100%;  /* 左侧边界前移100% */

这样处理的结果是leftDiv(左栏)被置于第一行最左端,但会覆盖middleDiv(中栏)的部分内容。我们需要将中栏的内容从被覆盖的地方拉出来。一个简便的方法是对父容器container使用margin:

#container {
    margin: 0 300px 0 300px;
}

此处使用padding:0 300px 0 300px; 效果相同。

此时,leftDiv(左栏)也会受父容器的影响向右移动300px,仍然覆盖着middleDiv(中栏)的一部分,所以我们使用相对定位让其向左移动:

#leftDiv {
    position: relative;
    left: -300px;
    ...
}

此时的布局如下图所示:

示意图.png

对rightDiv(右栏)作类似处理:

#rightDiv {
    margin-left: -300px;  /*左侧边界前移300px*/
    position: relative;
    right: -300px;  /*右侧边界右移300px*/
    ...   
}

不要忘记为body设定最小宽度:

body {
    min-width: 800px;
}

至此完成。

可以看到,圣杯布局的实现思想是给div套上一个父容器,通过调整父容器的padding和div左右栏的相对定位来实现三栏布局。

双飞翼布局

双飞翼布局,源于淘宝UED,是圣杯布局的一种改进,或者说是另一种三栏实现思路。其创新点在于额外为middleDiv(中栏)增加一个子div存放其内容。

<body>  
    <div id="container">
        <div id="middleDiv">
            <div id="content">中栏</div>
        </div>
        <div id="leftDiv">左栏</div>
        <div id="rightDiv">右栏</div>
    </div>
</body>

仍然使用float属性来对div进行浮动:

#leftDiv,#middleDiv,#rightDiv {
   float: left;
   ...
}

与圣杯类似,设置middleDiv(中栏)宽度为100%,且将leftDiv(左栏)拉到最左侧,将rightDiv(右栏)作类似处理:

#middleDiv {
    width: 100%;
    ...
}

#leftDiv {
    margin-left: -100%;
}

#rightDiv {
    margin-left: -300px;
}

到这一步为止,双飞翼布局方法和圣杯CSS方法并不不同。

此时,由于双飞翼布局方法为middleDiv(中栏)单独添加了一个div存放其内容,所以对于中栏的处理,可以使用该div的margin属性:

#content {
    margin: 0 300px 0 300px;
}

此处使用padding:0 300px 0 300px; 效果相同。

同样,不要忘记为body设定最小宽度:

body {
    min-width: 800px;
}

至此完成。

可见,圣杯布局方法与双飞翼布局方法的区别在于圣杯布局采用相对位置属性(position:relative)来调整左栏和右栏位置,并使用margin/padding属性调整中栏。而双飞翼布局方法无需相对位置属性,而是采用为中栏内容创建div的方式,通过margin/padding来实现布局。

总结

本文探讨了三栏布局的CSS基本实现方法,首先以基本思路对三栏布局进行实现,发现不足,进行调整。文章第二部分阐述了流行的圣杯布局方法和双飞翼布局方法的细节和异同。除本文所述布局方法外,还存在绝对定位法、table布局法、网格布局法,以及十分方便的flex布局法等多种方法,各有利弊。

本文仅探讨了三栏布局的基本实现思路与方法,详细的实现过程希望能够帮助大家深入理解CSS。关于其他方法的讨论将在以后实际应用时进行总结。😊

[转载]原文链接:https://segmentfault.com/a/1190000018513296

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-57743.html

文章标题:CSS三栏布局的经典实现方法

相关文章
js性能优化 如何更快速加载你的JavaScript页面
确保代码尽量简洁 不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具,只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。 ...
2015-11-12
10个强大的纯CSS3动画案例分享
我们的网页外观主要由CSS控制,编写CSS代码可以任意改变我们的网页布局以及网页内容的样式。CSS3的出现,更是可以让网页增添了不少动画元素,让我们的网页变得更加生动有趣,并且更易于交互。本文分享了10个非常炫酷的CSS3动画案例,希望大家...
2015-11-16
Android中Okhttp3实现上传多张图片同时传递参数
之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片。 最近做项目,打算换个方法上传图片。 Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片。 Okhttp目前已经更新到Okhttp...
2017-03-17
JavaScript实现PC手机端和嵌入式滑动拼图验证码三种效果
PC和手机端网站滑动拼图验证码效果源码,同时包涵了弹出式Demo,使用ajax形式提交二次验证码所需的验证结果值,嵌入式Demo,使用表单形式提交二次验证所需的验证结果值,移动端手动实现弹出式Demo三种效果 首先要确认前端使用页面,比如...
2017-03-17
Vue.js组件tab实现选项卡切换
本文实例为大家分享了vue插件tab选项卡的具体代码,供大家参考,具体内容如下 效果图: 代码如下: &lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt; &lt;head&gt; ...
2017-03-13
从2014年的发展来展望JS的未来将会如何
&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
12个你未必知道的CSS小知识
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过。 1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员...
2015-11-12
v-charts | 饿了么团队开源的基于 Vue 和 ECharts 的图表工具
在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts的出现正是为了解决这个 痛点。基于Vue2.0和echarts封装的v-charts图表组件,只需要统一提供一种对前后端都友好的数据格式 设置简...
2018-05-24
ajax为什么令人惊异?ajax的优缺点
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHT...
2015-11-12
three.js实现围绕某物体旋转
话不多说,请看代码: 可以拖动右上角观察变化 &lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot; style=&quot;width: 100%; height:100%;&quot;&gt...
2017-02-17
回到顶部