css布局 - 工作中常见的两栏布局案例及分析
突然想到要整理这么一篇平时工作中相当常见但是我们又很忽视的布局的多种处理方法。临时就在我经常浏览的网站上抓的相对应的截图。(以后看到其他类型的我再补充)
既然截了图,咱们就直接看人家使用的布局方式,毕竟站在前辈肩膀上学习,我整理起来更轻松[哈哈]。(然后我再说一些我能想到的处理方式,帮助我们在工作中应对不同的布局结构时,选择性的去找最适合自己页面布局的方法)
说在前面:为了更好的看出来两列结构,截图我都做了蓝线和红线的框选。颜色较深的换成了黄线。总之就是为了让你一眼看出来,哪块和哪块。适合布局萌新,大佬们请无视我。
目录:
一、大结构上的导航栏和内容区域两栏布局
1、博客园为例
2、腾讯课堂个人中心页
3、慕课网个人中心页
4、github个人中心页
二、mini版的nav+cont结构
三、类似九宫格布局的两列结构
四、图文两列布局
1、左图右文字非垂直居中,
2、左图,右固定行数的文字,右侧文字和左边图片垂直居中。
3、左图右文字溢出隐藏
五、左右两端布局
六、icon + 文字
七、最后加一个面试(送分)题
一、大结构上的导航栏和内容区域两栏布局
首先我们从 大结构上 说起,因为我发现很多网站从整个首屏的大结构上都是这种两栏布局:
旁边是侧边栏导航,中间是大块内容区域。比如下图中我学习常用的几个网站
博客园个人中心页
腾讯课堂个人中心页面
腾讯课堂搜索界面
慕课网个人中心页面
github个人中心页面
四个网站截图往这里一贴,瞬间我觉得自己练成了《葵花宝典》
这布局结构不能说一模一样,但让我们前端看这就是一样啊!!
我们先来看看这四个网站的分别实现方式,说不定刚好就是四种实现方式呢啊哈哈哈哈~
1、博客园的:(比较正常的布局实现)
大结构一个main包裹。
核心框架结构如下:
核心css,我总结有以下几点:
-
左边内容、右边nav均设置左浮动
-
main 没有触发bfc,也没有使用伪元素清除浮动,而是使用了一个空标签清除浮动。但我们平时不用空标签,而是用伪类元素。具体下边css代码中体现。
-
右边nav栏固定宽度,并用margin/padding-left隔开和左边内容区域的距离
-
值的注意的是左边内容区域宽度设置为百分百,并使用margin-left负值使得自身向左位移,以给右边的nav腾出空间和左边并列一排。
-
因为mainCont向左移,超出了main区域。所以mainCont的儿子mainCont-inner使用margin-left再向右移动回来。
-
main的最外边元素cnblogs-body设置百分比宽度,并用margin实现水平居中。
具体css样式:
简陋效果:
特别说明:
mainCont父元素margin-left: -22em; 子元素margin-left:22em;到底咋实现的?
mainCont父元素向左偏移,把右侧nav的位置留了出来。刚好到-22em的时候,nav盛下了。但是他却牺牲了自己,超出了屏幕外边。
也就是这张图一开始的样式。左边粉色超出了浏览器屏幕。里边的文字都看不到了。
然后我们让子元素mainCont-inner再margin-left把超出的位置顶回来。实际上就是让其左边超出main的位置都设置为margin的区域。这样内容区域我们就能看到了。当然也可以设置padding-left:22em;不过那样如果你的mainCont-inner里有border或背景色(比如本例)还是会有超出看不到的问题。
2、腾讯课堂的:其结构和上一个刚好相反,nav在左侧,实现原理差不多。
首先,html也很语义化、相当标准:(学习了)
相信这么一张截图,你已经看穿了一切。
其核心结构如下:
样式关键点:
-
main父元素负责整体的水平居中。
-
nav负责左边元素的左浮动+可展示宽度220px
-
mainCont负责占据右边剩余位置,在这里具体做法是让其跟随左侧也形成浮动流。然后宽度100%,在浮动流的世界里,mainCont再用margin-left不断向左逼近,直到把nav占据的220px找补回来(margin-left:-220px)。自己心满意得的盖住了nav。还得用padding把nav让出来。
-
width:100%的元素使用了padding后的,宽度会增大。使用box-sizing把padding的宽度算到width中。
-
main伪元素after清楚浮动,解决父元素塌陷问题。
发现:如果把nav和mainCont的浮动都去掉,单纯用margin负值不起作用。
具体css样式
我的实现:
觉得左边这里浮动已经形成浮动流,他占据左边220像素的日子也付东流了。所以右边这里没必要再浮动了。可以直接使用padding-left把左边nav占据的220px空出来就行了。况且不用float就是块级元素,连width啥的都不要了。mainCont里边只用这一行代码就行:
简陋效果
心得:
html语义化
外边的那层结构用来布局,里边的结构用来承载样式。至于全局可继承的属性则可以放到body。
对于腾讯网课程这个样式,使用的左右固定宽度+左右浮动。不想整理了。感兴趣的自己打开这个页面查看吧。
3、慕课网的:左侧absolute定位脱离文档流,右侧自适应。
哈哈哈,看到这里我好开心,因为真的就像我开始说的,这仨网站的实现方式竟然真的都不一样。
左侧浮动:
右侧自适应,margin让出左侧范围。
html结构:
样式关键点:
-
main负责控制总宽度和水平居中。
-
左侧nav浮动
-
右侧内容区margin让出nav的宽度范围。自适应。
css样式:
简陋的效果
4、最后说Github,就比较简单粗暴了
百分比宽度+浮动。
html结构:
样式关键点分析:
-
main负责控制最大宽度和水平居中
-
main伪元素清除浮动
-
nav和cont都左浮动,并且使用百分比平分main的空间。
css结构:
简陋样式:
果然,四个网站四种样式。看来平时多看看别人的代码还是很能开拓思路的。
二、mini版的nav+cont结构
像不像上边大结构缩放0.5倍后的样式。左边内容区域(content),右边导航栏(nav)。
看git的代码,都是一个风格,几乎宽度百分比定天下。上边截图代码的同样是这个思路,具体实现如下。
html大致结构:
css关键思路:
-
main依旧应该负责总宽度和水平居中之类的布局,这里因为这一小块是嵌套在其他结构里的。就没有什么设置。
-
nav样式上在右边,但是结构上被放到了上边。进行右浮动。这也是一个知识点:设置右浮动的元素结构放前边比较好。具体原因我给忘了。
-
上边h2通栏因为内容在左侧,所以直接设置了100%宽度(也就是没设置宽度)
-
h2右侧的内容,利用浮动会形成文字环绕效果。让该内容直接右浮动就自动绕开了nav的空间。
-
内容区域设置了左浮动和自身视觉宽度上的width值(也就是设计稿上多宽这里设置了多宽)不过我的愚见,觉得这里可以不设置浮动。反而设置上百分比宽度是为了自适应很有必要。
css代码:
简陋效果:
惊悚的是,我居然没有找到他的清除浮动。在哪~
三、类似九宫格布局的两列结构
github的实现方法是flex的两端对齐:
关键点
-
父元素ol设置display:flex,并两端对齐。
完了
欢迎去看我整理的九宫格布局的实现方法吧。虽然我整理的是一排三列。但是两列也适用。
四、图文两列布局
1、左图右文字非垂直居中,以右侧内容撑开高度为自由高度。这种的我们省心,不用考虑垂直居中的问题。
关于这种左图右文字的两列布局,我上一篇已经写了很多种实现方法了,这里我们使用最简单的float实现:
<div class="wrapper"> <div class="img"></div> <div class="txt">我是右边内容示范区</div> </div>
以下,img和txt的第一行才是最核心的布局代码,其他都是美化用的样式代码。
.img{ float: left; width: 50px; height: 50px; border-radius: 50%; background: #eee; } .txt{ margin-left: 70px; border: 1px solid salmon; height: 150px; line-height: 150px; text-align: center; }
效果
2、左图,右固定行数的文字,右侧文字和左边图片垂直居中。这种实现方式就有限了。
同上,左图右多行文字垂直居中,(截图这里限制了两行)但实际开发中,我遇到过有的设计稿不限制行数还要有垂直居中的。
先说上边这种,其实还用1的那种,图片浮动右边设置margin-left的方法也可以。不过我们为了自适应的垂直居中,也就是假如我下边那行座右铭文字过多换行的话,整个右边红框区域还能垂直居中:
这里我们用flex实现:
示例效果:
如果是pc端考虑兼容性实在不想用伟大的css3实现,也可以这么做:
inline-block + vertical-align 屡试不爽
txt这里还有个宽度设置,截图时还没加入。。
不管是内容少:
还是内容多,都能驾驭:(兼容性还好,想兼容ie6、7先出去枪毙自己几分钟,然后再回来写inline-block的适配)
同样,下边这种,也是左边图(只不过是方形的),右边是多行文案。同时这里还设置了两行固定显示,更好说了:
3、左图右文字溢出隐藏
关键点是左边absolute“漂浮”起来(父元素需要relative限制一下)
然后右边自适应占据整个父元素的宽度,并用margin-left把左边图片遮挡的部位空出来。
奥对了,还有限制两行溢出显示小...,并且最底部是两端布局。
先说溢出小点点:
正常这么设置,就是一行超出显示小点点。像这样:
若要控制规定行数显示小点点:
这样就是第二行显示小点点了:
(授人以渔 - 可以百度搜索“多行文本溢出显示省略号点点点...”)
而至于两端布局见下边。
五、左右两端布局
下边画了三处:
这个嵌套结构你看出来了吗?事先没看源码前,我一打眼觉得是左边一大块,右边一小块的两端布局。但是细看发现原作把 logo单独摘了出来,logo右边的内容再分两列两端布局。如下画的红框里的绿和蓝:
这个就简单多了
左边和右边内容分别左右浮动:
flex两端布局
左边左浮动,右边宽度自适应并text-aligin:right;
文本两端布局
这种方式我想到了,但是代码没有实现。网上百度看别人实现了。有点尴尬。flag先立这里,有时间实现了补上吧。
六、icon + 文字
可以说是非常非常 常见的、几乎100%设计稿必备结构了。
1、看个淘宝的截图
这种一般都是文字不超过六个字,行数不超过一行。
其实都不能算是需要我们注意的正儿八经的两列结构了。但是我想说的是我们工作中,常常抓耳挠腮的不是他的实现。而是在垂直方向上要求icon和文字居中的适配问题:
a、垂直居中问题:
图和文字都是内联块元素,我一般都使用vertical-align实现,
b、垂直居中适配问题:
使用了vertical-align:middle,由于文字的下沉特性,还是觉得上下总是偏那么几像素不居中。前端看不出来,设计师走查都不给你过。要么只能margin微调,但常常情况是这个手机调好了,另一个手机又不行了。此消彼长,跟打地鼠似的。那我们怎么破?
那就是我工作中布局的一个小技巧,也是和张大神学的,vertical-align设置middle,而是设置具体的
像素值。至于设置多少,正值还是负值都看你自己的实际项目和效果上下调整即可。虽然是很小的一个点,但是工作中真的帮助我挡住了很多测试提的同类型bug。
2、github的处理和我平时方法略显不同:
用font字体+伪元素的处理方式
右边的Beiging又一个padding-left值把左边的icon让了出来。而左边的icon使用的字体,放在i标签的伪元素before上了。
对了,说到伪元素,问一个很基础但是很多人都混乱的问题:
请问什么是伪元素,什么是伪类?伪元素的权重高还是伪类的权重高?
这是一个前端老阿姨我亲身经历的题。虽然简单的不像话,但是我摔得也很不像话。哈哈哈。顺便提一下,让每一个看到的你心里回忆一下这个点。欢迎基础扎实的你的留言~
好了,终于把自己心血来潮列的目录添满了,我和我的电脑现在都反映很慢了。那就完了?当然不是,因为,还有,一个!!!
七、最后加一个面试(送分)题
题目:移动端的input输入框自适应。
类似效果如下:
解法一:flex:
html:
<div class="box"> <input type="text"> <button>按钮</button> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; display: flex; align-items: center; justify-content: space-between; } input{ flex: 1; } button{ width: 80px; }
解法二、float布局
html:
<div class="box"> <button>按钮</button> <div class="input-box"> <input type="text"> </div> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; /* display: flex; align-items: center; justify-content: space-between; */ } .input-box{ width: 100%; margin-left: 80px; } input{ width: 100%; /* flex: 1; */ } button{ width: 80px; float: left; }
解法三、float+margin负边距
html:
<div class="box"> <div class="input-box"> <input type="text"> </div> <button>按钮</button> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; /* display: flex; align-items: center; justify-content: space-between; */ } .input-box{ float: left; width: 100%; margin-right: -80px; } input{ width: 100%; border: 1px solid #eee; padding: 5px 90px 4px 10px; box-sizing: border-box; /* flex: 1; */ } button{ width: 80px; }
ps:
padding-right: 90是为了留出按钮的位置,不让按钮挡住文字。
解法四、定位布局
html:
<div class="box"> <div class="input-box"> <input type="text"> </div> <button>按钮</button> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; /* display: flex; align-items: center; justify-content: space-between; */ position: relative; height: 40px; } .input-box{ /* float: left; width: 100%; margin-right: -80px; */ position: absolute; left: 0; right: 80px; } input{ width: 100%; border: 1px solid #eee; /* padding: 5px 90px 4px 10px; */ padding: 5px 10px; box-sizing: border-box; /* flex: 1; */ } button{ width: 80px; position: absolute; right: 0; }