0

0

浅谈BootStrap实现栅格布局的方法

青灯夜游

青灯夜游

发布时间:2021-06-01 11:37:42

|

5098人浏览过

|

来源于掘金社区

转载

本篇文章给大家介绍一下bootstrap实现栅格布局的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

浅谈BootStrap实现栅格布局的方法

【相关推荐:《bootstrap教程》】

1. 基本点

box-sizing: border-box

这是最基本的一点,将盒子模型设置成边框盒子.这样 width 属性指定的盒子宽度就包括 border + padding + content。只要 width 固定,指定 paddingborder 将不会改变盒子的大小。

*,
*::before,
*::after {
    box-size: border-box;
}

知识前置

  • sass 基础
  • bootstrap 栅格布局基本会使用
  • flex 布局基础

本文栅格实现参考 bootstrap 源码实现

2. Container

一般来说作为应用最顶层的容器分为两种:

  • 响应式容器
    • .container
    • .container-sm
    • .container-md
    • .container-lg
    • .container-xl
  • 固定宽度容器( bootstrap 中叫做流体容器)
    • .container-fluid

响应式容器会根据屏幕宽度的不同,根据媒体查询使用 max-width 约束容器的宽度。因为 bootstrap 移动优先的原则,所以是先满足小屏幕的容器样式,然后再根据媒体查询扩展大屏幕的样式。

container 基本数据


xs   sm  >= 576px md  >=768px lg  >=992px xl  >=1200px
.container 100% 540px 720px 960px 1140px
.container-sm 100% 540px 720px 960px 1140px
.container-md 100% 100% 720px 960px 1140px
.container-lg 100% 100% 100% 960px 1140px
.container-xl 100% 100% 100% 100% 1140px
.container-fluid 100% 100% 100% 100% 100%

断点:

$grid-breakpoints: (
    xs: 0,
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px
);

不同断点对应的容器宽度:

$container-max-widths: (
    sm: 540px, // min-width: 576px
    md: 720px, // min-width: 768px
    lg: 960px, // min-width: 992px
    xl: 1140px // min-width: 1200px
);

实际上断点到底取在哪里,可以随意自定义。这里只是引用的 bootstrap 的规范而已。

2.1 固定容器实现

固定容器实现很简单。无非就是将容器的宽度设置为 100%, 水平居中而已。

/**
 * 基本容器的样式
 * 宽度 100%
 * 有半个槽宽的内边距
 * 水平居中
 * @param $gutter 槽宽, 如果只是想要一个普通的容器。可以将参数槽宽设置为 0
 *                默认值是 $gird-gutter-width
 */
@mixin make-container($gutter: $grid-gutter-width) {
    width: 100%;
    padding-right: $gutter / 2;
    padding-left: $gutter / 2;
    margin-right: auto;
    margin-left: auto;
}

槽宽这个概念如果用过 bootstrap 应该能够理解。如果不理解可以跳到本文底部,有详细介绍。

当屏幕宽度小于 576px 的时候,所有的容器宽度都是 100%。即 xs 的情况下:

.container,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-fluid {
    @include make-container();
}

2.2 响应式容器实现

要实现响应式容器,就是要根据不同的断点分别给不同的容器设置媒体查询,以 max-width 约束容器的宽度。

根据规范所示:

  • 当断点为 sm 时, .container, .container-smmax-width540px,其余容器为初始的 100%
  • 当断点为 md 时, .container, .container-sm, .container-mdmax-width720px,其余容器为初始的 100%
  • 当断点为 lg 时, .container, .container-sm, .container-md, .container-lgmax-width960px,其余容器为初始的 100%
  • 当断点为 xl 时, .container, .container-sm, .container-md, .container-lg, .container-xlmax-width1140px,其余容器为初始的 100%

分析一下,就可以发现。每个断点处需要设置媒体查询的容器数刚好在 .container-#{$breakpoint} 处停止。

使用 sass 描述如下:

