【问题标题】:LESS CSS retina media queries without redundancyLESS CSS 视网膜媒体查询,没有冗余
【发布时间】:2023-03-08 04:09:01
【问题描述】:

我正在使用基于组件的 CSS 样式,因此我一直在使用 mixins 来允许我使用媒体查询,而不会意外编译数百个。这就是我对屏幕尺寸所做的:

主文件:

.mq-medium() {}

@import //other files

@media only screen and (min-width: 600px) {
  .mq-medium;
}

另一个文件:

.mq-medium() {
  .banner {
    width: 50%;
  }
}

这可以多次使用并导致分组查询。

问题

我正在尝试对视网膜背景图像查询做同样的事情,但我无法弄清楚如何去做。这是我的测试:

.mq-retina() { }

.background-image(@image){
  @filename:  ~`/(.*)\.(jpg|jpeg|png|gif)/.exec(@{image})[1]`;
  @extension: ~`/(.*)\.(jpg|jpeg|png|gif)/.exec(@{image})[2]`;
  background-image: ~`"url(@{filename}.@{extension})"`;
  .mq-retina() {
    & {
      background-image: ~`"url(@{filename}_2x.@{extension})"`;
      background-size: 100%;
    }
  }
}

.lol {
  .background-image("test.jpg");
}

@media only screen and (min-device-pixel-ratio: 1.5) { //shortened for this example
  .mq-retina;
}

但输出只是

.lol {
  background-image: url(test.jpg);
}

我认为这与范围界定问题有关,但不确定如何解决。如何添加到 .mq-retina() mixin 而不会出现范围界定问题?

【问题讨论】:

  • 嗯,是的,当然.mq-retina 定义在.background-image 中的mixin 在全局范围内是不可见的(因此在媒体块中,就像您尝试调用它一样)。将媒体移动到 mixin 或 .lol 或相反将 mixin 移动到全局范围。 (还有一个建议是减少内联javascript滥用,最后还有replace函数。至少不要这样做~`"url(@{filename}.@{extension})"`;这真的很奇怪)。
  • 我打算先修改那部分;我是从网上某处得到的,只是在测试它是否有效。不过,这仍然不能解决我的问题——我的目标是拥有一个媒体查询并自动将每个背景图像定义添加到其中,而不必每次都专门编写它。这可能是不可能的,但我想我会在注销之前先问一下。
  • 好的,现在我想我知道你需要什么了——简而言之,不,这是不可能的(或者更严格地说是可能的,但代价是相当冗长的更少代码)。问题是,由于您需要在不同的媒体查询中放入不同的规则集,因此您必须以一种或另一种方式重复这些方法,而 mixin 在这里无济于事,因为您无法创建会暴露其 的 mixin外部 东西颠倒了(因为mixin 内容在被调用而不是在其定义时被扩展,即.background-image("test.jpg"); inside .lol can't create global .mq-retina() with .lol inside)。

标签: css less media-queries


【解决方案1】:

(有关此解决方案的上下文,请参见上面的 cmets)。 我想说非重复媒体查询的代价总是“重复其他东西”。 IE。它要么必须是媒体依赖的属性,如:

// ...................................
// usage:

.mq-default() {
    .banner {
        .background-image("test.jpg");
    }
}

.mq-retina() {
    .banner {
        .background-image("test.jpg");
    }
}

// ...................................
// impl:

.mq-default() {}
.mq-retina()  {}

& {
    .mq-default;

    .background-image(@image) {
        background-image: @image;
    }
}

@media (min-device-pixel-ratio: 1.5) {
    .mq-retina;

    .background-image(@image) {
        background-image: replace(@image, "\.", "_2x.");
        background-size: 100%;
    }
}

或者媒体依赖的选择器本身,如:

// ...................................
// usage:

.background-image(banner, "test.jpg");

// ...................................
// impl:

.mq-retina() {}

@media (min-device-pixel-ratio: 1.5) {
    .mq-retina;
}

.background-image(@class, @image) {
    .@{class} {
        background-image: @image;
    }

    .mq-retina() {
        .@{class} {
            background-image: replace(@image, "\.", "_2x.");
            background-size: 100%;
        }
    }
}

---

附:对于这种简化的情况,也可以修改第一个示例以消除重复,例如:

// ...................................
// usage:

.mq-common() {
    .banner {
        .background-image("test.jpg");
    }
}

// ...................................
// impl:

.mq-default() {.mq-common}
.mq-retina()  {.mq-common}

& {
    .mq-default;

    .background-image(@image) {
        background-image: @image;
    }
}

@media (min-device-pixel-ratio: 1.5) {
    .mq-retina;

    .background-image(@image) {
        background-image: replace(@image, "\.", "_2x.");
        background-size: 100%;
    }
}

但这样它实际上变成了第二个示例的变体(更复杂的代码将导致生成的 CSS 中出现重复的选择器,因为您不想将所有属性都放入 .mq-common),这不算整个事情也变得令人头疼。

---

附言最后,终于可以通过引入另一个间接级别来整合“一切”(在生成的 CSS 中),但是源代码本身变得过于冗长而无法在实践中实际使用。 (在这个例子中,我将把它分成两个文件以获得更清晰的代码,但这并不是真正需要的——导入的文件可以写成一个大的 mixin):

// ...................................
// styles.less:

.banner {
    .mq-default({
        color: red;
    });

    .mq-medium({
        color: green;
    });

    .mq-retina({
        color: blue;
    });

    .background-image("test.jpg");
    note: not "wrapped" properties will appear in every media block;
}

.background-image(@image) {
    .mq-default({
        background-image: @image;
    });

    .mq-retina({
        background-image: replace(@image, "\.", "_2x.");
        background-size: 100%;
    });
}

// ...................................
// main.less:

.media-import(default);

@media (min-width: 600px) {
    .media-import(medium);
}

@media (min-device-pixel-ratio: 1.5) {
    .media-import(retina);
}

.media-import(@device) {
    .mq-default(@styles) when (@device = default) {@styles();}
    .mq-medium(@styles)  when (@device = medium)  {@styles();}
    .mq-retina(@styles)  when (@device = retina)  {@styles();}
    @import (multiple) "styles.less";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2013-09-27
    • 2015-10-13
    • 2013-09-28
    • 1970-01-01
    • 2019-07-04
    相关资源
    最近更新 更多