CSS布局:float、position、flex、grid

html-css022

CSS布局:float、position、flex、grid,第1张

CSS是前端基础技能之一,而CSS最重要的功能就是网站布局。

CSS布局方式有很多,从远古时代的table(表格)布局-->float(浮动)布局-->position(定位)布局-->flex(弹性)布局-->grid(网格)布局(还未正式推出),下面咱们简单谈一谈各种布局的用法及其优缺点。

table布局就是将网站当做一个表单来做,这里不做展开,因为现在基本不这么用了。

float:浮动。float刚开始并不是为了用来网页布局,而是用来解决图文信息中图片与文本冲突的问题的。

如下图:

这种常见的图文效果,没有float之前是很难达到的。有了float之后只需要加一个float:left,轻松搞定。

‘咦,如果float可以处理图文的问题,那用来布局不也可以吗?’,后来有人用float试着用于网页布局,还真的可以。

网页中最常见的布局如下:

用float做

比table布局要方便不少,不过float随之而来的带来了 “浮动高度塌陷”的问题:

如果浮动元素的父元素没有设定高度,当其子元素浮动后,父元素就因为内部没有子元素撑起从而高度变为0;

引申:网页元素一般分为 普通流,浮动流,定位流。其中普通流和浮动流在一个层级上,定位流>浮动流>普通流。

之后为了解决这个问题搞出来一系列清除“浮动高度塌陷”的策略方法,非常麻烦。

position:定位;顾名思义,就是确定位置。position同样可以用做网页布局。

同样的效果

不过position需要计算每一个元素的位置,而且这个位置是定死的,略显繁琐和笨重。实际上position我平常只用来定位一些小的标签之类的东西。position优点在于不像float那样会影响其他元素。

关键点:子绝父相。需要定位的元素用absolute绝对定位,其父元素用 relative相对定位。还有fixed固定定位,他是以html为父元素的定位。

flex:弹性;弹性布局很好的解决了float和position的问题,非常好用。

使用方法:

在父元素使用 display:flex确定弹性作用的范围。

然后

justify-content:center(space-around,space-between等);水平方向布局;

align-items:center(flex-start,flex-end等)垂直方向布局;

不过flex不兼容IE8及以下的浏览器。

大部分情况下flex布局已经能满足需要,不过flex只能用作一维布局,也就是说,flex一次只能作用于一条线。如果想要进行二维布局,必须翻转坐标二次弹性,这样会显得不够优雅,这时候grid(网格)布局就发展起来了。

grid布局用法和flex相似,但是作用于二维布局。

先在父元素使用 display:grid确定网格作用范围;

然后

grid-template-columns: 40px 50px auto 50px 40px(行)

grid-template-rows: 25% 100px auto(列)

等等属性,这里只简单介绍,大家了解有这个东西就行。

在现实工作用,以flex为主,position辅助已经足够应对所有问题。

现代浏览器 |  IE浏览器

display: grid| display: -ms-grid  //加前缀-ms

grid-template-columns: repeat(12, 1fr)  |  -ms-grid-columns: (1fr)[12]//重复函数

grid-template-columns: 1fr repeat(3, 20px 1fr)|  -ms-grid-columns: 1fr (20px 1fr)[3]

grid-template-columns:100px   minmax(200px,500px)   1fr| -ms-grid-columns:100px   minmax(200px,500px)   1fr//minmax函数 

当值为auto时不起作用。minmax(50px,auto)

单元格占行:现代浏览器

grid-column:1/2

grid-row:1/2

单元格占行:IE浏览器

-ms-grid-column:1

-ms-grid-column-span:1

-ms-grid-row:1

-ms-grid-row-span:1

https://css-tricks.com/css-grid-in-ie-debunking-common-ie-grid-misconceptions/

关键词:隐式轨道 / 隐式网格 / 自动布局算法

隐式网格是指当网格项目确认在显式网格之外时所创建的网格,简单来说,当没有足够空间或显式网格轨道来分配网格项目时,此时剩下网格会自动创建隐式网格。

当设置网格容器的网格模板 grid-template 属性并指定固定数量轨道时创建出来的就是典型的显式网格,而在实际的HTML中存在网格项目多余既定数量,此时这些多余的网格是之前未声明定义的,因此网格容器会通过添加隐式网格线来生成网格轨道,在将这些多余的网格分配到其中,这些多余的就是所谓“隐式网格”。

隐式网格轨道的尺寸由 grid-auto-rows 和 grid-auto-columns 属性来确定,使用 grid-auto-flow 属性来控制隐式网格自身主动定位(auto-placement),这三个属性都需要在网格容器上设置。

如何产生隐式网格呢?

例如:定义一个网格容器,网格间距为1px,默认存放两列等宽网格项目,创建具有隐式网格的布局。

问题是虽然在网格容器中设置了2列等宽的位置用来容器网格项目,也就是说只定义了1行轨道,但实际上网格容器中具有4个网格项目,问题来了,第3和第4个网格容器是如何处理的呢?

第3和第4会自动创建下一个轨道,即隐藏网格。创建出来的隐式网格的方向若没有设置则默认为 row 即 grid-auto-flow:row 。

这里我们首先将这4个网格分成两种类型显式网格和隐式网格,其中可以发现第1和第2个为显式网格,第3和第4网格为隐式网格。换句话说第1行为显式行轨道,第2行为隐式行轨道。

grid-auto-flow 属性用来设置自动布局算法,用于精确指定在网格中被自动布局的网格项是如何排列的,也就是说指定自动放置的网格项是如何流入网格中的,因此也被称之为“网格自动流”。

稠密堆积算法 VS 稀疏算法

dense 使用稠密堆积算法,若【后面】出现小元素则算法会尝试填充网格中【前面】留下的空白,如此这样会填补上稍大元素所留下的空白,但同时可能导致原有出现次序被打乱。

若省略 dense 则会使用稀疏算法,即在网格中布局元素时,布局算法只会向前移动,永远不会倒回来去填补空白,这样做以保证所有自动布局元素是[按照次序]出现的,即使可能会留下被后面元素填充的空白。

例如:改变隐式网格默认方向 row 为 column ,此时隐式网格行高 grid-auto-rows 将会失效。

网格容器的 grid-auto-rows 属性可以用来定义隐式网格中行轨道的大小

这里 grid-template-rows:70px 设置的是显式轨道的行高, grid-auto-rows:140px 则设置的是隐式轨道的行高。

设置隐式网格列宽,首先需使用 grid-auto-flow:column 自动创建隐式网格流方向为列,然后在使用 grid-auto-columns:1fr 设置隐式网格的列宽,这里使用 1fr 做等分处理。

例如:排序与布局

第1个网格项横跨左2格,后4格按 grid-auto-flow:column 的流向排列。