@each $breakpoint, $container-max-width in $container-max-widths {
    /**
    * .container
    * .container-sm
    * .container-md
    * .container-lg
    * .container-xl
    * 按照断点设置媒体查询
    * 其实就是通过 max-width 控制容器到底有多宽
    */
    @include media-breakpoint-up($breakpoint, $grid-breakpoints) {
        // 每个断点的屏幕最大 width
        %responsitive-#{$breakpoint} {
            max-width: $container-max-width;
        }

        // 用于确定哪些容器需要设置媒体查询的 flag
        $extend-breakpoint: true;

        @each $name, $width in $grid-breakpoints {
            @if $extend-breakpoint {
                .container#{breakpoint-infix($name)} {
                    @extend %responsitive-#{$breakpoint};
            	}
        	}

        	@if $name == $breakpoint {
            $extend-breakpoint: false;
        	}
    	}


	}

}

其中两个辅助函数 breakpoint-min, breakpoint-infix:

/**
 * 根据断点名称取得对应的断点 width.
 * 注意:如果是 xs 断点,返回的是 null
 * @param $name:  传入的 map key
 * @param $breakpoints-map: 断点 map
 * @return: 断点对应的 mind-width
 */
@function breakpoint-min($name, $breakpoints-map: $grid-breakpoints) {
    $min: map-get($map: $breakpoints-map, $key: $name);
    @return if($min != 0, $min, null);
}

/**
 * 根据断点名称作为 key 查询map
 * 若是 map 中 key对应的 value 不为 0 则生成后缀名
 * 否则返回空串
 *
 * @param $name:  传入的 map key
 * @param $breakpoints-map: 断点 map
 * @return: 断点对应的后缀名 格式 '-sm'
 */
@function breakpoint-infix($name, $breakpoints-map: $grid-breakpoints) {
    @return if(breakpoint-min($name) != null, '-#{$name}', '');
}

辅助 mixin media-breakpoint-up

/**
 * 根据 $name 作为 key 查询 $breakpoints-map 中对应的断点值 
 * 如果断点值存在,则对相应内容设置媒体查询
 * 如果断点值不存在,则将混合的内容原样输出
 * 
 * @param $name 断点名称
 * @param $breakpoints-map 保存断点的 map
 */
@mixin media-breakpoint-up($name, $breakpoints-map: $grid-breakpoints) {
    $min: breakpoint-min($name, $breakpoints-map);

    @if $min {
        @media (min-width: $min) {
            @content;
        }
    }@else {
        @content;
    }
}

3. Row

栅格布局主要就是围绕 rowcolumn 展开。行中放置列,列中放置应用内容,列中又可以嵌套行(子子孙孙无穷尽也(x))。

行其实就是一个固定的容器,所以样式也很简单。

/**
 * 行基础样式
 * 开启 flex 布局
 * 允许多行容器
 * 左右有半个槽宽的负外边距
 * 
 * @param $gutter 槽宽
 */
@mixin make-row($gutter: $grid-gutter-width) {
  display: flex;
  flex-wrap: wrap;
  margin-right: -$gutter / 2;
  margin-left: -$gutter / 2;
}
// 行
.row {
    @include make-row();
}

4. Column

column 是栅格布局中最重要的部分,同时也是最复杂的一部分。

有多种列可供使用:

  • 等宽列 .col
    • 特点是 .row 中放置 n 个 .col, 那么一个 .col 的宽度就是 .row 的 n 分之一
  • 比例列 .col-${i}
    • $i 取值为 1- 12. bootstrap 默认情况下一行可以分作12列。 .col-{$i} 所占的宽度就是 row 总宽度的 $i / 12
    • 这里默认分成的列数对应变量是 $grid-columns: 12 !default;
  • 可变宽度的弹性列 .col-auto
    • 其所占据的宽度由其内容宽度决定

如果是在小屏幕下,我们通常不会让一行有很多列,通常一行都只有一列。所以根据不同的屏幕断点,bootstrap 还提供了响应式列。

  • 等宽列 .col-#{$breakpoint}
  • 比例列 .col-#{$breakpoint}-${i}
  • 可变宽度的弹性列 .col-#{$breakpoint}-auto

