CSS的定位与布局

本文详细介绍了CSS的定位属性,包括static、relative、fixed、absolute和sticky,以及它们的应用场景。此外,还深入探讨了CSS布局,如flexbox和grid布局,详细阐述了相关属性的用法,并给出了实例,如骰子布局、表格表头锁定、圣杯布局等,展示了CSS布局的强大和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CSS的定位与布局

定位属性:position

元素是利用top、bottom、left、right属性进行定位的,要想使用这些属性,就需要先设置position值。position 属性规定了应用于元素定位方法的类型。

static

staticposition的默认属性值,使用static定位的属性将不受top、bottom、left、right的影响。文档将会按照源码的顺序决定每个元素的位置,每个块级元素占据自己的区块,元素与元素之间不会重叠。

relative、fixed、absolute

这三个属性值都是相对于某个基点的定位,不同之处在于基点的选择。三者都不会对其他元素的位置产生影响,因此元素之间可能会产生重叠。

relative

relative定位的基点是元素的默认位置,需要搭配top、bottom、left、right四个属性值一起使用,用于指定偏移的方向和距离。

fixed

fixed定位的基点为浏览器窗口,意味着即使滚动页面,元素也始终处于同一位置,可以搭配top、bottom、left、right

absolute

absolute定位的基点为父元素。该属性有一个限制条件:定位基点不可以是static定位,否则定位基点将变成网页的根元素(html)。absolute定位也需要搭配top、bottom、left、right一起使用。
注:absolute定位的元素会被“正常页面流”忽略,也就是说在“正常页面流”中,该元素占据空间为零,周边元素会不受影响。

sticky

sticky会产生动态效果,像是relativefixed的结合。该属性生效的前提是必须与top、bottom、left、right搭配,不能省略,否则与relative定位一样,不会产生动态固定的效果。
具体规则为:当页面滚动,父元素部分不可见时,只要与sticky元素的距离达到生效门槛,relative定位就会自动切换为fixed定位;等父元素完全不可见时,fixed定位会自动切换为relative定位。

div.sticky {
  position: -webkit-sticky;/*safari浏览器*/
  position: sticky;
  top: 10px;
}

上方代码块中,页面向下滚动,div.sticky父元素部分不可见时,一旦与div.sticky间距离小于10px,div.sticky就将变为fixed定位,保持与视口顶部10px的距离;页面继续向下滚动,父元素完全不可见时,恢复为relative定位。

应用
  1. “动态固定”效果
    上述例子即为动态固定效果的实现
  2. 堆叠效果
<div><img src="pic1.jpg"></div>
<div><img src="pic2.jpg"></div>
<div><img src="pic3.jpg"></div>
div {
  position: sticky;
  top: 0;
}

效果如下图所示,可以发现当滚轮滑动时,后面的图片会重叠在前一张图片上。
在这里插入图片描述 滚轮开始滑动

  1. 表格的表头锁定
th {
  position: sticky;
  top: 0;
}

效果如下:
在这里插入图片描述滚轮开始滑动

布局属性:display

传统的布局是利用display+position+float实现的,这种布局方式对于特殊的布局非常不方便,例如垂直居中。接下来介绍两种强大的布局方案。

flex(弹性布局)

flex是 flexible box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 flex 布局。设为 flex 布局以后,子元素的floatclearvertical-align属性将失效。
在这里插入图片描述
上图为一个flex容器,容器中存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

容器属性
flex-direction

该属性决定了主轴的方向(项目的排列方向),属性值有4个:

属性值效果
row(默认值)主轴为水平方向,起点在左端
row-reverse主轴为水平方向,起点在右端
column主轴为垂直方向,起点在上沿
column-reverse主轴为垂直方向,起点在下沿
.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

在这里插入图片描述

flex-wrap

默认情况下,项目会排列在一条线上。flex-wrap属性定义了 如果一条轴线排不下换行的方式

属性值效果
nowrap(默认值)不换行
wrap换行,第一行在上方
wrap-reverse换行,第一行在下方
.box {
  flex-wrap: nowrap | wrap | wrap-reverse;
}

nowrap
wrap
wrap-reverse

flex-flow

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

