汕头网站建设:响应式排版与Sass地图

2019.08.12 mf_web

66

管理一致的排版节奏并不容易,但是当类型响应时,事情变得更加困难。幸运的是,Sass地图使响应式排版更易于管理。

编写代码是一回事,但是跟踪每个断点的字体大小值是另一个 - 而上面仅针对段落。扔在h1向h6s,各具有可变的字体大小对于每个断点,它得到麻烦,特别是当类型不呈线性比例。汕头网站建设

如果你试图解决响应类型,这可能看起来很熟悉:

p { font-size: 15px; }@media screen and (min-width: 480px) {
  p { font-size: 16px; }}@media screen and (min-width: 640px) {
  p { font-size: 17px; }}@media screen and (min-width: 1024px) {
  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;// I think you get the point…
复制

这就是Sass地图和循环功能强大的地方:它们帮助我管理z-index值,颜色,以及稍后你会看到的字体大小。

使用Sass地图组织字体大小

让我们首先创建一个带键值对的Sass映射 - 断点为键,字体大小为对应值。

$p-font-sizes: (
  null  : 15px,
  480px : 16px,
  640px : 17px,
  1024px: 19px);
复制

首先考虑移动设备,我们看到密钥null代表默认字体大小(不在媒体查询中),并且断点按升序排列。

接下来,mixin,遍历Sass映射并生成适当的媒体查询。

@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以及要遵循的mixin具有一些基本的编程逻辑。Sass在SassScript(一组扩展版本)的帮助下,使基本的编程结构成为可能,比如if/ elsestatements,each循环和更多。我鼓励您花一些时间阅读文档。Sass的“强大功能”将为您介绍使用Sass可以做的事情的新维度。

然后我们将mixin用于段落:

p {
  @include font-size($p-font-sizes);}
复制

...导致以下CSS:

p { font-size: 15px; }@media screen and (min-width: 480px) {
  p { font-size: 16px; }}@media screen and (min-width: 640px) {
  p { font-size: 17px; }}@media screen and (min-width: 1024px) {
  p { font-size: 19px; }}
复制

管理和跟踪元素的字体大小变得更加容易!使用每个新元素,创建一个地图并在适当的选择器中调用mixin。

$h1-font-sizes: (
  null  : 28px  480px : 31px,
  640px : 33px,
  1024px: 36px);h1 {
  @include font-size($h1-font-sizes);}
复制

保持各种元素的字体大小一致:

p, ul, ol {
  @include font-size($p-font-sizes);}
复制

解决断点碎片

可是等等!如果我们决定我们希望ps 的字体大小为17像素,并且h1s在700像素的断点处为33像素而不是640像素,该怎么办?使用上面的解决方案,需要手动更改每个实例640px。通过尝试解决一个问题,我们无意中创建了另一个问题:断点碎片。

如果我们可以在Sass地图中管理字体大小,我们肯定可以使用断点来做同样的事情,对吧?究竟!

让我们为常见断点创建一个映射,并为每个值分配一个合适的名称。我们还将使用我们分配的断点名称来更改字体大小映射,$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,以便在迭代字体大小映射时,它将使用断点名称从$breakpoints生成媒体查询之前获取适当的值。

@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的默认断点映射是$breakpoints; 如果断点变量的名称不同,请务必在第1行的第二个参数中更改它。

瞧!现在,如果我们想要一个元素具有不存在的自定义断点的字体大小,该$breakpoints怎么办?在font-sizes映射中,只需输入断点值而不是名称作为键,mixin将为您完成工作:

$p-font-sizes: (
  null  : 15px,
  small : 16px,
  medium: 17px,
  900px : 18px,
  large : 19px,
  1440px: 20px,);p {
  @include font-size($p-font-sizes);}
复制

由于Sass的map-has-key功能,魔法发生在mixin中。它检查密钥名称是否存在于$breakpoints:如果存在,它将使用密钥的值; 如果没有,它将假设密钥是自定义值,并在生成媒体查询时使用它。

p { font-size: 15px; }@media screen and (min-width: 480px) {
  p { font-size: 16px; }}@media screen and (min-width: 700px) {
  p { font-size: 17px; }}@media screen and (min-width: 900px) {
  p { font-size: 18px; }}@media screen and (min-width: 1024px) {
  p { font-size: 19px; }}@media screen and (min-width: 1440px) {
  p { font-size: 20px; }}
复制

用线高度改善垂直节奏

线高也是实现一致垂直节奏的重要部分。因此,在不过分的情况下,让我们在解决方案中包含行高。

通过在列表中包含字体大小和行高度作为所需键的值来扩展字体大小映射:

$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,);
复制

注意:虽然行高值可使用任何有效的CSS单元(百分比,像素,EMS等)来定义的,“无单位”值被推荐和优选的,以避免由于继承意外的结果。

然后,我们需要在生成CSS时修改mixin以包括行高。

@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-sizes映射中键的值是否是列表而不是font-size值。如果它是一个列表,那么它在nth函数的帮助下通过索引值从列表中获取正确的值。它假定第一个值是字体大小,第二个值是行高。让我们看看它的实际效果:

p {
  @include font-size($p-font-sizes);}
复制

这是最终的CSS:

p { font-size: 15px; line-height: 1.3; }@media screen and (min-width: 480px) {
  p { font-size: 16px; }}@media screen and (min-width: 700px) {
  p { font-size: 17px; line-height: 1.4; }}@media screen and (min-width: 900px) {
  p { font-size: 18px; }}@media screen and (min-width: 1024px) {
  p { font-size: 19px; line-height: 1.45; }}@media screen and (min-width: 1440px) {
  p { font-size: 20px; }}
复制

这个最终解决方案很容易扩展,以适应许多其他属性,如字体粗细,边距等。关键是修改make-font-size实用程序mixin并使用该nth函数从列表中获取适当的值。

结论

有各种方法来处理响应式排版和一致的垂直节奏,它们不仅限于我的建议。但是,我发现这对我有用的次数比不多。

使用此mixin可能会在编译的CSS中生成重复的媒体查询。关于重复媒体查询与分组媒体查询,使用@extend而不是mixins,以及性能和文件大小,已经有很多讨论; 然而,测试得出的结论是“差异,虽然丑陋,但在最坏情况下是最小的,基本上不存在。”

我也意识到我的解决方案并不健壮(它不是为处理媒体查询范围max-width或视口方向而设计的)。这些功能可以在mixin中实现(我的个人版本也将像素值转换为ems),但对于复杂的媒体查询,我更喜欢手工编写。不要忘记您可以使用该map-get函数从现有地图中检索值。

汕头网站建设

最新案例

寒枫总监

来电咨询

400-6065-301

微信咨询

寒枫总监

TOP