>  기사  >  웹 프론트엔드  >  BootStrap이 그리드 레이아웃을 구현하는 방법에 대한 간략한 설명

BootStrap이 그리드 레이아웃을 구현하는 방법에 대한 간략한 설명

青灯夜游
青灯夜游앞으로
2021-06-01 11:37:424496검색

이 글에서는 BootStrap그리드 레이아웃 구현 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

BootStrap이 그리드 레이아웃을 구현하는 방법에 대한 간략한 설명

【관련 추천: "부트스트랩 튜토리얼"】

1. 기본 포인트

box-sizing: border-boxbox-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

이것이 가장 기본적인 포인트입니다. 상자 모델은 테두리 상자로 설정됩니다. 이러한 방식으로 너비 속성으로 지정된 상자의 너비에는 테두리 + 패딩 + 내용이 포함됩니다. 너비가 고정되어 있는 한 패딩테두리를 지정해도 상자 크기는 변경되지 않습니다.

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

  • Sass 기본
  • 부트스트랩 그리드 레이아웃 기본
  • Flex 레이아웃 기본
이 기사 그리드 그리드 구현은 부트스트랩 소스 코드 구현을 의미합니다

2. 컨테이너
  • 반응형 컨테이너
    • .container
    • .container-sm
    • .container-md
    • .container-lg
    • .container-xl
    li>고정 너비 컨테이너(부트스트랩에서는 유체 컨테이너라고 함)
    • .container-fluid
컨테이너 기본 데이터xs >=992px720px720px960px960px100% 100%

일반적으로 애플리케이션의 최상위 컨테이너는 두 가지 유형으로 나뉩니다.
반응형 컨테이너는 화면 너비에 따라 max-width를 사용하여 미디어 쿼리에 따라 컨테이너 너비를 제한합니다. 부트스트랩의 모바일 우선 원칙으로 인해 작은 화면의 컨테이너 스타일이 먼저 충족되고 미디어 쿼리를 기반으로 큰 화면의 스타일이 확장됩니다.
xl >=1200px .container 100% 540px
960px 1140px .container-sm 100% 540px
960px 1140px . % 100% 720px
1140px .container-lg 100% 100% 100%
1140px .container-xl 100% 100% 100%
1140px .container-fluid 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) 中:

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 的设计是这样的:

BootStrap이 그리드 레이아웃을 구현하는 방법에 대한 간략한 설명

  • 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

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

위 내용은 BootStrap이 그리드 레이아웃을 구현하는 방법에 대한 간략한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제