两栏布局

两栏布局

左边固定,右边自适应的两栏布局

首先创建基本的HTML布局和最基本的样式。

左边固定宽度,高度不固定

<div class="wrapper"id="wrapper">

<div class="left"></div>

<div class="right"></div>

</div>

基本的样式是,两个盒子相距20px, 左侧盒子宽120px,右侧盒子宽度自适应。基本的CSS样式如下:

.wrapper{padding:15px20px;border:1pxdashed#ff6c60;}

.left{width:120px;border:5pxsolid#ddd;}

.right{margin-left:20px;border:5pxsolid#ddd;}

1.双inline-block方案

.wrapper-inline-block { box-sizing: content-box; font-size: 0; // 消除空格的影响}

.wrapper-inline-block .left,.wrapper-inline-block .right { display: inline-block; vertical-align: top; // 顶端对齐 font-size: 14px; box-sizing: border-box;}

.wrapper-inline-block .right { width: calc(100% - 140px);}

这种方法是通过width: calc(100% - 140px)来动态计算右侧盒子的宽度。需要知道右侧盒子距离左边的距离,以及左侧盒子具体的宽度(content+padding+border),以此计算父容器宽度的100%需要减去的数值。同时,还需要知道右侧盒子的宽度是否包含border的宽度。

在这里,为了简单的计算右侧盒子准确的宽度,设置了子元素的box-sizing:border-box;以及父元素的box-sizing: content-box;。

同时,作为两个inline-block的盒子,必须设置vertical-align来使其顶端对齐。

另外,为了准确地应用计算出来的宽度,需要消除div之间的空格,需要通过设置父容器的font-size: 0;,或者用注释消除html中的空格等方法。

缺点:

需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing

需要消除空格字符的影响

需要设置vertical-align: top满足顶端对齐

2.双float方案

.wrapper-double-float { overflow: auto; // 清除浮动 box-sizing: content-box;}

.wrapper-double-float .left,.wrapper-double-float .right { float: left; box-sizing: border-box;}

.wrapper-double-float .right { width: calc(100% - 140px);}

缺点:

需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing。

父元素需要清除浮动。

3.float+margin-left方案

.wrapper-float { overflow: hidden; // 清除浮动}

.wrapper-float .left { float: left;}

.wrapper-float .right { margin-left: 150px;}

上面两种方案都是利用了CSS的calc()函数来计算宽度值。下面两种方案则是利用了block级别的元素盒子的宽度具有填满父容器,并随着父容器的宽度自适应流动特性

但是block级别的元素都是独占一行的,所以要想办法让两个block排列到一起。

我们知道,block级别的元素会认为浮动的元素不存在,但是inline级别的元素能识别到浮动的元素。这样,block级别的元素就可以和浮动的元素同处一行了。

为了让右侧盒子和左侧盒子保持距离,需要为左侧盒子留出足够的距离。这个距离的大小为左侧盒子的宽度以及两个盒子之间的距离之和。然后将该值设置为右侧盒子的margin-left。

缺点:

需要清除浮动

需要计算右侧盒子的margin-left

4.使用absolute+margin-left方法

.wrapper-absolute .left { position: absolute;}

.wrapper-absolute .right { margin-left: 150px;}

缺点:

使用了绝对定位,若是用在某个div中,需要更改父容器的position。

没有清除浮动的方法,若左侧盒子高于右侧盒子,就会超出父容器的高度。因此只能通过设置父容器的min-height来放置这种情况。

5.使用float+BFC方法

.wrapper-float-bfc { overflow: auto;}

.wrapper-float-bfc .left { float: left; margin-right: 20px;}

.wrapper-float-bfc .right { margin-left: 0; overflow: auto;}

这个方案同样是利用了左侧浮动,但是右侧盒子通过overflow: auto;形成了BFC,因此右侧盒子不会与浮动的元素重叠

这种情况下,只需要为左侧的浮动盒子设置margin-right,就可以实现两个盒子的距离了。而右侧盒子是block级别的,所以宽度能实现自适应。

缺点:

父元素需要清除浮动

6.flex方案

.wrapper-flex { display: flex; align-items: flex-start;}

.wrapper-flex .left { flex: 0 0 auto;}

.wrapper-flex .right { flex: 1 1 auto;}

flex可以说是最好的方案了,代码少,使用简单。有朝一日,大家都改用现代浏览器,就可以使用了。

需要注意的是,flex容器的一个默认属性值:align-items: stretch;。这个属性导致了列等高的效果。

为了让两个盒子高度自动,需要设置:align-items: flex-start;

7.grid方案

.wrapper-grid { display: grid; grid-template-columns: 120px 1fr; align-items: start;}

.wrapper-grid .left,.wrapper-grid .right { box-sizing: border-box;}

.wrapper-grid .left { grid-column: 1;}

.wrapper-grid .right { grid-column: 2;}

grid布局也有列等高的默认效果。需要设置: align-items: start;。

grid布局还有一个值得注意的小地方和flex不同:在使用margin-left的时候,grid布局默认是box-sizing设置的盒宽度之间的位置。而flex则是使用两个div的border或者padding外侧之间的距离。

极限情况

最后可以再看一下在父容器极限小的情况下,不同方案的表现。主要分成四种情况:

动态计算宽度的情况

两种方案: 双inline-block方案和双float方案。宽度极限小时,右侧的div宽度会非常小,由于遵循流动布局,所以右侧div会移动到下一行。

动态计算右侧margin-left的情况

两种方案: float+margin-left方案和absolute+margin-left方案。宽度极限小时,由于右侧的div忽略了文档流中左侧div的存在,所以其依旧会存在于这一行,并被隐藏。

float+BFC方案的情况

这种情况下,由于BFC与float的特殊关系,右侧div在宽度减小到最小后,也会掉落到下一行。

flex和grid的情况

这种情况下,默认两种布局方式都不会放不下的div移动到下一行。不过 flex布局可以通过 flex-flow: wrap;来设置多余的div移动到下一行。 grid布局暂不支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容