【css】回想下经典的布局

看到这张图相信大多数人都很熟悉,这曾经是一种经典的布局方式,一道经典的面试题,一般形如"实现一个布局,左右固定宽度,中间自适应"。随着岁月的流转,时光的交替(颇有一种“天下风云出我辈,一入江湖岁月催”的感慨,哈哈),它一步步逐渐退出了历史舞台,不过在经典,总是有它经典的含义在里面,今天笔者就尝试站在自己认知范围内,重新诠释了下经典,实现的手段则是用了各种可能的方式实现这一经典布局:
1、基于FL FR的实现
.layout1 {
height: 100px;
overflow: hidden
}
.layout1 .l {
height: 100%;
width: 100px;
float: left;
}
.layout1 .m {
height: 100%;
margin: 0 200px 0 100px;
}
.layout1 .r {
height: 100%;
width: 200px;
float: right;
}
<div class='layout1'>
<div class='l'></div>
<div class='r'></div>
<div class='m'>layout1</div>
</div>
图中的第一个行就是基于此方式实现的,原理很简单,利用浮动元素脱离文档流的特性,左边的左浮动,右边的有浮动,简单粗暴。
2、圣杯布局
.layout2 {
height: 100px;
overflow: hidden;
padding: 0 200px 0 100px;
}
.layout2 .m {
float: left;
width: 100%;
height: 100%;
}
.layout2 .l {
float: left;
width: 100px;
margin-left: -100%;
position: relative;
left: -100px;
}
.layout2 .r {
width: 200px;
margin-left: -200px;
float: left;
position: relative;
right: -200px;
}
<div class='layout2'>
<div class='m'>layout2</div>
<div class='l'></div>
<div class='r'></div>
</div>
为了保证dom元素的尽快展示,而将最重要的元素放在最前解析,优化用户体验,使用负margin和相对定位调整左右元素位置,使用大容器的padding作为调整空间的hack,十分经典的手法;
3、双飞翼布局
.layout3 {
height: 100px;
overflow: hidden;
}
.layout3 .m-wrap {
width: 100%;
float: left;
height: 100%;
}
.layout3 .m {
margin: 0 200px 0 100px;
}
.layout3 .l {
float: left;
width: 100px;
margin-left: -100%;
}
.layout3 .r {
float: left;
width: 200px;
margin-left: -200px;
}
<div class='layout3'>
<div class='m-wrap'>
<div class='m'>layout3</div>
</div>
<div class='l'></div>
<div class='r'></div>
</div>
与之前的方式基本一致,唯一的不同是添加了一个标签,而没有依赖根容器做hack。
1、2、3三种实现都是基于BFC(Block Formatting Contexts)规则的,直译作“块级格式化上下文”,它会在页面上隔离出一个渲染区域,容器里的子元素并不会在布局上影响到外面的元素。如何产生BFC呢?它需要满足以下规则:
- float 除了none以外的值
- overflow 除了visible 以外的值(hidden,auto,scroll )
- display (table-cell,table-caption,inline-block, flex, inline-flex)
- position值为(absolute,fixed)
- fieldset元素
虽然概念可能有些陌生,其实我们在解决边界重叠(父子兄弟元素的margin重合)问题会经常通过触发BFC的方式来解决,另外,清除浮动也是这个原理,不过这些并不是本文的重点,那么让我们继续,看看其他的实现方式。
4、flex实现
.layout4 {
display: flex;
height: 100px;
}
.layout4 .l {
flex: 0 0 auto;
width: 100px;
}
.layout4 .m {
flex: 1 1 auto;
}
.layout4 .r {
flex: 0 0 auto;
width: 200px;
}
<div class='layout4'>
<div class='l'></div>
<div class='m'>layout4</div>
<div class='r'></div>
</div>
实现十分简单,利用伸缩盒模型的特性,只需要开启中间元素的flex-grow(为了保证缩小时的正常显示笔者还开启了flex-shrink)就能个很轻易的实现这种布局,不过为了美观,笔者并没有贴上兼容性的代码。当然,想实现之前那种优先渲染的方式flex也是支持的:
.layout4 {
display: flex;
height: 100px;
}
.layout4 .l {
flex: 0 0 auto;
width: 100px;
}
.layout4 .m {
order: 1;
flex: 1 1 auto;
}
.layout4 .r {
order: 2;
flex: 0 0 auto;
width: 200px;
}
<div class='layout4'>
<div class='m'>layout4</div>
<div class='l'></div>
<div class='r'></div>
</div>
原理也很简单,使用order属性就可以轻松实现了。
flex实现与之前不同,基于的是FFC(Flex Formatting Contexts)规则,即“自适应格式化上下文”。与BFC略显复杂的触发规则不同,只要有元素满足display为flex或inline-flex,则会应用这套规则。
想来所有方式似乎都已穷举?其实不然,还有去年刚出台的新规则css-grid可以一试,于是
5、css grid
.layout5 {
height: 100px;
display: grid;
grid-template-columns: 100px 1fr 200px;
}
<div class='layout5'>
<div class='l'></div>
<div class='m'>layout5</div>
<div class='r'></div>
</div>
可以看到,基于css grid的实现是最为便捷的,基于不需要操作grid item,只需要设置容器就可以轻易实现,不过由于是新事物,所以兼容性比较差。
对应grid也有其对应的规范叫作“GFC”(Grid layout Formatting Contexts),即“网格布局格式化上下文”,与flex类似,只需要设置disply为grid即可开启,但是请注意,它与我们通常理解的table(相信大家心里都有很多想关于table的吐槽)布局并不一致,正如上面例子中的,这种css grid布局提供了很多方便的属性给我们用于绘制网格。
除了以上BFC、FFC、GFC,常见的还有一个IFC(Inline Formatting Contexts),即“内联格式化上下文”,display为inline、inline-block、inline-table的元素,在IFC中,行内元素是一个接一个排列的,起点是容器的顶部,虽然横向的margin、padding、border得以保留,但是垂直方向上则会以不同的方式对齐,通常额可以设置vertical-align来控制其对齐方式。值得注意一点的是虽然行内元素内部可以形成一个BFC,而对外它则会形成IFC。
话说回来,这确实是一种经典的布局,几乎所有新的布局方式都是很友好的在支持它,从蛮荒时代的要使用各种hack手段来实现,到现代的轻而易举的实现,也足见其在css发展中的重要地位,现在想来也确实,css3之前的css更多的像是一种工具式的语言,它没有任何优雅的特性,了无生趣,而到了css3时代,无论从性能上的优化,工程上的提高,都是可圈可点的。
当然,类似经典的实现在css中还有很多,例如各种垂直居中的方法,与js更新换代的方式不同,旧的技术不断被新技术替换,而在css领域,这种返古现象却经常发生,当然也和浏览器厂商、各个平台,复杂的兼容性场景有关,但是其中蕴含的思想就像jQuery那种设计理念,却不会随着岁月的流逝而过时,反而在特定的时间上,更是弥足珍贵的。
【css】回想下经典的布局的更多相关文章
- 从零开始,搭建博客系统MVC5+EF6搭建框架(4)下,前后台布局实现、发布博客以及展示。
一.博客系统进度回顾 目前已经完成了,前台展示,以及后台发布的功能,最近都在做这个,其实我在国庆的时候就可以弄完的,但是每天自己弄,突然最后国庆2天,连电脑都不想碰,所以就一直拖着,上一篇写了前端实现 ...
- CSS样式表与格式布局
样式表 CSS(Cascading Style Sheets 层叠样式表),作用是美化HTML网页. 内联样式表: 例:<p style="font-size:10px;" ...
- CSS+JS下拉菜单和纯CSS下拉菜单
下拉菜单 (思路:先把二级定位到屏幕外,鼠标悬停重新定位回来:另一个就是ul浮动,li也浮动) 下拉菜单的一般思路就是把子导航嵌套在无序列表中,把列表定位到屏幕之外,当鼠标悬停在其父列表项上时,重新定 ...
- 如何使用Flexbox和CSS Grid,实现高效布局
CSS 浮动属性一直是网站上排列元素的主要方法之一,但是当实现复杂布局时,这种方法不总是那么理想.幸运的是,在现代网页设计时代,使用 Flexbox 和 CSS Grid 来对齐元素,变得相对容易起来 ...
- 精通CSS+DIV网页样式与布局--图片效果
提到图片效果,小伙伴们可能会想到美图秀秀,ps等,这些软件都是款非常不错的照片处理软件,包括常用的:黑白,增强,高斯,高对比,夜视,老照片和铅笔画等等.不管你是否是专业的 照片拍摄人员,我们都可以通过 ...
- 精通CSS+DIV网页样式与布局--初探CSS
CSS英文名Cascading Style Sheet,中文名字叫层叠样式表,是用于控制页面样式并允许将样式信息与网页内容分离的一种标记性语言,DIV+CSS是WEB设计标准,它是一种网页的布局方法. ...
- 如何使用 Flexbox 和 CSS Grid,实现高效布局
CSS 浮动属性一直是网站上排列元素的主要方法之一,但是当实现复杂布局时,这种方法不总是那么理想.幸运的是,在现代网页设计时代,使用 Flexbox 和 CSS Grid 来对齐元素,变得相对容易起来 ...
- 纯CSS实现移动端常见布局——高度和宽度挂钩的秘密
纯CSS实现移动端常见布局--高度和宽度挂钩的秘密 不踩坑不回头.之前我在一个项目中大量使用css3的calc计算属性.写代码的时候真心不要太爽啊-可是在项目上线之后,才让我崩溃了,原因非常easy, ...
- 87.CSS Flex 弹性盒模型布局教程(共用的css在48篇文章gird)
CSS Flex 弹性盒模型布局教程 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. flex布局就是给任何一个容器添加 dis ...
随机推荐
- 【BZOJ2527】Meteors(整体二分)
题意: Byteotian Interstellar Union有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会 ...
- 3.2 符号表之二叉查找树BST
一.插入和查找 1.二叉查找树(Binary Search Tree)是一棵二叉树,并且每个结点都含有一个Comparable的键,保证每个结点的键都大于其左子树中任意结点的键而小于其右子树的任意结点 ...
- ELK pipeline
https://www.felayman.com/articles/2017/11/24/1511527532643.html?utm_medium=hao.caibaojian.com&ut ...
- 51nod 1010 只包含因子2 3 5的数 && poj - 1338 Ugly Numbers(打表)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1010 http://poj.org/problem?id=1338 首先 ...
- UVA 1025_A Spy in the Metro
[题意](小紫书)一个人从站台1出发,乘车要在时刻T到达站台n,为使在站台等车时间最短,她可以选择乘坐两个方向的列车,并在客车停靠站的时候换车. [分析]每次停站下车时,她都有三种选择,1.原地不动 ...
- [bzoj5379]Tree_dfs序_线段树_倍增lca
Tree bzoj-5379 题目大意:给定一棵$n$节点的树.支持:换根.把节点$u$和$v$的$lca$的子树加.询问$u$的子树和. 注释:$1\le n,q\le 3\times 10^5$. ...
- 联想M7400打印机加粉墨了还是显示没有粉墨
联想M7400打印机加粉墨了还是显示没有粉墨?想必有很多的办公人士发现这个难题吧.其实很简单的! 先说下打印机的原理,打印机粉墨一边用的时候系统也在计数,当我们打印机加好墨后但打印机是不知道已经加好 ...
- how to read openstack code: Neutron architecture
今天这一章节非常重要.我们知道neutron是一个非常复杂的系统,由很多组件构成.研究这样一个复杂的系统,正确的顺序应该是现在宏观上对其整体结构有所了解,然后再由针对性的对其组件进行深入了解.本章要做 ...
- Rust 1.7.0 macro宏的复用 #[macro_use]的使用方法
Rust 1.7.0 中的宏使用范围包含三种情况: 第一种情况是宏定义在当前文件里.这个文件可能是 crate 默认的 module,也可能是随意的 module 模块. 另外一种情况是宏定义在当前 ...
- 《编程导论(Java)·3.1.2 方法》之 副作用
4. 副作用 在一些语言如Pascal中,子程序被分成两种:函数和过程.尽管Java没有强制性地要求将方法区分为命令和函数.然而这样的差别对于良好地设计程序有非常大的帮助[1]. 首先说明一个概念:副 ...