.box {
  flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content

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

属性值效果
flex-start(默认值)左对齐
flex-end右对齐
center居中
space-between两端对齐,项目之间的间隔都相等
space-around每个项目两侧的间隔相等,因此项目之间的间隔比项目与边框的间隔大一倍
.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

justify-content

align-items

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

属性值效果
flex-start交叉轴的起点对齐
flex-end交叉轴的终点对齐
center交叉轴的中点对齐
baseline项目的第一行文字的基线对齐
stretch(默认值)如果项目未设置高度或设为auto,将占满整个容器的高度
.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

align-items

align-content

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

属性值效果
flex-start与交叉轴的起点对齐
flex-end与交叉轴的终点对齐
center与交叉轴的中点对齐
space-between与交叉轴两端对齐,轴线之间的间隔平均分布
space-around每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍
stretch(默认值)轴线占满整个交叉轴
.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

在这里插入图片描述

项目的属性
order

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

.item {
  order: <integer>;
}

order

flex-grow

该属性属性定义了项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: <number>; /*默认为0*/
}

flex-grow
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

flex-shrink

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

.item {
  flex-shrink: <number>; /* 默认为1 */
}

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

flex-basis

该属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间。

.item {
  flex-basis: <length> | auto; /* 默认为auto */
}
flex

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

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

align-self

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

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

align-self

实例
骰子的布局

默认的Html模板为:

<div class="box">
  <span class="item"></span>
</div>
只有左上一个点时,flex布局默认即为首行左对齐,所以只需要一行代码

在这里插入图片描述

.box {
  display: flex;
}
设置项目的对齐方式,就可以实现居中对齐和右对齐

在这里插入图片描述

.box {
  display: flex;
  justify-content: center;
}
设置交叉轴对齐方式,可以垂直移动主轴。

在这里插入图片描述

.box {
  display: flex;
  align-items: center;
}

在这里插入图片描述

.box {
  display: flex;
  justify-content: space-between;
}

在这里插入图片描述

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

在这里插入图片描述

.box {
  display: flex;
}
.item:nth-child(2) {
  align-self: center;
}

在这里插入图片描述

.box {
  display: flex;
  justify-content: space-between;
}
.item:nth-child(2) {
  align-self: flex-end;
}

在这里插入图片描述

.box {
  display: flex;
}
.item:nth-child(2) {
  align-self: center;
}
.item:nth-child(3) {
  align-self: flex-end;
}

在这里插入图片描述

<div class="box">
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
</div>
.box {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}
.column {
  flex-basis: 100%;
  display: flex;
  justify-content: space-between;
}
网格布局
  1. 基本网格布局
    最简单的网格布局,就是平均分布。在容器里面平均分配空间,跟上面的骰子布局很像,但是需要设置项目的自动缩放。
  2. 百分比布局
    某个网格的宽度为固定的百分比,其余网格平均分配剩余的空间。
    在这里插入图片描述
<div class="Grid">
  <div class="Grid-cell u-1of4">...</div>
  <div class="Grid-cell">...</div>
  <div class="Grid-cell u-1of3">...</div>
</div>
.Grid {
  display: flex;
}
.Grid-cell {
  flex: 1;
}
.Grid-cell.u-full {
  flex: 0 0 100%;
}
.Grid-cell.u-1of2 {
  flex: 0 0 50%;
}
.Grid-cell.u-1of3 {
  flex: 0 0 33.3333%;
}
.Grid-cell.u-1of4 {
  flex: 0 0 25%;
}
  1. 圣杯布局
    是一种最常见的网站布局。页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer)。其中躯干又水平分成三栏,从左到右为:导航、主栏、副栏。
    在这里插入图片描述
<body class="HolyGrail">
  <header>...</header>
  <div class="HolyGrail-body">
    <main class="HolyGrail-content">...</main>
    <nav class="HolyGrail-nav">...</nav>
    <aside class="HolyGrail-ads">...</aside>
  </div>
  <footer>...</footer>
