使用相同的 css 布局,但适用于不同尺寸的媒体

Using the same css layout but for differently sized media

我使用 CSS 网格和 Sass,并且我针对不同的屏幕尺寸(phonetabletdesktop)使用不同的网格布局。但对于某些页面,我想要相同的布局,但选择的屏幕比其他页面稍大或稍小。

这样的事情可能吗?还是我从错误的角度接近它?我当前的解决方案(见下文)有效,但样式重复很多。

更详细:

我根据屏幕尺寸选择了 3 个不同的网格。

.hero {
    &__container {
        grid-template-areas:
            "header"
            "image"
            "text";
        }
        @media min-width: 1000px {
            grid-template-areas:
                "header header header"
                "text   ...     image"
                "text   ...     image";
            }
            // other definitions for this screen size
        }
        @media min-width: 1300px {
            grid-template-areas:
                "header header image"
                "text   ...    image"
                "text   ...    image";
            }
            // other definitions for this screen size
        }
    }

  &__header {
    grid-area: header;
    font-size: 2.5rem;
    
    @media min-width: 1000px {
        font-size: 2.8rem;
    }
    @media min-width: 1300px {
        font-size: 3.2rem;
    }
  }
  ...
}

它们被用于大约 20 个类似的网页。

<div class="page_a">
    <div class="hero">
        <div class="hero__container">
            <div class="hero__header">...</div>
            <div class="hero__text">...</div>
            <div class="hero__image">...</div>
        </div>
    </div>
</div>

布局非常相似,但我想根据内容的具体情况在不同的点切换到不同的布局:header 文本长度、图像的大小和重要性等.

我想做的是这样的:

.page_a {
    .hero {
        // redefine nothing, use defaults
    }
}

.page_c {
    .hero {
        // the header is longer so we need a bigger screen to switch to the biggest layout 
        // somehow say that the 1300px layout should be used from 1500px
    }
}

我唯一能做的就是在每个可能的点(默认点+自定义点)简单地重新定义所有网格,这意味着代码非常重复:

.page_c {
    .hero {
        // use 1000px layout also for 1300px - the whole thing has to be repeated
        @media min-width: 1300px {
            grid-template-areas:
                "header header header"
                "text   ...     image"
                "text   ...     image";
            }
            // other definitions for this size
        }
        // use 1300px layout for 1500px - the whole thing has to be repeated
        @media min-width: 1500px {
            grid-template-areas:
                "header header image"
                "text   ...    image"
                "text   ...    image";
            }
            // other definitions for this size
        }
    }
}

这意味着每次我更改一些布局时,我都必须去所有使用它的地方以各种尺寸进行更改。

给你...


您的问题可以用 SASS 或 SCSS 解决,更准确地说是 @mixin。我正在使用 SCSS 因为我更熟悉它,但你也可以使用 SASS.

什么是@mixin?

如 SASS 官方 website 所述:Mixins 允许您定义可在整个样式表中重复使用的样式。 首先定义一个@mixin 然后您稍后在您的代码中使用 @include 调用它。每个 @mixin 都应该有一个唯一的名字。例如:定义一个 @mixin layout_600 并用 @include layout_600.

调用它

定义 @mixin 时有两点很重要:

  1. A @mixin 应该定义 你用 @include 调用它之前。否则,SCSS 将尝试调用尚未定义的内容(已定义但稍后在您的样式表中)。
  2. A @mixin 应该定义在嵌套代码的外部(最好在样式表的顶部)。如果您在嵌套代码中定义了一个 @mixin ,您将无法在以后想要更改默认样式时调用它。让你明白我的意思的最简单方法就是告诉你正确的方法和错误的方法。

正确:

@mixin layout_600 {
    font-size: 3rem;
    color: blue;
    font-weight: 700;
}

.hero {
    &__header {
        @media (min-width: 600px) {
            @include layout_600;
        }
    }
}

.page_b {
    .hero {
        // Use the 600px layout also for the 1000px.
        &__header {
            @media (min-width: 1000px) {
                // It will work.
                @include layout_600;
            }
        }
    }
}

错误:

.hero {
    &__header {
        @media (min-width: 600px) {
            @mixin layout_600 {
                font-size: 3rem;
                color: blue;
                font-weight: 700;
            }
        }
    }
}

.page_b {
    .hero {
        // Use the 600px layout also for the 1000px.
        &__header {
            @media (min-width: 1000px) {
                // It won't work.
                @include layout_600;
            }
        }
    }
}

您需要为每个想要的布局(例如 600px、1000px)写一个 @mixin。您只需为每个布局执行一次,但您可以调用特定的 @mixin n 次。这是完美的,因为:

  • 您不必重写代码,您只需使用 @include 多次调用特定的 @mixin
  • 如果你想改变你的样式,你只需在你的 @mixin 中做一次,并且样式将在引用此 @mixin 的每个地方更改。

工作示例


更改默认样式之前

我这样定义了三个 @mixin

  • 当:window 宽度 < 600px,
  • 当:600px < window 宽度 < 1000px 并且
  • 当:window 宽度 > 1000px。

如您所见,font-sizecolor 在不同的 window 宽度处是不同的。随着 window 越来越宽,字体越来越大,颜色从黑色变为蓝色再变为红色。顺便说一句,在右上角我添加了一个div,显示当前window宽度。

Here's a live demo before changing the default style.


更改默认样式后

我决定为 page_b 使用 600px 布局(即 @mixin layout_600),也为 1000px 使用 600px 布局(即 @mixin layout_600)。这可以通过使用 @include layout_600 调用 @mixin layout_600 来轻松完成,如下所示:

.page_b {
    .hero {
        // Use the 600px layout also for the 1000px.
        &__header {
            @media (min-width: 1000px) {
                @include layout_600;
            }
        }
    }
}

如你所见,当 window 宽度实际为 1000px 时 page_b 的样式与 window 宽度为 600px 时的样式相同(较小的字体和蓝色) .

Here's a live demo after changing the default style.


自定义一个@mixin

此外,如果需要,可以自定义 @mixin。例如,我使用 600px 布局(即 @mixin layout_600),但将 color 从红色更改为绿色。可以这样做:

.page_b {
    .hero {
        // Use the 600px layout also for the 1000px.
        &__header {
            @media (min-width: 1000px) {
                @include layout_600;
                color: green; // Customize the mixin.
            }
        }
    }
}

如您所见,color 应该是蓝色的(如 @mixin layout_600),但它是绿色的。

Here's a live demo after customizing a @mixin.