语义是,当屏幕大于等于断点对应宽度时,呈现列的语义形式。当小于断点宽度时,所有的列都退化成 width: 100%; 的形式。同样的,这也通过媒体查询实现.

4.1 列基础样式

所有列的最基础的样式:

/**
* 列基础样式
* 开启相对定位,作为列中内容绝对定位的参考点
* width 为 100%
* 左右有半个槽宽的外边距
*/
%grid-column {
    position: relative;
    width: 100%;
    padding-left: $gutter / 2;
    padding-right: $gutter / 2;
}

这个样式用于当屏幕小于对应断点的时候,列的样式进行退化

4.2 设置 .col, .col-${i}, .col-auto 的基础样式

$infix: breakpoint-infix($breakpoint, $breakpoints);

// .col-*-i 系列设置基础样式
@if $columns > 0 {
    @for $i from 1 through $columns {
        .col#{$infix}-#{$i} {
            @extend %grid-column;
    	}
	}
}

// .col-*, -col-*-auto 系列设置列基础样式
.col#{$infix},
.col#{$infix}-auto {
    @extend %grid-column;
}

我们这里以 $breakpoint: sm 为例,则 $infix: '-sm'。变量 $colums: 12 是默认的一行可以分为多少列.

执行完之后, .col-sm, .col-sm-#{$i}(i 取值 1-12), .col-sm-auto 它们的默认样式都设置成了 %grid-column。退化的基本样式就设置好了。

之后就开始设置媒体查询,以确定不同的列的样式。

因为此时的例子 $breakpoint: sm, 所以接下来的内容都会被编译进 @media(min-width: 576px) 中:

Article Forge
Article Forge

行业文案AI写作软件,可自动为特定主题或行业生成内容

下载

4.3 列样式设置

等宽列样式设置

flex:1 1 0; max-width: 100%。列可以等比例放大等比例缩小。初始行可用空间计算值是整个 main size。(如果不理解,可以去搜索 flex-basis: 0 代表什么含义)。这样的话,无论 .row 下放置多少个 .col-sm,每个 .col-sm 的宽度都是相等的。(前提是列能容纳得了内容)

.col-sm {
    flex-basis: 0;
    flex-grow: 1;
    max-width: 100%;
}

.row-cols#{$infix}-#{$i}

这个是 bootstrap 的特色类,这个类应用在 row 上。约束其下最多可以拥有多少个等宽列.这个类对于其他的列是不影响的,仅仅影响等宽列。(是通过选择器优先级实现的)

// 设置 .row-cols-*-i 系列 的样式
@if $grid-row-columns > 0 {
    @for $i from 1 through $grid-row-columns {
        .row-cols-sm-#{$i} {
            @include row-cols($i);
    	}
	}

}

辅助 mixin row-cols

/**
 * 设置 .row-col-*-i 系列下的列样式
 * flex: 0 0 100% / $count,即是一个不会放大不会缩小,永远按 i 的值等比例平分行的列
 * 
 * @param $count 要平分的列数
 */
@mixin row-cols($count) {
    & > * {
        flex: 0 0 100% / $count;
        max-width: 100% / $count;
    }
    
}

.row-cols-sm-1 > * 的选择器特殊性和 .col-sm 相同。但是前者声明在后者后面,所以造成了样式覆盖。即 .row-cols#{$infix}-#{$i} 只对等宽列起效。

严格的说,当使用对应断点的 .row-cols-#{$breakpoint}-#{$i} 之后,会对其下列中 .col-#{$breakpoint} 及断点之前的等宽列生效。即 .row-cols-md-4 会对 .col, .col-sm, .col-md 都生效。原因是因为整个循环顺序是从 xs -> xl。如果不明白,看一下编译输出的 CSS 就知道为什么了。

可变宽度弹性列样式设置 .col-sm-auto

