在页面布局中,我们经常会遇到/使用这么一类常见的布局,也就是列表内容水平居中于容器中,像是这样:

<ul class="g-contaner">
<li></li>
<li></li>
</ul>
ul {
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
gap: 10px;
}

效果如下:

这里,外层的容器是定宽的,内层的 flex-item 也是定宽的。

当 flex-item 个数较小时,是没有问题的。但是,如果当元素内容过多,并且设置了 flex-wrap: nowrap 的话,内容就会溢出容器:

此时,我们有几种解法,其中一种便是给父容器设置 overflow: auto 或者 overflow: hidden,让父容器可以滚动,像是这样:

ul {
// ...
overflow: auto;
}

效果就变成了这样:

我们尝试滚动一下这个容器,会发现一个致命问题:容器只能向左滚动,无法向右滚动,因此只能看到后半部分被截断的内容,而无法看到前半部分被截断的内容

什么意思呢?结合上面的 Gif 与下面这张示意图,一看就懂:

针对这个问题。其中一类比好好的解法在于,当 flex-item 不足以溢出时候,flex-item 居中展示,而当 flex-item 的数量溢出父容器宽度时候,布局上采用类似于 justify-content: flex-start 的样式进行排布,这样可以保证内容在滚动的过程中能够全部看到

正常效果应该如下:

上面第一、第二行就是 flex-item 不足以溢出时候,flex-item 居中展示, 而第三行 ,就是当 flex-item 的数量溢出父容器宽度时候,布局上采用类似于 justify-content: flex-start 的样式进行排布,这样可以保证内容在滚动的过程中能够全部看到。

因此,本文我们将一起探讨一下,在面对这个问题时的几种不同方式的解法。

方法一:Flex 布局下关键字 safe、unsafe

其实,规范也已经注意到了布局下的这个居中滚动问题。

因此,在从 Chrome 115 开始,flex 布局下新增了两个关键字 safeunsafe

基于 CSS Box Alignment Module Level 3,明确列出了这种安全(safe)不安全(unsafe) 的布局说明:

而今天,我们可以直接在对齐模式中,通过 safe 关键字解决这个问题。

我们简单改造一下上述我们的 flex 布局代码,将 justify-content: center 改为 justify-content: safe center 即可:

ul {
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
- justify-content: center;
+ justify-content: safe center;
align-items: center;
gap: 10px;
}

此时,flex 布局就能自动识别当前 flex 容器下的 flex-item 数量是否超出容器宽度/高度,从而改变对齐方式

完整的代码,你可以戳这里自己感受:CodePen Demo -- 使用 Safe 关键字解决 Flex 居中溢出问题

目前而言,这个方法唯一的问题在于 兼容性safe 关键字的大范围使用,还需要静待一段时间。

方法二:使用 margin: auto 替代 justify-content: center

因此,我们有必要继续去探寻其它解决方案。

在之前,有发过另外两篇 flex 相关技巧性的文章 --

  1. 探秘 flex 上下文中神奇的自动 margin - 掘金
  2. 水平垂直居中深入挖掘 - 掘金

除去 justify-content: center 之外,其实我们还可以利用 margin: auto 实现子 flex-item 的水平居中。

我们改造一下文章一开始的示意 DEMO:

ul {
width: 500px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
gap: 10px;
}
li {
margin: auto;
}

当,flex-item 数量不足以溢出容器宽度时,效果如下:

此时,flex-item 在 margin: auto 的作用下,会均分整个容器的剩余空间,并且是水平和垂直方向上的。

用规范的话说就是,设置了 margin: auto 的元素,在通过 justify-contentalign-self 进行对齐之前,任何正处于空闲的空间都会分配到该方向的自动 margin 中去。

所以,margin: auto 也是一种居中非常重要的技巧,虽然我们常将这个技巧用于 flex 布局下的垂直居中。可以翻看一下上面提供的两篇文章。

有趣的是,当 flex-item 的数量溢出父容器宽度时候,由于没有剩余空间了,此时 margin: auto 其实相当于失效了,因此布局上的效果同样也是采用类似于 justify-content: flex-start 的效果进行排布。

同样能达到我们的目的:

完整的代码,你可以戳这里自己感受:CodePen Demo -- 使用 margin:auto 解决 Flex 居中溢出问题

