浅谈HTML几种布局方式

布局是前端比较基础但是也很重要的部分,过去传统的布局方案一般是通过基于盒子模型:
在这里插入图片描述
然后配合display、position或float等属性进行布局。这种布局方式使用和理解起来是相对简单,但是我认为布局更复杂的布局场景和维护起来会比较困难。
本文总结几种布局方式供参考:Flex 弹性布局、Grid网格布局和多列布局。没有适用所有场景的布局,只有合适的布局,在实际应用中多种布局方式灵活使用才能达到更好的效果。

1. Flex弹性布局

概念

Flex布局指弹性布局,是一种一维的布局方式,提供了对子元素的空间分布控制和对齐能力,为盒装模型提供了最大的灵活性。

任何一个容器都可以指定为flex布局

.box{
	display: flex;
}

行内flex容器

.box{
	display: inline-flex;
}

设置了flex布局后,元素的子元素的float、clear和vertical-align属性都将失效,使用了flex布局的元素即为flex容器,他的子元素自动成为容器成员。

flex容器存在两根主轴,主轴(main axis)和垂直交叉轴(cross axis)。
主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

容器属性

flex-direction

该属性决定主轴的方向,该属性取值为:

  • row(默认值):主轴为水平方向,起点在左端。
    在这里插入图片描述
  • row-reverse:主轴为水平方向,起点在右端。
    在这里插入图片描述
  • column:主轴为垂直方向,起点在上沿。
    在这里插入图片描述
  • column-reverse:主轴为垂直方向,起点在下沿。
    在这里插入图片描述
flex-wrap

该属性表示如果轴线排不下该如何换行。取值为:

  • nowrap 不换行,全部挤在一行
    在这里插入图片描述
  • wrap 换行,第一行在上面
    在这里插入图片描述
  • wrap-reverse 换行,第一行在下面
    在这里插入图片描述
flex-flow

该属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

.box{
	display: flex;
	flex-flow: row nowrap;
}
justify-content

该属性定义了项目在主轴上的对齐方式。取值为:

  • flex-start(默认值):左对齐
    在这里插入图片描述
  • flex-end:右对齐
    在这里插入图片描述
  • center: 居中
    在这里插入图片描述
  • space-between:两端对齐,项目之间的间隔都相等。
    在这里插入图片描述
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
    在这里插入图片描述
align-items

该属性定义项目在交叉轴上如何对齐。取值为:

  • flex-start:交叉轴的起点对齐。
    在这里插入图片描述
  • flex-end:交叉轴的终点对齐。
    在这里插入图片描述
  • center:交叉轴的中点对齐。
    在这里插入图片描述
  • baseline: 项目的第一行文字的基线对齐。
    在这里插入图片描述
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
    在这里插入图片描述
align-content

该属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。取值为:

  • flex-start:与交叉轴的起点对齐。
    在这里插入图片描述
  • flex-end:与交叉轴的终点对齐。
    在这里插入图片描述
  • center:与交叉轴的中点对齐。
    在这里插入图片描述
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
    在这里插入图片描述
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
    在这里插入图片描述
  • stretch(默认值):轴线占满整个交叉轴。
    在这里插入图片描述

容器子元素的属性

order

属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

flex-grow

属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
在这里插入图片描述

flex-shrink

属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

负值对该属性无效。
在这里插入图片描述

flex-basis

属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
在这里插入图片描述

flex

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

align-self

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

2. Grid布局

Grid网格布局,是一种很强大的布局方式,它将容器划分为一个一个网格,网格布局于Flex布局有一定相似性,都可以指定容器内元素的位置,但flex布局只能指定元素在轴线上的位置,而网格布局则是将容器划分位了,看起来flex布局像是一维布局,而网格布局为二维布局。

概念

  • 采用网格布局的元素,称为容器。网格布局容器内部的元素为子元素。
  • 容器内水平区域为行,垂直区域为列
  • 行和列交叉区域称之为单元格,n行m列会产生n*m个单元格
  • 划分网格的线,称为网格线

容器属性

网格布局是通过设置容器属性和子元素属性完成。

display: grid | inline-grid

容器可以设置为块级网格布局grid,也可以设置为行级网格布局inline-grid

注意:
当元素设置为网格布局的容器时,容器子元素的float、display:inline-block、display:table-cell、vertical-align等属性全部失效

grid-template-columns / grid-template-rows

这两个属性表示将网格容器划分行列,并定义行列宽高值。

.container{
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
}

在这里插入图片描述
同时这两个属性也可以使用百分比表示

  .container{
    display: grid;
    grid-template-columns: 25% 25% 25% 25%;
    grid-template-rows: 25% 25% 25% 25%;
  }

在这里插入图片描述

repeat() 方法

可以使用repeat() 函数简化重复值的配置

  .container{
    display: grid;
    grid-template-columns: repeat(4, 25%);
    grid-template-rows: repeat(4, 25%);
  }

