详细讲解 Web 页面为什么会出现横向滚动条,以及如何利用 Chrome DevTools 快速定位问题,解决 Flex、Grid、Shiki、Table 等常见布局溢出问题。
在开发响应式页面时,我们经常会遇到这样一种情况:
很多开发者第一反应会认为是导航栏的问题,但实际上,真正导致横向滚动条出现的,通常是页面中的某一个元素把整个布局撑宽了。
本文将介绍如何快速定位问题,以及常见的解决方案。
浏览器会根据页面所有元素计算整个文档的宽度。
如果某个元素的实际宽度超过了浏览器视口(Viewport),整个页面就会出现横向滚动。
例如:
Viewport(1200px) ┌────────────────────────────┐ │ │ │ 页面内容 │ │ │ └────────────────────────────┘ 某个元素实际宽度:1450px 最终: Document Width = 1450px
此时浏览器就会自动出现横向滚动条。
打开浏览器 Console:
console.log(document.documentElement.clientWidth) console.log(document.documentElement.scrollWidth)
如果得到:
clientWidth = 1180 scrollWidth = 1456
说明页面确实存在元素超出了浏览器宽度。
其中:
只要 scrollWidth 大于 clientWidth,就一定存在布局溢出。
很多人会一个一个排查组件,其实 Chrome Console 可以直接找到问题元素。
执行下面这段代码:
const els = [...document.querySelectorAll('*')] els.forEach(el => { const rect = el.getBoundingClientRect() if (rect.width > window.innerWidth) { console.log(el, rect.width) } })
它会打印所有宽度超过浏览器的元素。
如果结果是:
<main> <article>
不要误以为就是它们。
很多时候它们只是被内部元素撑大了。
真正需要继续定位子元素。
继续执行:
const max = { el: null, right: 0 } for (const el of document.querySelectorAll('*')) { const rect = el.getBoundingClientRect() if (rect.right > max.right) { max.el = el max.right = rect.right } } console.log(max)
这段代码可以快速找到页面最右边的元素。
通常就是导致整个页面溢出的元凶。
这是目前最常见的问题。
例如:
<div className="flex"> <article className="flex-1"> <aside className="w-80"> </div>
很多开发者认为 flex-1 会自动收缩。
实际上不会。
Flex Item 默认具有:
min-width: auto;
也就是说:
内容再长,它也不会缩小。
正确写法应该是:
<div className="flex"> <article className="flex-1 min-w-0"> <aside className="w-80 shrink-0"> </div>
其中:
这是解决大多数 Flex 横向滚动问题最关键的一步。
如果项目使用了 Shiki 高亮。
默认生成:
<pre class="shiki">
很多主题会默认设置:
white-space: pre;
导致长代码不会自动换行。
推荐样式:
pre.shiki { max-width: 100%; overflow-x: auto; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; } pre.shiki code, pre.shiki span, pre.shiki .line { white-space: inherit; }
这样既支持代码自动换行,也不会撑宽整个页面。
HTML Table 默认不会自动缩小。
错误写法:
<table class="max-w-full">
实际上 max-width 对 table 基本不起作用。
正确方式:
<div class="overflow-x-auto"> <table class="min-w-full"> </div>
让 Table 自己滚动,而不是整个页面滚动。
很多图片都会超过容器宽度。
推荐统一添加:
img { max-width: 100%; height: auto; }
这样图片永远不会撑宽父容器。
例如:
https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
由于没有空格,浏览器不会自动断行。
可以添加:
overflow-wrap: anywhere; word-break: break-word;
即可自动换行。
如果无法确定是哪一个元素。
可以在 DevTools 中选择:
Elements
然后点击左上角元素选择器。
鼠标移动页面。
如果蓝色高亮区域已经超过浏览器宽度。
那么当前选中的元素,就是导致页面溢出的关键节点。
页面出现横向滚动条,并不是导航栏的问题,而是某个元素撑宽了整个文档。
实际开发中,最常见的几个原因分别是:
掌握 Chrome DevTools 的定位方法之后,基本几分钟内就能找到真正导致页面溢出的元素,大幅提升排查布局问题的效率。
暂无评论,留下第一条声音吧。