方法三:额外嵌套一层

上面的 margin:auto 虽然没有兼容性问题,但是有一点点瑕疵。我们仔细对比 margin: autojustify-content: center 在 flex-item 不足以溢出下的表现:

瑕疵在于,使用 margin: auto 的方式,flex-item 之间的间距是不可控。因为它们始终会去平分剩余空余空间。

2023-12-06 更新,基于 margin: auto 不可控的方式,其实通过只给子 item 的首个元素添加 margin-left: auto,给尾元素添加 margin-right: auto,其实是可以解决间距问题的。

所以,兼容性最好的方式,就是我们多叠加一层,同样可以巧妙的解决这个问题。

原结构:

<ul class="g-contaner">
<li></li>
// ...
<li></li>
</ul>

改造后的结构:

<ul class="g-contaner">
<ul class="g-wrap">
<li></li>
// ...
<li></li>
</ul>
</ul>

改造后的 CSS:

.g-contaner {
width: 500px;
height: 200px;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: center;
align-items: center;
overflow: auto;
} .g-wrap {
display: flex;
gap: 10px;
max-width: 100%;
}

我们通过多设置了一层 g-wrap,并且设置了 max-width: 100%,当然,它也是一个 flex 容器。

因此当:

  1. .g-wrap 内 flex item 宽度不足 100% 时,整个 .g-wrap 受到其父容器的 justify-content: center 限制会表示为水平居中;
  2. .g-wrap 内 flex item 宽度超出 100% 时,由于设置了 max-width: 100%,所以,整个容器最大宽度就是 .g-container 的宽度。此时的子 flex item 的表现就是默认的 justify-content: flex-start,因此内容也是从头开始展示,滚动场景下没有问题

至此,我们借助多嵌套一层,同样完美的解决了整个问题。其效果与方法一类似,就不再额外贴 Gif 图。

完整的代码,你可以戳这里:CodePen Demo - 使用额外嵌套层解决 Flex 居中溢出问题

总结一下

好,我们快速总结一下三种方式的优劣对比:

  1. 方法一:Flex 布局下关键字 safe、unsafe,修改代码量最少,效果完美,核心问题在于兼容性目前不佳;
  2. 方法二:使用 margin: auto 替代 justify-content: center,兼容性好,问题在于 flex item 不足父容器 100% 时,元素之间间距无法控制;
  3. 方法三:额外嵌套一层,效果完美,改造量略多一点点。

三种方式各有优劣,基于实际面临的业务场景再做选择。

同时,本文举例采用了水平方向的例子,实际在业务中,我们同样可能会遇到垂直方向一样的问题,本文中的解法都是通用的。并且,基于 safe 的解法中,除了 justify-content: safe center 外,safe 关键字还可以应用于 align-itemsalign-self,实际使用时,结合规范,选取最适合的写法。

最后

好了,本文到此结束,希望本文对你有所帮助

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

