前情
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 Flex 布局,如果说目前我开发中离不开的布局方式那就非 Flex 莫属了,而且小程序就是推荐使用 Flex 布局的,对 Grid 布局的支持不太理想。
在一次次使用 flex 布局的时候遇到了一些小困扰,而解决这些小困扰的过程中发现了一些小技巧,特记录并分享出来。
技巧内容
技巧 1:flex-direction 为 column 的子元素自适应内容宽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
.test {
width: 100%;
display: flex;
flex-direction: column;
}
.test-item {
height: 100px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: red;
color: white;
}
.test-item:nth-of-type(3){
align-self: flex-start;
}
</style>
</head>
<body>
<div class="test">
<div class="test-item">010101</div>
<div class="test-item">020202</div>
<div class="test-item">030303</div>
</div>
</body>
</html>
复制代码
当设置为 flex-direction: column 后,项目元素 align-self 样式值默认为 stretch,导致项目元素会充满整行,如果你想做到项目元素自适应内容宽你设置为 align-self:baseline 或者 flex-start 即可
上述示例可以实现如下图布局效果:
体验链接:CSS Playground
技巧 2:利用 margin:auto 实现一些特殊布局
对于如下需求你第一想到的 flex 布局方式是怎么实现:
按正常的实现思路是左边一个 div 包住左边内容,右边再一个 div,再使用 justify-content:between 可以实现或者让左边的 div 为 flex:1,那有什么方式可以让结构打平一层,左边的包裹 div 免去了,那就是 margin:auto,利用好 margin:auto 可以实现一些特殊布局,演示代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
.test,.test0,.test1 {
width: 100%;
display: flex;
flex-direction: row;
background-color: black;
}
.test-item,.test-item0,.test-item1 {
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
color: white;
background-color: green;
}
.test-item:nth-last-of-type(1){
margin-left: auto;
}
.test-item0:nth-last-of-type(2){
margin-left: auto;
}
.test-item1:nth-of-type(2){
margin-left: auto;
}
.test-item1:nth-of-type(3){
margin-right: auto;
}
</style>
</head>
<body>
<div class="test">
<div class="test-item">1</div>
<div class="test-item">2</div>
<div class="test-item">3</div>
<div class="test-item">4</div>
</div>
<div class="test0">
<div class="test-item0">1</div>
<div class="test-item0">2</div>
<div class="test-item0">3</div>
<div class="test-item0">4</div>
</div>
<div class="test1">
<div class="test-item1">1</div>
<div class="test-item1">2</div>
<div class="test-item1">3</div>
<div class="test-item1">4</div>
</div>
</body>
</html>
复制代码
上述示例可以实现如下图布局效果:
体验链接:CSS Playground
技巧 3:利用 align-self 实现交叉轴(Cross Axis)上单个元素位置控制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.test {
display: flex;
flex-direction: column;
align-items: center;
}
.test-item {
width: 100px;
height: 100px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
color: white;
background-color: red;
}
.test-item:nth-of-type(1){
align-self: flex-start;
}
.test-item:nth-of-type(3){
align-self: flex-end;
}
</style>
</head>
<body>
<div class="test">
<div class="test-item">1</div>
<div class="test-item">2</div>
<div class="test-item">3</div>
</div>
</body>
</html>
复制代码
通过 align-items 可以整体控制交项目元素在叉轴上的对齐方式,但如果想单个控制它的对齐方式,那就用好 align-self 吧,上述示例可以实现如下图布局效果:
体验链接:CSS Playground
技巧 4:使用 gap 设置容器内项目之间的间距
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
.wrap {
display: flex;
flex-direction: row;
}
.test {
width: 320px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
margin-right: 20px;
}
.test-item {
width: 100px;
height: 100px;
margin-bottom: 10px;
flex: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
color: white;
background-color: red;
}
.test0 {
width: 320px;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
margin-right: 20px;
gap: 10px 10px;
}
.test-item0 {
width: 100px;
height: 100px;
flex: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
color: white;
background-color: red;
}
</style>
</head>
<body>
<div class="wrap">
<div class="test">
<div class="test-item">01</div>
<div class="test-item">02</div>
<div class="test-item">03</div>
<div class="test-item">04</div>
<div class="test-item">05</div>
<div class="test-item">06</div>
<div class="test-item">07</div>
<div class="test-item">08</div>
</div>
<div class="test0">
<div class="test-item0">11</div>
<div class="test-item0">12</div>
<div class="test-item0">13</div>
<div class="test-item0">14</div>
<div class="test-item0">15</div>
<div class="test-item0">16</div>
<div class="test-item0">17</div>
<div class="test-item0">18</div>
</div>
</div>
</body>
</html>
复制代码
Flex 布局如果不依赖 gap 想实现如下右图的布局是比较麻烦的,通过 justify-content: space-between 可以做到平分余下空间让元素间有间距,但是如果遇到未行元素不够的时候就会出现如下左图的问题,解决办法是手动生成一个空的元素让它补齐一行内容也是可以做到的;另一种实现方式是通过 margin 来实现元素间距,再通过:nth-child()方式来去除每行最边缘元素的 margin。上述二种方式都相对比较麻烦,如果你使用 gap 就可以轻松实现右图效果
体验地址:CSS Playground
技巧 5:比较常用的几个缩写
flex: 1/flex: 0%; 等效于 flex:1 1 0%; 子元素平分父元素空间,各子元素尺寸一样
flex: none; 等效于 flex:0 0 auto; 元素保持自身原始大小不变
flex:auto; 等效于 flex:1 1 auto; 元素尺寸可以弹性增大,也可以弹性变小,具有十足的弹性,项目会根据自身大小和剩余空间进行伸缩
注:flex:1 和 flex:auto 区别:
flex-basis 属性定义了项目在分配多余空间之前,占据的主轴空间(main size)
flex:1 相当于 flex: 1 1 0%,表示项目的基准大小为 0%,不考虑项目本身的大小,只根据剩余空间进行伸缩
flex:auto 相当于 flex: 1 1 auto,表示项目的基准大小为 auto,即项目本身的大小,同时也会根据剩余空间进行伸缩
如果容器有足够的空间,flex:1 和 flex:auto 都会平分剩余空间,但是 flex:auto 会保持项目本身的最小宽度,而 flex:1 不会
如果容器没有足够的空间,flex:1 会优先压缩内容,使得所有项目都能等分空间,而 flex:auto 会优先保持内容的完整性,挤压其他项目的空间
在线测试地址:JS Bin - Collaborative JavaScript Debugging
技巧 6:浏览器开发者工具辅助使用
对于新手刚刚学习使用 flex 布局,经常容易忘记一些属性,其实可以通过浏览器开发者工具辅助来学习 flex 布局,vs code 也有对应的插件可以辅助
期望
上述只是个人在开发中发现的一些 Flex 布局小技巧,如果你有好的技巧欢迎也分享出来,共同学习进步。期待你的留言👀。
文章转载自:!win !
原文链接:https://www.cnblogs.com/xwwin/p/18603495
体验地址:http://www.jnpfsoft.com/?from=infoq
评论