repeat()函数参数第一个参数为数字,表示重复几次,第二个是重复的值。同时repeat()函数也可以重复多个值

.container{
  display: grid;
  grid-template-columns: repeat(2, 100px 200px);
  grid-template-rows: repeat(2, 100px 200px);
} 

在这里插入图片描述

auto-fill关键字

有时单元格的大小是固定的,但容器的大小是变化的, 如果希望一行能尽量多的容纳单元格,可以使用auto-fill关键字

.container{
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
}

在这里插入图片描述

fr关键字

fr关键字表示了容器内子元素的比例关系,例如1fr表示2fr的一半

.container{
  display: grid;
  grid-template-columns: 1fr 2fr;
}

在这里插入图片描述

fr关键字还可以配合绝对长度使用

.container{
  display: grid;
  grid-template-columns: 100px 1fr 1fr;
}

在这里插入图片描述

minmax()函数

minmax()函数产生一个长度范围,接收两个参数,最大值和最小值。

.container{
  display: grid;
  grid-template-columns: 200px 200px minmax(200px, 500px);
}

在这里插入图片描述

表示第三列子元素的宽度都会随着容器进行变化,范围是200-500px

auto关键字

auto关键字表示浏览器自动调整长度,与使用了minmax()函数的区别就是没有设定的最大最小值。

.container{
  display: grid;
  grid-template-columns: 200px auto 200px;
}

在这里插入图片描述

row-gap / column-gap / gap

这三个属性表示单元格之间的间距,row-gap是行间距,column-gap是列间距,gap是行列间距,相当于两个属性合并。

.container{
  display: grid;
  grid-template-columns: 200px 200px 200px;
  row-gap: 20px;
  column-gap: 20px;
}

等同于

.container{
  display: grid;
  grid-template-columns: 200px 200px 200px;
  gap: 20px 20px;
}

在这里插入图片描述

这三个属性原本是多列布局(Multi-column Layout)特有的属性,在新的标准中这三个属性同时被多列布局(Multi-column Layout)、弹性盒布局(Flexible Box)和网格布局(Grid Layout)中使用。
但在不支持这三个属性的浏览器上,还需要加上前缀grip-,例:grip-row-gap / grip-column-gap / grip-gap

grid-template-areas

该属性主要是将网格布局分区,一个区域可以由一个或多个单元格组成。

.container{
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-areas: 'a b c'
                       'd e f'
                       'g h i';
}

以上就是把布局分成九个区域。相同的区域名称表示合并分区:

.container{
  height: 500px;
  display: grid;
  grid-template-areas: "head head"
                       "nav  main"
                       "nav  foot"; /* 区域划分 当前为 三行 两列 */
  grid-template-rows: 80px 1fr 100px; /* 各区域 宽高设置 */
  grid-template-columns: 150px 1fr; 
}
.item{
  text-align: center;
  line-height: 100px;
  border: 1px solid white;
}
.block1 {
  grid-area: head;
  background: #f44336;
}
.block2 {
  grid-area: nav;
  background: #9c27b0;
}
.block3 {
  grid-area: main;
  background: #2196f3;
}
.block4 {
  grid-area: foot;
  background: #00bcd4;
}

<div class="container">
  <div class="item block1">子元素1</div>
  <div class="item block2">子元素2</div>
  <div class="item block3">子元素3</div>
  <div class="item block4">子元素4</div>
</div>

在这里插入图片描述

grid-auto-flow

划分网格后,子元素会按照顺序,自动放置在网格中,默认是先行后列。该属性由grid-auto-flow控制,默认值row,即表示先行后列排序。取值为Column表示先列后行。

.container{
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 200px 200px 200px;
  grid-auto-flow: column;
}

在这里插入图片描述

grid-auto-flow取值还可以是row dense和column dense。这两个值主要是在行列顺序上,尽量保证填充空白,例如:

.container{
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 200px 200px 200px;
  grid-auto-flow: row;
}
.item{
  text-align: center;
  line-height: 100px;
  border: 1px solid white;
}
.block1 {
  grid-column-start: 1;
  grid-column-end: 3;
  background: #f44336;
}
.block2 {
  grid-column-start: 1;
  grid-column-end: 3;
  background: #9c27b0;
}
.block3 {
  background: #2196f3;
}
.block4 {
  background: #00bcd4;
}
...

<div class="container">
  <div class="item block1">子元素1</div>
  <div class="item block2">子元素2</div>
  <div class="item block3">子元素3</div>
  <div class="item block4">子元素4</div>
  <div class="item block5">子元素5</div>
  <div class="item block6">子元素6</div>
  <div class="item block7">子元素7</div>
  <div class="item block8">子元素8</div>
  <div class="item block9">子元素9</div>
</div>

会出现下面情况:
在这里插入图片描述

由于子元素1和子元素2都占用了两个单元格,而当前容器布局只有三个单元格,所以元素2被挤到第二行,导致第一行出现了一个空白单元格。此时容器使用grid-auto-flow: row dense既可以尽量铺满每一行:

.container{
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 200px 200px 200px;
  grid-auto-flow: row dense;
}

在这里插入图片描述

justify-items / align-items / place-items

justify-items属性设置单元格内容即子元素的水平位置(左中右),align-items属性设置单元格内容的垂直位置(上中下),这两个属性取值为:

start: 单元格左(justify-items)/上(align-items)边缘对齐
end: 单元格右(justify-items)/下(align-items)边缘对齐
center: 居中
stretch: 拉伸充满单元格(默认)

而place-items则是前两个属性的组合属性,语法是place-items: <align-items> <justify-items>

例:justify-items: start;
在这里插入图片描述

justify-content / align-content / place-content

这三个属性是设置网格布局的整个内容曲在容器内的位置,justify-content设置水平位置,align-content设置垂直位置。place-content则为前两个属性的组合形式。取值为:

start:容器起始边框对齐
end:容器的终止边框对齐
center:容器内部居中
stretch:如果子元素的大小没有指定,则拉伸满整个容器(默认)
space-around:子元素之间的距离相等,两个子元素之间的距离比子元素距容器边框的距离大一倍
space-between: 子元素之间距离相等,但是子元素与容器边框没有距离
space-evenly: 子元素之间的距离相等,且子元素与容器边框的距离等于子元素之间的距离

例:justify-content: space-around;
在这里插入图片描述

grid-auto-columns / grid-auto-rows

有时子元素可能会设置在网格的外部,浏览器会生成多余的网格放置多余的元素。可以使用这两个元素设置多余的子元素的宽和高。

.container{
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-auto-rows: 50px;
}

在这里插入图片描述

子元素属性

grid-column-start / grid-column-end / grid-row-start / grid-row-end

子元素通过这四个属性可以指定位置,方法就是指定子元素的四个边框,分别在哪个网格线上。

grid-column-start:左边框所在的垂直网格线
grid-column-end:右边框所在的垂直网格线
grid-row-start:上边框所在的水平网格线
grid-row-end:下边框所在的水平网格线

例:

.block1 {
  grid-column-start: 2;
  background: #f44336;
}

在这里插入图片描述

这四个属性还可以使用span关键字,表示跨越几个单元格,例:

.block1 {
  grid-column-start: span 2;
  background: #f44336;
}

在这里插入图片描述

grid-area

该属性表示项目放置在哪一个区域下,名称的取值在容器定义了grid-template-areas属性中。

grid-area的取值还可以是grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写形式:

.block{
	grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}
justify-self / align-self / place-self

justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。

align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。

place-self则是前两个属性的合并简写形式

3. 多列布局(Multi-column Layout)

多列布局就像他的名字一样,是css3提供的一种多列组织内容的方式,就是类似报纸杂志类似的排榜方式。

多列局部不像Flex布局或网格布局那样,会直接更改子元素的显示属性。例如当容器被定义为网格容器后,该容器的子元素都会变成网格项(grid-item),而会被按规则放置到网格单元格中。而在多列布局中的子元素按照正常的布局放置,会按照顺序被排成多列,而这些子元素可以灵活的设置大小。

容器属性

column-width / column-count / columns

使用属性 colum-widthcolumn-count 定义的容器即为一个多列的容器。

其中column-count表示明确的将容器划分为几列的属性,而子元素会按顺序排列流入容器中。列宽是根据容器的可用宽度而变化。

.container {
  column-count: 3;
}

在这里插入图片描述

colum-width表示设置列的最小宽度,不代表实际宽度,而实际宽度还是以容器可用控件决定,浏览器会根据指定的宽度创建更多的列,而剩余的空件就会被现有的列平分。

.container {
  column-width: 300px;
}

在这里插入图片描述

columns相当于column-width 和 column-count两种的组合属性,但该属性也可设置单独的属性,例:

.container { columns: 2 }
.container { columns: 200px }
.container { columns: 2 200px }
column-rule / column-rule-color /column-rule-style / column-rule-width

这几个属性控制每一个列之间的分割线的样式。而column-rule 则是后三种属性的组合属性。例:

.container {
  columns: 3 300px;
  column-rule: 4px dotted rgb(79, 185, 227);
}

在这里插入图片描述

column-gap

column-gap属性控制的是每个列之间的间距,该值可取像素值或百分比,也可以取值为normal(默认),多列布局中normal表示为1em

column-span

column-span属性用来定义子元素是否跨列,该属性取值为 noneall,例:

.container {
  columns: 3 300px;
  column-rule: 4px dotted rgb(79, 185, 227);
}
.block1 {
  background: #f44336;
  column-span: all;
}

<div class="container">
  <h1>多列示例</h1>
  <div class="item block1">子元素1</div>
  <div class="item block2">子元素2</div>
  <div class="item block3">子元素3</div>
  <div class="item block4">子元素4</div>
</div>

在这里插入图片描述

  • 17
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值