一套通用的响应式布局

发布时间:2021-04-27 14:49
最后更新:2021-04-27 14:49
所属分类:
前端 CSS

响应式布局通常都是使用@media媒体查询来完成,但是要实现每一套查询都需要编写大量重复的CSS代码,借用Less预处理器提供的函数功能,可以非常有效的将它们抽象出来。

公共函数代码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
.flex(@media) {
    display: flex;
    &.row-@{media} {
        flex-direction: row;
    }
    &.row-@{media}-inv {
        flex-direction: row-reverse;
    }
    &.col-@{media} {
        flex-direction: column;
    }
    &.col-@{media}-inv {
        flex-direction: column-reverse;
    }
    @main-axis-align: {
        start: flex-start;
        center: center;
        end: flex-end;
        space: space-around;
        even: space-evenly;
        between: space-between;
        baseline: baseline;
    }
    each(@main-axis-align, {
        &.rm-@{key}-@{media} {
            justify-content: @value;
        }
        &.cm-@{key}-@{media} {
            align-content: @value;
        }
    });
    @cross-axis-align: {
        start: flex-start;
        center: center;
        end: flex-end;
        stretch: stretch;
        baseline: baseline;
    }
    each(@cross-axis-align, {
        &.rc-@{key}-@{media} {
            align-items: @value;
        }
        .as-@{key}-@{media} {
            align-self: @value;
        }
    });
    each(range(1, 10), .(@i) {
        .extend-@{i}-@{media} {
            flex-grow: @i;
        }
        .shrink-@{i}-@{media} {
            flex-shrink: @i;
        }
    });
    @special-width: {
        min: min-content;
        max: max-content;
        fit: fit-content;
    };
    each(@special-width, {
        .w-@{key}-@{media} {
            width: @value;
        }
    });
    @basis-percent: 2, 3, 4, 5, 8, 10, 12, 16, 20, 24;
    each(@basis-percent, .(@max) {
        each(range(1, @max), .(@i) {
            .b-@{i}-@{max}-@{media} {
                // 如果应用在Lesscss 4中,这里需要改成:percentage((@i / @max)),
                // 因为Lesscss 4在数据计算上有了比较大的修改。
                flex-basis: percentage(@i / @max);
            }
            .w-@{i}-@{max}-@{media} {
                width: percentage(@i / @max);
            }
            .wmax-@{i}-@{max}-@{media} {
                max-width: percentage(@i / @max);
            }
            .wmin-@{i}-@{max}-@{media} {
                min-width: percentage(@i / @max);
            }
        });
    });
    each(range(0, 100), .(@i) {
        .w-@{i}p-@{media} {
            width: percentage(@i / @max);
        }
        .wmax-@{i}p-@{media} {
            max-width: percentage(@i / @max);
        }
        .wmin-@{i}p-@{media} {
            min-width: percentage(@i / @max);
        }
    };
    @wrap-modes: {
        none: nowrap;
        wrap: wrap;
        inv: wrap-reverse;
    }
    each(@wrap-modes, {
        &.w-@{key}-@{media} {
            flex-wrap: @value;
        }
    });
}

使用方法

假设上面这段Less代码存放在common.less文件里,那么可以构建出以下响应式样式定义。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@import "common.less";

/* 全局样式部分 */
.flex {
    .flex(a);
}

/* 小尺寸屏幕样式 */
@media screen and (max-width: 639px) {
    .flex {
        .flex(s);
    }
}

/* 中等尺寸屏幕样式 */
@media screen and (min-width: 640px) and (max-width: 959px) {
    .flex {
        .flex(m);
    }
}

/* 大尺寸屏幕样式 */
@media screen and (min-width: 960px) {
    .flex {
        .flex(l);
    }
}

HTML示例

下面通过一个简单的HTML示例,来说明这段响应式布局的使用。这个HTML示例可以达到小屏幕采用纵向排列,中等屏幕采用水平可换行排列,大屏幕采用水平不换行排列,所有元素均采用两端对齐。

1
2
3
4
5
6
7
8
<div class="flex col-n row-a w-wrap-m rm-between-a rc-center-a">
    <div class="squre w-2-2-n w-1-3-m w-2-12-l">Squre 1</div>
    <div class="squre w-2-2-n w-1-3-m w-2-12-l">Squre 2</div>
    <div class="squre w-2-2-n w-1-3-m w-2-12-l">Squre 3</div>
    <div class="squre w-2-2-n w-1-3-m w-2-12-l">Squre 4</div>
    <div class="squre w-2-2-n w-1-3-m w-2-12-l">Squre 5</div>
    <div class="squre w-2-2-n w-1-3-m w-2-12-l">Squre 6</div>
</div>

索引标签
前端
CSS
Less
响应式布局
Responsive
Flex