156 lines
3.7 KiB
Markdown
156 lines
3.7 KiB
Markdown
---
|
||
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>
|
||
``` |