现代双栏布局首选Flex或Grid:Flex更直观,适用于主内容+侧边栏;Grid更灵活,适合多栏响应式,但需语义正确的HTML结构,否则CSS无效。

双栏布局不用 float,也不靠 width + margin 硬调;现代写法就两条路:display: flex 或 display: grid,前者更直观,后者更灵活——但前提是 HTML 结构得对,否则再好的 CSS 也撑不住。
用 display: flex 实现主内容+侧边栏
这是最常用、最不容易翻车的方案。关键不是给整个页面加 flex,而是只在需要分栏的容器上设 display: flex,并控制子元素宽度和顺序。
-
<main></main>标签本身语义就是“主体内容区”,别再套一层<div class="container">,否则 flex 容器层级错乱,<code><aside></aside>可能被拉伸或错位 - 主内容建议用
flex: 1(等价于flex: 1 1 0),侧边栏用固定宽度或flex: 0 0 280px,避免内容撑破 - 别在
或上直接设display: flex,否则<header></header>和<footer></footer>高度会被强制拉满,导致页脚不贴底
<main>
<article><p>正文内容</p></article>
<aside><p>相关推荐</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20d3191a227.jpg" alt="DeepBI DHTML 页面生成器" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器">DeepBI DHTML 页面生成器</a>
<p>生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力:
- 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面;
- 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”;
- 提及位于 `apps/console/src/featur</p>
</div>
<a href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div></aside>
</main>
<style>
main { display: flex; }
article { flex: 1; padding: 1rem; }
aside { flex: 0 0 280px; padding: 1rem; background: #f5f5f5; }
</style>
用 display: grid 控制列宽与响应断点
适合需要精确列比例、或后续要扩展为三栏/自适应多栏的场景。Grid 不依赖 DOM 顺序,但必须明确定义 grid-template-columns,且注意 fr 单位在小屏下可能让侧边栏过窄甚至消失。
- 写
grid-template-columns: 1fr 280px比3fr 1fr更可控——前者主栏自适应,侧栏绝对宽度;后者在窄屏下会把两栏都压扁 - 用
@media (max-width: 768px)把 grid 改成grid-template-columns: 1fr,同时给<aside></aside>加order: -1就能让侧栏移到顶部,而不是卡在正文下面 - 别漏掉
grid-gap(或gap),否则两栏紧贴,视觉上像一栏
<style>
main { display: grid; grid-template-columns: 1fr 280px; gap: 1.5rem; }
@media (max-width: 768px) {
main { grid-template-columns: 1fr; }
aside { order: -1; }
}
</style>
为什么 <aside></aside> 不等于“右边那个 div”
很多页面把广告、全站导航、登录框塞进 <aside></aside>,结果在移动端用 display: none 隐藏后,SEO 和屏幕阅读器仍会读取它——因为语义错了。<aside></aside> 必须是与当前 <article></article> 强相关的辅助内容,比如“本文作者介绍”“同类文章推荐”,而不是“全站最新活动”。
- 全站通用模块该用
<section></section>+aria-labelledby,或直接<div role="complementary"> <li>如果只是视觉上想放右边,但语义上不相关,就别用 <code><aside></aside>,用<div class="sidebar"> 更诚实 <li>结构语义错,CSS 再怎么加 <code>min-width或overflow-wrap也救不了响应失效和可访问性问题 - 用
display: none隐藏侧栏最稳妥,它天然移除渲染、焦点和可访问性树 - 如果要用动画隐藏,优先选
clip-path或visibility: hidden+opacity: 0,再配合pointer-events: none - 确保
<main></main>的tabindex或焦点管理逻辑适配了布局切换,否则键盘用户会卡住
移动端双栏塌陷时容易忽略的细节
很多人只记得改宽度,却忘了交互反馈和焦点流。比如侧栏收起后,键盘焦点还在原位置,用户按 Tab 键可能跳进不可见区域;或者用 transform: translateX(100%) 隐藏侧栏,但没加 inert 属性,屏幕阅读器仍会朗读。
真正难的不是写两行 CSS,而是判断哪块内容该归到 <article></article>、哪块该进 <aside></aside>、哪块根本不该出现在这个页面里。结构定错,后面所有样式都是补丁叠补丁。


















