一、代码整体功能解读

这段代码是 Odoo 官网底部(footer)的布局代码,基于 Bootstrap 栅格系统实现响应式布局,主要包含:

  1. 品牌 Logo 区域;
  2. 分栏的导航链接(社区、开源、服务、关于我们);
  3. 语言选择器、企业简介、社交媒体链接;
  4. 版权信息栏。

核心依赖 Bootstrap 的栅格规则:containerrowcol-* 层级结构,通过 row 包裹列(col)实现横向布局,col-* 控制不同屏幕尺寸下的列宽。

二、为什么用三个 .row?(核心问题)

结论:看似“一行布局”,实则是「嵌套式栅格」的设计逻辑——每个 .row 服务于不同层级的列拆分,而非“同一行”的重复使用

我们逐一层解三个 .row 的作用,结合 Bootstrap 栅格的核心规则:row 是列的“容器”,必须包裹 col;且 row 会清除列的浮动、设置负边距,保证列的对齐和间距。

第一个 .row:最外层的“大行”(全局布局拆分)

<div class="row"> <!-- 第一个row -->
  <div class="col-12 col-lg-7 col-xl-6">导航链接区</div>
  <div class="col-12 col-lg-5 col-xl-5 offset-xl-1">语言/简介/社交区</div>
</div>
  • 作用:将 footer 主体拆分为「左右两大列」:

    • 左侧列(col-12 col-lg-7):小屏幕占满整行,大屏占 7/12 宽度,放导航链接;
    • 右侧列(col-12 col-lg-5):小屏幕占满整行,大屏占 5/12 宽度,放语言选择、简介、社交链接;
  • 必要性:这是 footer 主体的“一级拆分”,必须用 row 包裹这两个列,否则列无法按栅格规则排列(Bootstrap 要求 col 必须嵌套在 row 内)。

第二个 .row:左侧导航区的“二级行”(导航链接的列拆分)

<div class="col-12 col-lg-7 col-xl-6">
  <div class="row"> <!-- 第二个row -->
    <div class="col-12 col-md-4">社区+开源链接</div>
    <div class="col-6 col-md-4">服务链接</div>
    <div class="col-6 col-md-4">关于我们链接</div>
  </div>
</div>
  • 作用:在「左侧大列」内部,进一步拆分为「三列导航组」:

    • 第一列(col-12 col-md-4):小屏幕占满整行,中等屏占 4/12,放“社区+开源”链接;
    • 第二/三列(col-6 col-md-4):小屏幕各占 6/12(半行),中等屏各占 4/12,分别放“服务”“关于我们”链接;
  • 必要性:左侧大列是一个独立的“容器”,要在其内部再拆分列,必须嵌套新的 row——因为 Bootstrap 的 col 不能直接嵌套 col,必须通过 row 作为中间层(否则列的间距、对齐会错乱)。

第三个 .row:“社区+开源”列的“三级行”(最细粒度的列拆分)

<div class="col-12 col-md-4 mb-3 mb-md-0">
  <div class="row"> <!-- 第三个row -->
    <div class="col-6 col-md-12">社区链接</div>
    <div class="col-6 col-md-12">开源链接</div>
  </div>
</div>
  • 作用:在「社区+开源」这个二级列内部,再拆分为「两列(社区/开源)」:

    • 小屏幕(<768px):两列各占 6/12(半行),横向排列;
    • 中等屏(≥768px):两列各占 12/12(整行),纵向堆叠;
  • 必要性:和第二个 row 逻辑一致——要在一个 col 内部再拆分列,必须嵌套 row,否则无法实现“小屏横向分栏、大屏纵向堆叠”的响应式效果。

三、核心逻辑总结(为什么不能只用一个 row?)

  1. 栅格嵌套规则:Bootstrap 栅格的核心是「row → col → row → col」的嵌套层级,col 内部不能直接放 col,必须通过 row 中转,否则列的 margin/padding、浮动等样式会失效,布局错乱;
  2. 响应式分层控制:三个 row 分别对应「全局→左侧导航→社区/开源」三个层级的响应式拆分:

    • 一级 row:控制 footer 左右两大块的大屏/小屏占比;
    • 二级 row:控制左侧导航区三列的大屏/小屏占比;
    • 三级 row:控制社区/开源两列的大屏/小屏占比;
  3. 视觉上的“一行”≠ 代码上的“一个 row”
    你看到的“一行布局”是「大屏下的最终视觉效果」,但代码需要兼容小屏的响应式折叠(比如小屏下,这些列会逐层堆叠),嵌套的 row 是实现“不同屏幕下不同列数拆分”的必要手段。

四、补充细节(辅助理解)

  1. 类名含义(Bootstrap 响应式):

    • col-12:超小屏(<576px)占 12/12(整行);
    • col-md-4:中等屏(≥768px)占 4/12;
    • col-lg-7:大屏(≥992px)占 7/12;
    • offset-xl-1:超大屏(≥1200px)向右偏移 1/12;
  2. 其他样式类:

    • o_not_editable:Odoo 自定义类,标记该区域不可编辑;
    • dropdown:Bootstrap 下拉菜单(语言选择器);
    • text-muted/mb-4 等:Bootstrap 文本样式、间距类。

五、简化理解的类比

可以把整个 footer 想象成一个“三层抽屉柜”:

  • 第一层抽屉(第一个 row):把柜子分成左右两个大格;
  • 第二层抽屉(第二个 row):在左大格里,再分成三个中格;
  • 第三层抽屉(第三个 row):在第一个中格里,再分成两个小格;
    每个抽屉(row)都是为了“拆分其内部空间”,而非重复描述“同一层”。
    (来自doubao) 理解bootstrap的grid布局

标签: none