</body>
.HolyGrail {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}
header,
footer {
  flex: 1;
}
.HolyGrail-body {
  display: flex;
  flex: 1;
}
.HolyGrail-content {
  flex: 1;
}
.HolyGrail-nav, .HolyGrail-ads {
  /* 两个边栏的宽度设为12em */
  flex: 0 0 12em;
}
.HolyGrail-nav {
  /* 导航放到最左边 */
  order: -1;
}
  1. 悬挂式布局
    在主栏的左侧或右侧添加一个图片栏。
    在这里插入图片描述
<div class="Media">
  <img class="Media-figure" src="" alt="">
  <p class="Media-body">...</p>
</div>
.Media {
  display: flex;
  align-items: flex-start;
}
.Media-figure {
  margin-right: 1em;
}
.Media-body {
  flex: 1;
}
  1. 固定的底栏
    有时,页面内容太少,无法占满一屏的高度,底栏就会抬高到页面的中间。这时可以采用Flex布局,让底栏总是出现在页面的底部。
    在这里插入图片描述
<body class="Site">
  <header>...</header>
  <main class="Site-content">...</main>
  <footer>...</footer>
</body>
.Site {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}
.Site-content {
  flex: 1;
}

grid(网格布局)

网格布局(Grid)是最强大的 CSS 布局方案。它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。
grid 布局与 flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。
flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。grid 布局远比 flex 布局强大。

基本概念

采用网格布局的区域,称为"容器"(container)。容器内部采用网格定位的子元素,称为"项目"(item)。项目只能是容器的顶层子元素,不包含项目的子元素,grid 布局只对项目生效。

容器属性

设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等设置都将失效。

display

display: grid指定一个容器采用网格布局

div {
  display: grid;
}

在这里插入图片描述
默认情况下,容器元素都是块级元素,但也可以设成行内元素。

div {
  display: inline-grid;
}

在这里插入图片描述

grid-template-columns ,grid-template-rows

容器指定了网格布局以后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。

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

在这里插入图片描述
除了使用绝对单位,也可以使用百分比。

  • repeat()
    重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。repeat()接受两个参数,第一个参数是重复的次数(上例是3),第二个参数是所要重复的值。
.container {
  display: grid;
  grid-template-columns: repeat(3, 33.33%);
  grid-template-rows: repeat(3, 33.33%);
}
repeat()重复某种模式也是可以的。
grid-template-columns: repeat(2, 100px 20px 80px);

在这里插入图片描述

  • auto-fill关键字
    有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。
.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}
表示每列宽度100px,然后自动填充,直到容器不能放置更多的列。

在这里插入图片描述

  • fr关键字
    为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为1fr2fr,就表示后者是前者的两倍。
.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

在这里插入图片描述
fr可以与绝对长度的单位结合使用,这时会非常方便。

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

在这里插入图片描述

  • minmax()
    minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
minmax(100px, 1fr)表示列宽不小于100px,不大于1fr。
  • auto 关键字
    auto关键字表示由浏览器自己决定长度。
grid-template-columns: 100px auto 100px;
上面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width,且这个值大于最大宽度。
  • 网格线的名称
    grid-template-columns属性和grid-template-rows属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。