【布局技巧】Flex 布局下居中溢出滚动截断问题的更多相关文章

  1. 弹性布局(Flex布局)整理

    一.  弹性布局 一个好的网站都有让用户看上去很舒服的布局,一个网站的布局也会或多或少影响到它的浏览量,看完阮大神的博客,就想把弹性布局整理一下. 在平时的我们常用的布局类型有以下几种: 1.浮动+定 ...

  2. cdispaly的Grid布局与Flex布局

    cdispaly的Grid布局与Flex布局 Gird 布局与 Flex 布局有一定的相似性,都是对容器的内部项目进行划分. Flex 布局是轴线布局,只能指定项目针对轴线的位置,可以看作成一维布局 ...

  3. 前端(八)—— 高级布局:文档流、浮动布局、流式布局、定位布局、flex布局、响应布局

    高级布局:文档流.浮动布局.流式布局.定位布局.flex布局.响应布局 一.文档流 1.什么是文档流 将窗体自上而下分成一行一行,块级元素从上至下.行内元素在每行中从左至右的顺序依次排放元素 2.本质 ...

  4. css3弹性伸缩布局(一)—————flex布局

    CSS3弹性伸缩布局简介 2009年,W3C提出了一种崭新的方案—-Flex布局(即弹性伸缩布局),它可以简便.完整.响应式地实现各种页面布局,包括一直让人很头疼的垂直水平居中也变得很简单地就迎刃而解 ...

  5. 关于基本布局之——Flex布局

    Flex布局 1.Flex为"Flexible Box"的简称,即为弹性布局,可作用于任何容器上.给div这类块状元素元素设置display:flex或者给span这类内联元素设置 ...

  6. CSS布局之Flex布局

    Flex布局,可以简便.完整.响应式地实现各种页面布局. 浏览器支持:得到所有浏览器的支持.(注:Flex布局将成为未来布局的首选方案)   一. Flex布局的概念 Flex是Flexible Bo ...

  7. 移动 WEB 开发布局方式 ---- flex 布局

    一.flex布局体验 1.1 传统布局 flex 布局 1. 2 初体验 1. 搭建 HTML 结构 <div> <span>1</span> <span&g ...

  8. Android学习笔记之布局技巧以及布局中的细节介绍....

    PS:休息两天,放一放手上的东西,做做总结... 学习内容: 1.Android中LinearLayout布局技巧... 2.layout中drawable属性的区别...   先简单的介绍一下dra ...

  9. 布局方式-flex布局

    .弹性盒子 .盒子本来就是并列的 .指定宽度即可 <style> .container { width: 800px; height: 200px; display: flex; bord ...

  10. CSS3系列:流式(弹性)布局(flex布局)

    我的新伸缩盒子.http://www.cnblogs.com/leee/p/5533436.html

随机推荐

  1. 学好Elasticsearch系列-索引的批量操作

    本文已收录至 Github,推荐阅读 Java 随想录 微信公众号:Java 随想录 先看后赞,养成习惯. 点赞收藏,人生辉煌. 目录 基于 mget 的批量查询 基于 bulk 的批量增删改 增加 ...

  2. GrapeCity Documents V6.0 Update 2发布,新增支持SpreadJS的.sjs文件格式

    近日,GrapeCity Documents 正式迎来其V6.2 的发布更新,能够支持 SpreadJS 中 .sjs 类型的文件.这一重大更新将为用户带来更多地惊喜. .sjs文件有两个关键优势:空 ...

  3. C盘无法创建文件处理

    icacls c:\ /setintegritylevel M 打开终端执行上方命令,亲测可用

  4. 为什么大家都在用 WebP?

    WebP 是谷歌在 2010 年提出的一种新型的图片格式,放到现在来讲,已经不算是"新"技术了,毕竟已经有了更新的 JPEG XL 和 AVIF .但是在日常工作中,大家时常会碰到 ...

  5. 常用设计模式(Java)

    目录 设计模式引入 1. 什么是设计模式 2. 学习设计模式的意义 3. 设计模式的基本要素 4. OOP七大原则 1.单例模式 1. 饿汉式单例 2. 懒汉式单例 3. 内部类实现单例 4. 反射会 ...

  6. Mysql忘记密码后如何重置密码

    长时间不使用本机的Mysql后把密码忘记了咋整?直接上干货: 第一步(Mysql部署的位置,若自己能找到就忽略这一步):任务管理器中也可以找到 第二步:修改配置文件 在my.ini末尾加上 skip- ...

  7. LVS+keepalived配置高可用架构和负载均衡机制(1)

    一.基础知识 1. 四层负载均衡(基于IP+端口的负载均衡) 所谓四层负载均衡,也就是主要通过报文中的目标ip地址和端口,再加上负载均衡设备设置的服务器选择方式(分发策略,轮询),决定最终选择的内部服 ...

  8. Spring框架中 依赖注入和控制反转,最简单、最通俗的解释! 再加上一个AOP

    首先依赖注入 == 控制反转,只不过控制反转这个词汇,让人产生了错误的理解,才使用新的词汇:依赖注入来替换到这个词汇. "依赖注入"是指一个对象应用另外一个对象来提供一个特殊的能力 ...

  9. Spring Boot中发送邮件时,如何让发件人显示别名

    之前,我们通过一系列文章,介绍了如何在Spring Boot中发送邮件: 发送邮件 添加附件 引用静态资源 邮件模版 已经包含了大部分的应用场景.但最近DD在做YouTube中文配音的时候,碰到一个问 ...

  10. Node.js中常用的设计模式有哪些?

    本文由葡萄城技术团队首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可 ...