让段落的font-size根据响应式的断点保持一定的轨道(track),从h1到h6为每个断点给字体大小设置一个变量,如此把事情变得更加繁琐,特别当类型不在一个线性比例上时。
如果你试图在响应式中解决这样的排版,下面的代码看起来非常的熟悉:
p { font-size: 15px; }
@media screen and (min-) {
p { font-size: 16px; }
}
@media screen and (min-) {
p { font-size: 17px; }
}
@media screen and (min-) {
p { font-size: 19px; }
}
Sass的变量能在一个项目中得到很好的重用,但用于管理响应式排版中的字体大小时就得非常的鸡肋:
$p-font-size-mobile : 15px;
$p-font-size-small : 16px;
$p-font-size-medium : 17px;
$p-font-size-large : 19px;
$h1-font-size-mobile: 28px;
$h1-font-size-small : 31px;
$h1-font-size-medium: 33px;
$h1-font-size-large : 36px;
// 我认为你是明白的…
这里演示了Sass的Map和循环的强大之处: 他们能帮助我们更好的理管z-index的值,颜色,不一会你将看到他们帮助我们更好的管理字体大小。
使用Sass Maps管理字体大小
根据Sass Map的key-value关系创建一个Sass Map。将断点设置为key,将字体大小设置为对应key的value:
$p-font-sizes: (
null : 15px,
480px : 16px,
640px : 17px,
1024px: 19px
);
记住移动先行(Mobile-first),我们看到第一个断点的key设置为null,表示默认的字体大小(不是媒体查询),并且按断点的升序排列。
接下来创建一个mixin,遍历Sass map中的key,并生成适当的媒体查询。
@mixin font-size($fs-map) {
@each $fs-breakpoint, $fs-font-size in $fs-map {
@if $fs-breakpoint == null {
font-size: $fs-font-size;
}
@else {
@media screen and (min-width: $fs-breakpoint) {
font-size: $fs-font-size;
}
}
}
}
注意:这是一个mixin,值得一提的是,Sass具有编程逻辑特性,Sass借助SassScript的扩展,可以在Sass中使用一些基本的编程结构,比如@if/@else、@for和@each等逻辑控制命令。我建议您花一些时间去阅读相关文档。Sass的特性中介绍了一些Sass的新特性,了解一些Sass可以做哪些事情。
现在我们可以要段落中调用前面声明的混合宏:
p {
@include font-size($p-font-sizes);
}
编译出来的CSS:
p { font-size: 15px; }
@media screen and (min-) {
p { font-size: 16px; }
}
@media screen and (min-) {
p { font-size: 17px; }
}
@media screen and (min-) {
p { font-size: 19px; }
}
管理和跟踪元素的字体大小变得容易多。对于新元素增加,只需要创建一个新的Sass Map和选择器中调用混合宏:
$h1-font-sizes: (
null : 28px,
480px : 31px,
640px : 33px,
1024px: 36px
);
h1 {
@include font-size($h1-font-sizes);
}
编译出来的CSS:
h1 {
font-size: 28px;
}
@media screen and (min-) {
h1 {
font-size: 31px;
}
}
@media screen and (min-) {
h1 {
font-size: 33px;
}
}
@media screen and (min-) {
h1 {
font-size: 36px;
}
}
字体大小一致的元素可以这样调用:
p, ul, ol {
@include font-size($p-font-sizes);
}
编译出来的CSS:
p, ul, ol {
font-size: 15px;
}
@media screen and (min-) {
p, ul, ol {
font-size: 16px;
}
}
@media screen and (min-) {
p, ul, ol {
font-size: 17px;
}
}
Sass
// ----
// libsass (v3.2.5)
// ----
$p-font-sizes: (
null : 15px,
480px : 16px,
640px : 17px,
1024px: 19px
);
$h1-font-sizes: (
null : 28px,
480px : 31px,
640px : 33px,
1024px: 36px
);
@mixin font-size($fs-map) {
@each $fs-breakpoint, $fs-font-size in $fs-map {
@if $fs-breakpoint == null {
font-size: $fs-font-size;
}
@else {
@media screen and (min-width: $fs-breakpoint) {
font-size: $fs-font-size;
}
}
}
}
h1 {
@include font-size($h1-font-sizes);
}
p, ul, ol {
@include font-size($p-font-sizes);
}
CSS
h1 {
font-size: 28px;
}
@media screen and (min-) {
h1 {
font-size: 31px;
}
}
@media screen and (min-) {
h1 {
font-size: 33px;
}
}
@media screen and (min-) {
h1 {
font-size: 36px;
}
}
p, ul, ol {
font-size: 15px;
}
@media screen and (min-) {
p, ul, ol {
font-size: 16px;
}
}
@media screen and (min-) {
p, ul, ol {
font-size: 17px;
}
}
@media screen and (min-) {
p, ul, ol {
font-size: 19px;
}
}
解决断点分段
等等,新问题又来了。如果我们想要的段落p的字体大小为17px和h1标题的字体大小为33px,而断点是700px,不是640px。如果使用上面的解决方案,需要在每个实例中更改断点640px。我们试图解决这个问题,无意之中创建了另一个:断点分段。
试想一下,我们可以使用Sass Map来管理字体大小,是不是可以使用Sass Map来管理断点,对吗?完全正确!
给常见的断点创建一个Sass Map,并且给每个值取一个适当的名称。我们也会改为font-size的Map中断点名称(key的名称),名称和断点Map $breakpoints相匹配。
$breakpoints: (
small : 480px,
medium: 700px, // Previously 640px
large : 1024px
);
$p-font-sizes: (
null : 15px,
small : 16px,
medium: 17px,
large : 19px
);
$h1-font-sizes: (
null : 28px
small : 31px,
medium: 33px,
large : 36px
);
最后一步是调整mixin,通过断点的名称映射到字体断点,并且遍历整个map,取到适当的值:
@mixin font-size($fs-map, $fs-breakpoints: $breakpoints) {
@each $fs-breakpoint, $fs-font-size in $fs-map {
@if $fs-breakpoint == null {
font-size: $fs-font-size;
}
@else {
// If $fs-font-size is a key that exists in
// $fs-breakpoints, use the value
@if map-has-key($fs-breakpoints, $fs-breakpoint) {
$fs-breakpoint: map-get($fs-breakpoints, $fs-breakpoint);
}
@media screen and (min-width: $fs-breakpoint) {
font-size: $fs-font-size;
}
}
}
}
注意:mixin中默认的断点Map是$breakpoints。如果你的断点变量名不同,一定要在参数中修改成你需要的断点变量名。
瞧!现在,我们要想给元素添加一个新的断点中字体字体大小,而且这个断点在$breakpoints中并不存在。只需要在字体大小的map中设置,只需要把需要的断点设置为一个key,并且设置对应的font-size值。那么mixin将这样工作:
$p-font-sizes: (
null : 15px,
small : 16px,
medium: 17px,
900px : 18px,
large : 19px,
1440px: 20px,
);
p {
@include font-size($p-font-sizes);
}
在mixin中Sass的map-has-key函数起到很强大的作用。他会检查Map的key的值是否在$breakpoints中,如果存在,它将使用key的值;如果不存在,它会认为key是一个定制的key,并且会使用这个定制key的值生成媒体查询。
p { font-size: 15px; }
@media screen and (min-) {
p { font-size: 16px; }
}
@media screen and (min-) {
p { font-size: 17px; }
}
@media screen and (min-) {
p { font-size: 18px; }
}
@media screen and (min-) {
p { font-size: 19px; }
}
@media screen and (min-) {
p { font-size: 20px; }
}
Sass
// ----
// libsass (v3.2.5)
// ----
$breakpoints: (
small : 480px,
medium: 700px, // Previously 640px
large : 1024px
);
$p-font-sizes: (
null : 15px,
small : 16px,
medium: 17px,
900px : 18px,
large : 19px,
1440px: 20px,
);
$h1-font-sizes: (
null : 28px,
small : 31px,
medium: 33px,
large : 36px
);
@mixin font-size($fs-map, $fs-breakpoints: $breakpoints) {
@each $fs-breakpoint, $fs-font-size in $fs-map {
@if $fs-breakpoint == null {
font-size: $fs-font-size;
}
@else {
// If $fs-font-size is a key that exists in
// $fs-breakpoints, use the value
@if map-has-key($fs-breakpoints, $fs-breakpoint) {
$fs-breakpoint: map-get($fs-breakpoints, $fs-breakpoint);
}
@media screen and (min-width: $fs-breakpoint) {
font-size: $fs-font-size;
}
}
}
}
p {
@include font-size($p-font-sizes);
}
CSS
p {
font-size: 15px;
}
@media screen and (min-) {
p {
font-size: 16px;
}
}
@media screen and (min-) {
p {
font-size: 17px;
}
}
@media screen and (min-) {
p {
font-size: 18px;
}
}
@media screen and (min-) {
p {
font-size: 19px;
}
}
@media screen and (min-) {
p {
font-size: 20px;
}
}
使用line-height来控制Vertical Rhythm
line-height对于实现Vertical Rhythm来说是一个很重要的参数。所以,我们提供一个line-height的解决方案,来解决Vertical Rhythm。
扩展font-size的map,在里面增加line-height。这里使用了Sass的list:
$breakpoints: (
small : 480px,
medium: 700px,
large : 1024px
);
$p-font-sizes: (
null : (15px, 1.3),
small : 16px,
medium: (17px, 1.4),
900px : 18px,
large : (19px, 1.45),
1440px: 20px,
);
注意:line-height值可以使用任何有效的CSS单位来定义(%、px、em等),不过更建议使用不带任何单位来定义line-height,用来避免继承造成意想不到的结果。
然后,修改mixin,生成包括line-height的CSS:
@mixin font-size($fs-map, $fs-breakpoints: $breakpoints) {
@each $fs-breakpoint, $fs-font-size in $fs-map {
@if $fs-breakpoint == null {
@include make-font-size($fs-font-size);
}
@else {
// If $fs-font-size is a key that exists in
// $fs-breakpoints, use the value
@if map-has-key($fs-breakpoints, $fs-breakpoint) {
$fs-breakpoint: map-get($fs-breakpoints, $fs-breakpoint);
}
@media screen and (min-width: $fs-breakpoint) {
@include make-font-size($fs-font-size);
}
}
}
}
// Utility function for mixin font-size
@mixin make-font-size($fs-font-size) {
// If $fs-font-size is a list, include
// both font-size and line-height
@if type-of($fs-font-size) == "list" {
font-size: nth($fs-font-size, 1);
@if (length($fs-font-size) > 1) {
line-height: nth($fs-font-size, 2);
}
}
@else {
font-size: $fs-font-size;
}
}
mixin检查font-sizeMap中的值是不是一个列表。如果是一个列表,通过nth()函数索引出需要的值。理论上第一个值是字体大小,第二个是行高的值。我们来看看效果:
p {
@include font-size($p-font-sizes);
}
编译出来的CSS:
p {
font-size: 15px;
line-height: 1.3;
}
@media screen and (min-) {
p {
font-size: 16px;
}
}
@media screen and (min-) {
p {
font-size: 17px;
line-height: 1.4;
}
}
@media screen and (min-) {
p {
font-size: 18px;
}
}
@media screen and (min-) {
p {
font-size: 19px;
line-height: 1.45;
}
}
@media screen and (min-) {
p {
font-size: 20px;
}
}
Sass
// ----
// libsass (v3.2.5)
// ----
$breakpoints: (
small : 480px,
medium: 700px,
large : 1024px
);
$p-font-sizes: (
null : (15px, 1.3),
small : 16px,
medium: (17px, 1.4),
900px : 18px,
large : (19px, 1.45),
1440px: 20px,
);
@mixin font-size($fs-map, $fs-breakpoints: $breakpoints) {
@each $fs-breakpoint, $fs-font-size in $fs-map {
@if $fs-breakpoint == null {
@include make-font-size($fs-font-size);
}
@else {
// If $fs-font-size is a key that exists in
// $fs-breakpoints, use the value
@if map-has-key($fs-breakpoints, $fs-breakpoint) {
$fs-breakpoint: map-get($fs-breakpoints, $fs-breakpoint);
}
@media screen and (min-width: $fs-breakpoint) {
@include make-font-size($fs-font-size);
}
}
}
}
// Utility function for mixin font-size
@mixin make-font-size($fs-font-size) {
// If $fs-font-size is a list, include
// both font-size and line-height
@if type-of($fs-font-size) == "list" {
font-size: nth($fs-font-size, 1);
@if (length($fs-font-size) > 1) {
line-height: nth($fs-font-size, 2);
}
}
@else {
font-size: $fs-font-size;
}
}
p {
@include font-size($p-font-sizes);
}
CSS
p {
font-size: 15px;
line-height: 1.3;
}
@media screen and (min-) {
p {
font-size: 16px;
}
}
@media screen and (min-) {
p {
font-size: 17px;
line-height: 1.4;
}
}
@media screen and (min-) {
p {
font-size: 18px;
}
}
@media screen and (min-) {
p {
font-size: 19px;
line-height: 1.45;
}
}
@media screen and (min-) {
p {
font-size: 20px;
}
}
最后的解决方案是可易扩展,可以适应其他属性的加入,比如font-weight、margin等属性。关键是要修改make-font-size这个混合宏,并且通过nth()函数从列表中索引出相匹配的值。
结语
处理响应式排版和Vertical Rhythm的方法有很多,然而,这是我很多次工作中总结出来的经验之谈。
我最强舞者 (I, Best Dancer)安卓版v8
我最强舞者(I, Best Dancer)是一款休闲放置类手
迷你世界国服版本2024 v1.43.0
迷你世界国服版本2024是一款自由度非常高的沙盒游戏,玩法和
烹饪乐园 安卓版v1.23.6
烹饪乐园(Cooking Town)是一款非常好玩的餐厅模拟
迷你世界小米服 最新安卓版v1.43.0
迷你世界小米版是由迷你玩科技开发的休闲模拟经营类游戏。此版本
布娃娃Sprunki沙盒 安卓版v0.0.1
布娃娃Sprunki沙盒是一个非常有趣的沙盒游戏,复古简约的