.container {
  display: grid;
  grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
  grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
上面代码指定网格布局为3行 x 3列,因此有4根垂直网格线和4根水平网格线。方括号里面依次是这八根线的名字。
网格布局允许同一根线有多个名字,比如[fifth-line row-5]。
  • 布局实例
    grid-template-columns属性对于网页布局非常有用。两栏式布局只需要一行代码。
.wrapper {
  display: grid;
  grid-template-columns: 70% 30%;
}

上面代码将左边栏设为70%,右边栏设为30%。
传统的十二网格布局,写起来也很容易。

grid-template-columns: repeat(12, 1fr);
row-gap 、column-gap 、gap

row-gap属性设置行与行的间隔(行间距),column-gap属性设置列与列的间隔(列间距)。

.container {
  row-gap: 20px;
  column-gap: 20px;
}

gap属性是column-gaprow-gap的合并简写形式,语法如下。

gap: <row-gap> <column-gap>;

如果gap省略了第二个值,浏览器认为第二个值等于第一个值。

grid-template-areas

网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。

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

上面代码先划分出9个单元格,然后将其定名为a到i的九个区域,分别对应这九个单元格。
多个单元格合并成一个区域的写法如下。

grid-template-areas: 'a a a'
                     'b b b'
                     'c c c';

如果某些区域不需要利用,则使用"点"(.)表示。
注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end

grid-auto-flow

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。这个顺序由grid-auto-flow属性决定,默认值是row,即"先行后列"。也可以将它设成column,变成"先列后行"。

grid-auto-flow: column;

在这里插入图片描述
grid-auto-flow属性除了设置成rowcolumn,还可以设成row densecolumn dense。这两个值主要用于,某些项目指定位置以后,剩下的项目怎么自动放置。
在这里插入图片描述
上图中,1号项目后面的位置是空的,这是因为3号项目默认跟着2号项目,所以会排在2号项目后面。现在修改设置,设为row dense,表示"先行后列",并且尽可能紧密填满,尽量不出现空格。

grid-auto-flow: row dense;

在这里插入图片描述

justify-items 、align-items 、place-items

justify-items属性设置单元格内容的水平位置(左中右),align-items属性设置单元格内容的垂直位置(上中下)。

.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

这两个属性的写法完全相同,都可以取下面这些值。

属性值效果
start对齐单元格的起始边缘
end对齐单元格的结束边缘
center单元格内部居中
stretch(默认值)拉伸,占满单元格的整个宽度
.container {
  justify-items: start;
}

左对齐
place-items属性是align-items属性和justify-items属性的合并简写形式。

place-items: <align-items> <justify-items>;
justify-content 、align-content、place-content

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)。

.container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

这两个属性的写法完全相同,都可以取下面这些值。

属性值效果
start对齐容器的起始边框
end对齐容器的结束边框
center容器内部居中
stretch(默认值)项目大小没有指定时,拉伸占据整个网格容器
space-around每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
space-between项目与项目的间隔相等,项目与容器边框之间没有间隔
space-evenly项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔

以后三者为例
space-aroundspace-betweenspace-evenly
place-content属性是align-content属性和justify-content属性的合并简写形式。如果省略第二个值,浏览器就会假定第二个值等于第一个值。

grid-auto-columns 、grid-auto-rows

有时候,一些项目的指定位置,在现有网格的外部。比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。
grid-auto-columns属性和grid-auto-rows属性用来设置,浏览器自动创建的多余网格的列宽和行高。它们的写法与grid-template-columnsgrid-template-rows完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。

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

在这里插入图片描述

grid-template、grid

grid-template属性是grid-template-columnsgrid-template-rowsgrid-template-areas这三个属性的合并简写形式。

grid属性是grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow这六个属性的合并简写形式。

项目属性
grid-column-start 、grid-column-end、grid-row-start 、grid-row-end

项目的位置是可以指定的,具体方法就是指定项目的四个边框,分别定位在哪根网格线。

属性名效果
grid-column-start左边框所在的垂直网格线
grid-column-end右边框所在的垂直网格线
grid-row-start上边框所在的水平网格线
grid-row-end下边框所在的水平网格线
.item-1 {
  grid-column-start: 2;
  grid-column-end: 4;
}

上面代码指定,1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。
在这里插入图片描述
上图中,只指定了1号项目的左右边框,没有指定上下边框,所以会采用默认位置,即上边框是第一根水平网格线,下边框是第二根水平网格线。
这四个属性的值,除了指定为第几个网格线,还可以指定为网格线的名字。还可以使用span关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。

grid-column 、grid-row

grid-column属性是grid-column-startgrid-column-end的合并简写形式,grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。

.item {
  grid-column: <start-line> / <end-line>;
  grid-row: <start-line> / <end-line>;
}

斜杠以及后面的部分可以省略,默认跨越一个网格。

grid-area

grid-area属性指定项目放在哪一个区域。

.item-1 {
  grid-area: e;
}

在这里插入图片描述
还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

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

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

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

.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}
.item-1  {
  justify-self: start;
}

在这里插入图片描述
place-self属性是align-self属性和justify-self属性的合并简写形式。

place-self: <align-self> <justify-self>;

如果省略第二个值,place-self属性会认为这两个值相等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值