
你有没有过这种情况?写布局时想让两个div并排,结果一个“啪嗒”掉下去;或者想让按钮垂直居中,调了半小时margin还歪着?我刚做前端那会,为了一个简单的两栏布局,用float加clearfix写了一堆代码,结果响应式的时候右边栏直接跑到底部,改得我凌晨两点还在挠头。后来学了flex才明白——那些让你头疼的高频布局场景,flex早就给你想好了解决方案,而且代码写起来像“搭积木”一样简单。
先说说最常用的水平垂直居中。我之前用position加transform写,要算top:50%; left:50%; transform: translate(-50%, -50%);,不仅记不住还容易错。现在用flex?两行代码的事:给父元素加display: flex;
,再加上justify-content: center;
(水平居中)和align-items: center;
(垂直居中)。不管里面的元素是固定宽高还是自适应,哪怕是图片、文字或者按钮,都能精准居中。去年帮朋友做他的个人博客,他想让首页的“欢迎来到我的小世界”这句话居中,我用这两行代码改完,他瞪着眼睛说:“原来这么简单?我之前查了半小时教程,写了一堆复杂的CSS!”
再说说自适应两栏/三栏布局——这应该是前端最常遇到的场景之一了吧?比如左边是固定宽度的导航栏,右边是要占满剩余空间的内容栏。用flex的话,左边只要设flex: 0 0 200px;
(意思是“不放大、不缩小、固定200px宽”),右边设flex: 1;
(意思是“占满剩下的所有空间”),搞定!我之前做一个电商网站的商品列表页,左边是筛选栏(固定220px),右边是商品卡片。最开始用float写,结果筛选栏里的选项一多,右边的商品栏直接“掉”到筛选栏下面,客户催着改了三次。后来换成flex,不管筛选栏加多少内容,右边都稳稳地占满剩余空间,再也没出过错——你看,这就是flex的“弹性”优势,它会自动帮你分配空间,不用你手动算宽度。
还有响应式导航栏——现在手机端流量占比越来越高,导航栏能不能适配手机端,直接影响用户体验。我去年帮一家本地奶茶店做官网,他们的导航在PC端是横向排列的,但手机端挤成一团,顾客反馈“点都点不到”。用flex改之后,PC端用justify-content: space-around;
让导航项均匀分布在顶部,手机端用媒体查询加flex-direction: column;
,把导航项变成垂直排列,再加上一个汉堡菜单按钮——不到20行代码,手机端的导航就变得整整齐齐。老板看了之后说:“手机上终于能正常点单了!”
用flex的小技巧,让你少写50%的代码
其实flex的好用,不仅在于能解决高频场景,更在于它的“小技巧”能帮你简化代码——很多你之前要写一堆CSS才能实现的效果,用flex的几个属性就能搞定。
比如flex-grow这个属性,它能控制元素的“放大比例”。比如你有三个div,想让它们按1:2:1的比例占满容器宽度,只要给三个div分别加flex-grow: 1;
、flex-grow: 2;
、flex-grow: 1;
就行,不用算每个div的宽度(比如容器宽800px,第一个div占200px,第二个占400px,第三个占200px)。我之前做一个价格对比表,三个列要均匀分配空间,用flex-grow设成1:1:1,直接“一键均匀”,比用百分比算宽度省了好多时间——关键是不会出错,比如用百分比的话,万一加了padding或border,宽度就会溢出,flex则会自动调整。
再比如order属性,它能“调换元素的顺序”,不用改HTML结构。我之前写一篇文章详情页,PC端是“标题在左、作者信息在右”,但手机端想让“作者信息”排在标题下面(因为手机屏幕窄,这样更符合阅读习惯)。要是用传统方法,得改HTML结构或者用position定位,麻烦得很。但用flex的话,只要给作者信息的div加order: -1;
(order值越小,排得越靠前),再配合媒体查询,手机端就能自动调换顺序——HTML不用动,CSS改一行就行,是不是很高效?
还有align-self属性,它能“单独调整某个元素的垂直对齐方式”。比如你有一个列表,大部分元素都是顶部对齐,但有一个元素想居中——用align-self: center;
就能单独调整这个元素,不用改整个容器的align-items
属性。我之前做一个团队介绍页,团队成员的头像都是顶部对齐,但有一个成员的头像下面有一行小字,我想让这个头像居中,用align-self改了之后,完美解决问题,没影响其他成员的布局。
为了让你更清楚flex的常用属性,我整理了一张flex高频属性表,用大白话解释每个属性的作用和常用值:
属性 | 作用 | 常用值 |
---|---|---|
justify-content | 控制元素在水平方向的对齐方式 | flex-start(左对齐)、center(居中)、space-between(两端对齐)、space-around(均匀分布) |
align-items | 控制元素在垂直方向的对齐方式 | flex-start(顶部对齐)、center(居中)、flex-end(底部对齐)、stretch(拉伸填满) |
flex-direction | 控制元素的排列方向(横排还是竖排) | row(横排,默认)、column(竖排)、row-reverse(反向横排) |
flex-grow | 控制元素的放大比例(剩余空间怎么分) | 0(不放大,默认)、1、2、3…(数字越大,占的空间越多) |
order | 控制元素的排列顺序(不用改HTML) | 0(默认)、-1(往前排)、1(往后排)、2…(数字越小,排得越靠前) |
其实我刚开始学flex的时候,也觉得“不就是个布局方式吗?”,但用得多了才发现——它真的是前端的“效率工具”。比如我之前写一个登录表单,要让输入框和按钮水平排列,并且按钮对齐输入框的右侧。用传统方法,我得给输入框设float:left,按钮设float:right,还要清浮动;用flex的话,只要给父元素加display: flex;
,输入框设flex: 1;
,按钮设margin-left: 10px;
——5行代码搞定,而且不管输入框多长,按钮都能稳稳地排在右边。
现在我做布局,基本上第一反应就是“用flex试试”——它不仅能帮我快速实现效果,更能减少“调试布局”的时间。比如之前用float,我得反复调整margin、clearfix,生怕布局错位;用flex之后,大部分情况都是“写一遍代码就对了”,就算要改,也只要调整一两个属性就行。
如果你还没试过用flex做布局,我 你从“水平垂直居中”开始——先体验一下“两行代码搞定居中”的爽感,再慢慢尝试其他场景。要是你已经在用flex,但还有没摸透的地方,欢迎在评论区告诉我——比如你遇到过什么flex的“坑”?或者有什么好用的小技巧?我们一起聊聊!
你肯定遇过这种情况——要做个顶部导航栏,几个菜单链接得均匀分布在页面上方,或者想让一个橙色按钮在灰色盒子里上下左右都居中,这时候用flex准没错。我之前做这种布局,最开始还在用float加margin一点点调,结果要么链接挤成一团,要么按钮歪到盒子右上角,后来学会flex,直接给父盒子加display: flex
,再补个justify-content: space-around
(导航均匀分布)或者align-items: center
(按钮垂直居中),两三行代码就搞定——比之前用float省了至少一半时间,而且再也没出现过“刷新一下布局就乱了”的情况。其实flex的核心特别好理解,它就是“一维布局”——要么管水平方向的一排(比如导航栏),要么管垂直方向的一列(比如侧边栏的竖排链接),像一根“隐形的线”,把元素按你想要的方向串起来,不用你手动算每个元素的位置。
但要是遇到更复杂的场景,比如电商网站的商品列表,你想让每排正好放3个商品,每个商品都有图片、标题、价格,而且不管屏幕多大,每排的3个都要整整齐齐对齐(哪怕图片高度不一样,标题也要在同一水平线),这时候flex就有点“吃力”了。我上个月帮朋友的美妆店做官网时就遇到这问题:用flex排商品,每排3个,结果有的商品标题长一点,整个卡片就被拉长,下一排的商品跟着歪;换成Grid之后,只写了grid-template-columns: repeat(3, 1fr)
这一行代码,直接让每排3个商品,每个商品占的宽度一模一样,而且不管图片多高,每个商品卡片的底部都能对齐——就像给每个商品套了个“格子”,牢牢固定在对应的位置里。这就是Grid的本事,它是“二维布局”,能同时管“行”和“列”,像一张“隐形的网”,把元素精准放在网格里,不管屏幕怎么变,网格的结构都不会乱。
其实我现在做布局,根本不会纠结“选flex还是Grid”——因为它们俩是互补的,不是非此即彼的关系。比如做一个完整的页面,我会用flex做header的水平导航(一根线串起菜单),用Grid做main的商品列表(一张网固定商品),再用flex做footer的底部链接(一根线居中版权信息),两种布局配合着用,比单独用其中一个灵活多了。你想啊,要是你就想让几个元素“排成一串”(比如导航、按钮居中),flex是最顺手的工具;要是你想做“像表格一样的网格”(比如商品列表、表单),Grid能帮你省掉大把调试对齐的时间。我上周做个求职网站的简历模板,表单部分用Grid排了两列(左边是label,右边是输入框),grid-template-columns: 120px 1fr
一句话就让label占固定宽度,输入框占剩下的空间,每一行都对齐得整整齐齐,比用flex一行一行调省心多了。
还有次我帮邻居的早餐店做小程序页面,首页的“推荐套餐”要排2列,每列有图片、名称、价格,手机端要改成1列。用Grid的话,只需要在媒体查询里把grid-template-columns
从repeat(2, 1fr)
改成1fr
,瞬间就适配了手机端——要是用flex,我得调flex-wrap和width,反而容易出错。所以真不用觉得“Grid比flex高级”或者“flex要被淘汰了”,它们俩就像筷子和勺子,各有各的用处:筷子能夹菜,勺子能喝汤,一起用才能吃得更舒服。你只要记住——布局是“一根线”(要么排一排,要么排一列)就用flex,是“一张网”(又要排又要列)就用Grid,俩一起用也完全没问题,反而更高效。
flex弹性布局的浏览器兼容性怎么样?
现代浏览器(Chrome、Firefox、Safari、Edge)都完美支持flex布局,IE10及以上版本也能兼容基本功能(需要加-ms-前缀,比如display: -ms-flexbox;)。如果你的项目不需要兼容IE9及以下,完全可以放心用——现在大部分前端项目的兼容性要求已经覆盖到IE10+,所以不用太担心flex的兼容性问题。
flex和Grid布局有什么区别?应该选哪个?
flex是「一维布局」(只能处理行或列中的一个方向),适合做导航栏、水平/垂直居中、两栏自适应这类简单布局;Grid是「二维布局」(同时处理行和列),适合更复杂的网格场景,比如商品列表的多列排版、表单的二维对齐。简单说:如果你的布局是「一排或一列」,用flex;如果是「多排多列」,用Grid——两者不是替代关系,而是互补的。
用flex布局时,子元素挤在一起不换行怎么办?
默认情况下,flex的子元素会「强制排在一行」,哪怕超出容器宽度。想让子元素换行,只要给父元素加flex-wrap: wrap;
就行!比如做商品卡片布局时,卡片太多挤成一团,加这个属性后,卡片会自动换行到下一行。如果要调整换行后的垂直对齐方式(比如换行后上下间距均匀),还可以用align-content: space-between;
这类属性。
flex-grow、flex-shrink、flex-basis这三个属性怎么理解?
这三个是flex的「核心子元素属性」,合起来可以简写为flex: [grow] [shrink] [basis];
:
flex-grow:1;
表示这个元素会占满容器的剩余空间(数值越大,占的空间越多); flex-basis:200px;
表示元素先占200px,剩下的空间再按flex-grow分配。 最常用的简写是flex:1;
,等于flex-grow:1; flex-shrink:1; flex-basis:0%;
,适合让元素占满剩余空间。
用flex做垂直方向的布局(比如竖排导航)怎么设置?
默认flex是「水平排列」(flex-direction: row;),想改成垂直排列,只要给父元素加flex-direction: column;
就行!比如竖排导航栏,父元素加这个属性后,子元素会从上到下垂直排列。如果要调整垂直方向的对齐(比如导航项靠上/居中/靠下),用justify-content
(因为方向变了,justify-content now控制垂直方向);调整水平方向的对齐(比如导航项靠左/居中/靠右),用align-items
。