41

在 Sass 中,是否可以操作给定元素已经继承的值?

我的目标是这样的:

body
  color: blue
  .warning
    color: red

strong
  color: darken(inherit,20)
4

4 回答 4

26

遗产

不,Sass 不“知道”从哪个选择器继承颜色。它必须知道那strong是 的后代body。对你我来说,这似乎是一个足够合理的假设,因为strong它不允许在身体之外,但是对于大多数选择器来说,这种假设是不能做出的。Sass 还必须知道其他祖先元素不会发生级联。

ul {
    color: red;
}

ol {
    color: blue;
}

li {
    // which color do I inherit from ????
}

那么我可以指定要从哪个选择器复制吗?

Sass 也不授予以任何方式访问任何先前声明的变量的值。没有办法指定“比身体的颜色更暗”。CSS 规则不是对象或映射,不能以任何方式访问。您的案例可能很简单,但考虑一个更复杂的案例,如下所示:

.foo {
    background: mix(white, blue); // fallback for non-rgba browsers
    background: rgba(blue, .5);

    .baz & {
        background: yellow;
    }

    @media (min-width 30em) {
        background: orange;
    }

    @supports (flex-wrap: wrap) {
        background: red;
    }
}

.bar {
    // access which background color from .foo ????
}

那么我能做什么呢?

你要么需要使用变量,要么它必须是 vanilla CSS 的一个特性才能做你想做的事情。

老式的 CSS

某些属性可能会产生使用浏览器支持多年的东西动态生成/继承的错觉:

ul.one {
  background: white;
}

ul.two {
  background: yellow;
}

ul {
  background: rgba(0, 120, 255, .2);
  padding: 1em;
}
<ul class="one">
  <li><ul>
    <li><ul>
      <li>Foo</li>
    </ul></li>
  </ul></li>
</ul>

<ul class="two">
  <li><ul>
    <li><ul>
      <li>Foo</li>
    </ul></li>
  </ul></li>
</ul>

CSS 变量

生成 CSS 变量几乎与您能够操作继承的属性一样接近。浏览器支持还不完全存在(检查caniuse),但看起来像这样:

萨斯:

ul {
  --list-color: orange;
  --darker-color: darken(orange, 15%);
  color: var(--list-color);
}

ol {
  --list-color: green;
  --darker-color: darken(green, 10%);
  color: var(--list-color);
}

li {
  background: var(--darker-color);
}

输出:

ul {
  --list-color: orange;
  --darker-color: #b37400;
  color: var(--list-color);
}

ol {
  --list-color: green;
  --darker-color: #004d00;
  color: var(--list-color);
}

li {
  background: var(--darker-color);
}
<ul>
  <li>Foo</li>
</ul>

<ol>
  <li>Bar</li>
</ol>

如果您使用的浏览器支持 CSS 变量,则结果应如下所示:

在此处输入图像描述

于 2013-02-17T12:59:55.323 回答
9

我正在寻找同样的东西,并遇到了这个。你的问题得到了回答,但并没有解决问题。

这是解决方案:http ://codepen.io/monsto/pen/tiokl

如果您的 HTML 是这样的:

    <div class="main">
      <header class="header">
        <div class="warning">
          <p><strong>Danger,</strong> Will Robinson!</p>
        </div>
      </header>
    </div>

然后使用 SASS 你可以这样做:

$bg: #f88;

@mixin colorize {
  $bg: darken($bg,15%) !global; // !global flag required for 3.4 or later, remove if using 3.3 or older
  background: $bg;
}

.warning {
  background: $bg;
  p {
    @include colorize;
    strong {
      @include colorize;
    }
  }
}

SASS 似乎不知道它的输出结果。因此,inherit对它没有任何意义。您基本上是在要求它在输出之前知道输出是什么。

但是,它确实知道它的变量,因为默认情况下,它们的范围很窄。从文档:

变量仅在定义它们的嵌套选择器级别内可用。如果它们是在任何嵌套选择器之外定义的,那么它们在任何地方都可用。

然后混入中的变量:

传递给 mixin 的内容块在定义块的范围内进行评估,而不是在 mixin 的范围内。

这允许上述 mixin 采用在父级别中定义的已知变量,并将其重新定义为当前级别并可供其子级使用。这就像$x = $x + 1在一个多嵌套循环中做

TBPH,这改变了我对 SASS 的看法。它显然比我想象的要程序化得多。

于 2013-09-12T19:05:51.620 回答
9

鉴于一个元素不能具有多个组合的相同属性,并且inherit无法知道当前呈现的状态是什么,您的选择是

1) 使用 SASS 变量自己跟踪过去的转换:Demo

.parent {
  $firstTrans: translateX(50%);
  transform: $firstTrans;

  .child {
    /* Old followed by new */
    transform: $firstTrans rotate(10deg);
  }
}

2)将转换应用到父级(如果需要,可能添加另一个容器):Demo

3) 使用 Javascript 将当前变换与您要添加的变换组合(这是确保删除应用于父级的变换的唯一方法):Demo

注意:由于此元帖子,此答案来自合并帖子

于 2014-01-24T15:57:51.200 回答
1

这个答案darken专门针对该功能:一种可能的替代方法是使用 CSSbrightness()过滤器而不是 SASS(或 LESS)的darken()功能。您基本上需要将颜色包装在span标签内,这样过滤器就不会影响其他元素。

简单演示:

.red {color: red}
.blue {color: blue}
.green {color: green}

span {
  display: inline-block;
  padding: 1em;
}

.darken span {
  -webkit-filter: brightness(0.4);
  filter: brightness(0.4);
}
<span class="red">Red</span>
<span class="blue">Blue</span>
<span class="green">Green</span>

<div class="darken">
  <span class="red">Red</span>
  <span class="blue">Blue</span>
  <span class="green">Green</span>
</div>

jsFiddle:https ://jsfiddle.net/azizn/hhorhz9s/

您需要牢记浏览器兼容性,它应该适用于 IE Edge、最新的 Firefox 和 Chrome。有关更多信息,请参阅caniuseMDN

在背景变暗的情况下,您可以使用具有不透明度的伪选择器或添加半透明的黑色 PNG 背景图像。

于 2016-04-10T03:04:11.983 回答