// 设置 .col-*-auto 的样式
.col-sm-auto {
    @include make-col-auto();
}

辅助 mixin make-col-auto

/**
 * 设置 .col-*-auto 的样式
 * 默认情况下是一个不会放大不会缩小,宽度由 flex item 宽度决定的盒子
 */
@mixin make-col-auto() {
    flex: 0 0 auto;
    width: auto;
    max-width: 100%;
}

设置比例列样式 .col-sm-#{$i}

// 设置 .col-*-i 系列的样式
@if $columns > 0 {
    @for $i from 1 through $columns {
        .col-sm-#{$i} {
            @include make-col($i, $columns);
    	}
	}
}

辅助 mixin make-col

/**
 * .col-*-i 的样式
 * 
 * @param $size 占据的列数
 * @param $columns: 总可用列数
 */
@mixin make-col($size, $columns: $grid-columns) {
    flex: 0 0 percentage($size / $columns);
    max-width: percentage($size / $columns);
}

这里就是按比例分配,如果 $i: 5, 则 .col-sm-5 就占据整行宽度的 5/12

flex 布局中使用 order 属性来视觉排序 flex item.所以 bootstrap 也提供了列排序的类

// 列排序相关
.order-sm-first {
    order: -1;
}

.order-sm-last {
    order: $columns + 1;
}

// 一行最多12列,也就是说从 -1 开始编号就可以安排完整行所有的列排列顺序
@for $i from 0 through $columns {
    .order-sm-#{$i} {
        order: $i;
	}
}

只要明白浏览器视觉排序是按照 order 数值从小到大排序就能了解这个是干嘛的了。

列偏移

实际需求中,总是会有列偏移的需求,这里是通过 margin-left 实现。

// 设置列偏移
@if $columns > 0 {
    @for $i from 0 through ($columns - 1) {
        @if not ($infix == '' and $i == 0) {
            .offset#{$infix}-#{$i} {
                @include make-col-offset($i, $columns);
        	}
    	}
	}
}

辅助 mixin make-col-offset:

@mixin make-col-offset($size, $columns: $grid-columns) {
    $num: $size / $columns;
    margin-left: if($num == 0, 0, percentage($num));
}

整个创建响应式列的流程就是这样,这里只是举了断点为 sm 的情况,其他断点也是这个流程。就不一一赘述了,实际上实现也是通过循环。如果不需要响应式,只是需要等宽列,可变宽度弹性列,比例列的话就更简单了,我相信如果能理解上面的内容的话以读者的聪明才智可以很容易自己写出来。

5. 槽

槽(gutter) 是两列之间的间距。槽的数量是列数量 - 1.

槽公式:
设栅格行宽度为 w, 列宽度为 c(这里的列宽指内容区域), 槽宽度为 g, 列数为 n
则 w = n * c + (n - 1) * g

bootstarp 的设计是这样的:

1.png

  • container

    container 上左右分别有 1/2 gutterpadding

  • row

    row 上设置了 -1/2 gutter 的左右外边距将容器的 padding 影响抹平

  • column

    colum 上设置了 1/2 gutter 的左右外边距使得内容距离容器的边界有了 1/2 gutter 的距离。使得内容不贴边。

    同时允许列嵌套行,因为行的负外边距会将列的左右 padding 影响清除,可以达到无限套娃的目的。

    总之这个 gutter 的 大小因不同的设计而异, bootstrap 的默认 gutter 宽度为 30px,读者可以根据自己的设计目的调整。

6. 完整源码

完整源码移步 git 仓库(不是 bootstrap 完整版本,是个人重写加了注释的仅具有 grid 功能的版本。内容不多)

bootstrap-grid地址:https://github.com/IliyaRin/bootstrap-grid

更多编程相关知识,请访问:编程入门!!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

16

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

23

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

75

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

95

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

218

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

420

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

168

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

222

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

33

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

HTML+CSS基础与实战
HTML+CSS基础与实战

共132课时 | 12.5万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号