开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
使用Flexbox构建经典布局
Flexbox提供了一种非常有效的方式来定位,排序和分布元素,即使在视窗或元素大小不明确或动态变化时亦是如此。
Flexbox 的优势可以用一句话来表达:“在不需要复杂的计算之下,元素的大小和顺序可以灵活排列 ”,即“Flexbox 为您提供了元素大小和顺序的灵活性”。如此一来,可以让 Web 的布局变得简单地多。
Flexbox构建一些经典布局,也是在实践中经常使用的一些布局,比如等高布局,分屏(或等分列),水平垂直居中 、Sticky Footer 、圣杯布局 和 Grid Frameworks(简单的网格系统) 等,我们平常使用的比如: 浮动(float),定位(position)和内联块(display:inline-block)等实现布局会比较困难,甚至还需要一定的CSS黑魔法(Hark手段),但我们使用Flexbox就容易的多。
而在Web布局中,水平垂直居中是使用很频繁的,比如Icon图标在容器中水平垂直居中,一个标题在导航栏中水平垂直居中等。
水平垂直居中常见的效果一般有两种,单行(或单列)水平垂直居中和多行(或多列)水平垂直居中。
在Flexbox中,我们可以在flex容器上使用:
justify-content:center;让flex项目水平居中。
- 对于单行而言,使用align-items:center;可以让flex项目垂直居中,当然也可以使用align-content:center;不过要显式设置flex-wrap的值为wrap或wrap-reverse.
- 对于多行而言,flex-direction的值设置为column,可以使用align-items:center让flex项目水平居中,然后使用justify-content:center实现垂直方向居中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="container">
<div class="item-single">元素</div>
<div class="item-multiple"><span>1</span><span>2</span><span>3</span></div>
</div>
</body>
</html>
<style>
.container {
display: flex;
border: 1px solid #000;
width: 500px;
height: 300px;
}
.item-single {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 100px;
background: skyblue;
}
.item-multiple {
display: flex;
flex-direction: column;
width: 100px;
height: 100px;
background: gray;
justify-content: center;
align-items: center;
}
</style>
你还可以使用align-self来实现flex项目垂直居中,设置align-self:center即可
.container {
display: flex;
justify-content: center;
}
.item {
align-self: center;
}
如果要实现单个flex项目在flex容器中水平垂直居中,你还可以使用justify-content和align-content的简写place-content来设置为center,但需要配合flex-wrap来使用,一般设置为wrap.
.container {
display: flex;
place-content:center;
}
当然我们只需要控制一个flex项目在容器中水平垂直居中时,使用margin:auto;也是可以的。
等高布局
在设置一些多卡片内容,多个盒子排布的时候,需要给他们设置相同高度的排列布局,这时我们使用flexbox就很容易实现。
如果要实现上面这种等高布局的卡片排列形式,我们使用Flexbox来布局
<div class="cards">
<div class="card">
<figure>
<img src="thumb.png" alt="缩略图" />
</figure>
<h3>Card Title</h3>
<p>Card Describe</p>
<button>Button</button>
</div>
<!-- 其他 Card -->
</div>
<style>
.cards {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
display: flex;
flex-direction: column;
flex: 1 1 300px;
}
</style>
我们给卡片都设置了flex,使所有的卡片都变成等高的,但这时也会有一个问题,虽然卡片都是等高的了,但是里面的内容会因为数量而造成扩展和压缩,所有我们设置给内容标签p上flex-grow:1;就可以解决卡片内容的大小;当然我们也可以设置底部按钮button元素margin-top:auto;如果不希望按钮宽度占满整行,还可以设置align-self:flex-start(flex-end)。
均分列(等分列)布局
在Web中,均分列的布局效果有很多,特别是在Web移动端中,像一些底部菜单栏,商品展览栏,卡片分布栏等,这些布局效果最大的特点就是每列的宽度是相等的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="container">
<div class="item">code <span>首页</span></div>
<div class="item">code <span>逛一逛</span></div>
<div class="item">code <span>商品</span></div>
<div class="item">code <span>我的页面</span></div>
</div>
</body>
</html>
<style>
.container {
display: flex;
}
.item {
flex: 1;
min-width: 0;
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 5px;
}
</style>
要真正达到均分列,只在 Flex 项目上显式设置 flex:1 是不够的,还需要在 Flex 项目上显式设置 min-width 值为 0 。这也就是说,为什么 min-width:0 很重要。
不过,在使用 flex:1 的时候,需要额外注意的是,这个 1 会被视为 flex-grow 的值。如果你要使用 flex ,更建议的做法是,显式地使用 flex 属性的三个值,比如 flex: 1 1 0% 或 flex: 1 1 100% 。
圣杯布局
对于经典的圣杯布局,它有:
页头
页脚
主内容
左侧边栏
右侧边栏
在HTML源码的文档中,主内容
位于两个侧边栏之前页头
和页脚没有固定额的高度,由其内容或盒模型属性值(margin,padding,border)决定相关大小在垂直方向上,中间三列(
)的高度占据和之外的浏览器视窗高度,并且随着内容的增多而变高。在水平方向,一般情况之下两个侧边栏也是由其内容来决定大小,但多数情况之下会给两个侧边栏设置一个固定宽度。中间主内容列 <article> 占据两侧边栏之外的浏览器视窗宽度,并且随着内容增加,不会出现水平滚动条。
Sticky Footer布局
页脚
的位置会随着页头(Header),主内容(Content)高度而变化,但当页头和主内容内容较小,其高度总和小于浏览器视窗高度时,页脚始终位于浏览器视窗底部而对于Sticky Footer布局,使用Flexbox只需要保持主内容容器随着父容器的剩余空间扩展,其实就是给主容器设置一个flex-grow:1;就可以了。
如果不希望当浏览器视窗高度较小,主内容容器高度进行收缩,你可以将其flex-chrink设置为0,同样,为了避免页头和页脚收缩,也可以在它们上面设置flex-chrink为0。
除了上面这种方法外,还可以设置页脚margin-top:auto来实现布局效果。
百分百无滚动布局
百分百不滚动布局也是Web中常见的一种布局,比如要设置一个弹窗,包括顶部容器,下面滚动容器
需要效果是顶部不动,中间的内容较多时可以滚动
主体代码是:
<!-- 整个 Modal 高度是 100vh -->
<modal>
<modal-header>
<!-- 固定高度 -->
</modal-header>
<modal-content>
<!-- 滚动容器:flex: 1 -->
</modal-content>
</modal>
modal {
height: 100vh;
display:flex;
flex-direction:column;
}
modal-header {
height:120px;
}
modal-content {
flex:1;
overflow-y:auto;
}
经过上面书写,会在ios系统上触发一个Bug,就是在滚动内容上显式设置overflow-y:scroll,滚动依然会失效,成这个 Bug 是因为我们上面的 CSS 代码触发了 Flex 项目的边缘情况。
这时关键是需要给设置flex:1的滚动容器的父元素设置min-width:0,在设置flex:1的flex项目上尽可能重置它的最小尺寸值。