blog/source/_posts/responsive-flex.md
2021-04-27 14:55:08 +08:00

156 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 一套通用的响应式布局
tags:
- 前端
- CSS
- Less
- 响应式布局
- Responsive
- Flex
categories:
- - 前端
- CSS
date: 2021-04-27 14:49:29
---
响应式布局通常都是使用`@media`媒体查询来完成但是要实现每一套查询都需要编写大量重复的CSS代码借用Less预处理器提供的函数功能可以非常有效的将它们抽象出来。<!--more-->
## 公共函数代码
```less 公共布局函数
.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} {
flex-basis: percentage(@i / @max);
}
.w-@{i}-@{max}-@{media} {
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`文件里,那么可以构建出以下响应式样式定义。
```less 响应式样式定义
@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示例可以达到小屏幕采用纵向排列中等屏幕采用水平可换行排列大屏幕采用水平不换行排列所有元素均采用两端对齐。
```html 响应式布局示例
<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>
```