【问题标题】:How to simultaneously transition colour of nested children如何同时过渡嵌套子项的颜色
【发布时间】:2016-09-21 23:58:38
【问题描述】:

我正在努力寻找能做两件事的 CSS,改变所有子元素的颜色,并将其作为过渡。我创建了以下JSFiddle 的简单测试用例:

<div class="parent">Level 1
  <div>Level 2
    <div class="child">Level 3 (!important means this should become red on hover)
    </div>
  </div>
</div>

我正在尝试使用 CSS 将文本转换为不同的颜色。这是我正在使用的框架:

.parent {
  transition: all 2s ease-out;
}
.parent:hover {
  color: red !important;
}
.child {
  color: blue;
}

我想在父级指定一个规则,该规则将导致所有子级更改颜色。我知道不鼓励使用 !important,但这似乎是使用它的有效案例,因为此规则将该部分标记为“错误”并且应该覆盖其他规则。

这是我为使其工作所做的工作,但它要求我对所有设置颜色的子元素都有规则。在这个简单的例子中这很好,但在实际系统中会出现问题,因为我们可能不知道改变颜色的所有规则。

div {
  font-size: 3rem;
  text-indent: 1rem;
}
.child {
  color: blue;
}

.parent,
.parent .child {
    transition: all 3s;
}

.parent:hover,
.parent:hover .child {
  color: red !important;
}
<div class="parent">
  Level 1
  <div>
    Level 2
    <div class="child">
      Level 3 (!important means this should become red on hover)
    </div>
  </div>
</div>

是否可以在不知道所有必须指定的类的情况下将所有子元素转换为新颜色?我尝试使用.parent * 选择器,但每一级嵌套都会增加过渡期,如fiddle

更新

我对正在发生的事情有了更好的了解。 @Hunter 解决了不必要的 !important 规则。所以,真正的问题是,transition-duration 属性似乎对孩子来说是附加的,看看当不再将鼠标悬停在文本上时移除红色需要多慢,理想情况下每个嵌套元素的颜色应该同时转换.

div {
  padding-left: 1rem;
}

.a-child { color: blue; }

.parent * {
  transition: color 2s;
}

.parent:hover * {
  color: red;
}
<div class="parent">
  <div>
    Level 1
    <div>
      Level 2
      <div>
        Level 3
        <div>
          Level 4
          <div class="a-child">
          Level 5
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

【问题讨论】:

  • 所以当有人将鼠标悬停在父元素上时,您希望所有三个级别都改变颜色?
  • 我认为过渡没有实际延迟。但是您在蓝色元素上看到的延迟可能是由于它从蓝色过渡到红色。 通过中间颜色。 它可能比 CSS 问题更直观。但是找不到参考资料。
  • @AnkithAmtange 使用 * 选择器时,第二个文本位(第一个 div)在 out 转换时运行时间是原来的两倍。
  • 如果我错了,请纠正我。但是选择器要么匹配,要么不匹配。它们不应导致过渡延迟。您所指的应该是游戏中的transition-timing-functionease-out
  • @AnkithAmtange 我认为发生的事情是嵌套元素都匹配 CSS 规则,但是每个匹配规则的转换持续时间是相加的。因此,我们看到 Level2 的颜色变化比 level1 需要更长的时间(特别是在返回黑色时)

标签: html css css-transitions


【解决方案1】:

通用选择器的性能有了显着提高,但它仍然是一个令人担忧的问题,尽管是一个小问题。如果所有孩子都是&lt;div&gt;s,我建议你使用.parent div

CSS:

div {
  font-size: 3rem;
  text-indent: 1rem;
}

.child {
  color: blue;
}

.parent,
.parent div {
  transition: all 3s;
}

.parent:hover,
.parent:hover div {
  color: red;
}

HTML:

<div class="parent">
  Level 1
  <div>
    Level 2
    <div class="child">
      Level 3 (!important means this should become red on hover)
    </div>
  </div>
</div>

这是JSFiddle

编辑

为避免递归传输延迟,只需明确设置黑色子代的color,例如蓝色的.a-child

div {
  padding-left: 1rem;
}

.parent * {
  color: black; /* explicitly set color of children */
  transition: color 2s;
}

.a-child { color: blue; }

.parent:hover * {
  color: red;
}
<div class="parent">
  <div>
    Level 1
    <div>
      Level 2
      <div>
        Level 3
        <div>
          Level 4
          <div class="a-child">
          Level 5
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

递归延迟的原因,是父级的color属性设置为红色,直到transition完成,然后color值才恢复默认值(继承自&lt;body&gt;即黑色)。

二级&lt;div&gt;color属性没有显式设置,因此它继承了其父级的值;这就是为什么它会一直保持红色,直到其父级的 transition 完成继承黑色并开始过渡到黑色,这会递归地发生,从而产生延迟效果。

这就是为什么当鼠标悬停时蓝色&lt;div&gt; 立即开始转变为蓝色;因为它的color 属性显式设置为blue

【讨论】:

  • 观看 2 级的过渡,当鼠标悬停结束时,我们看到 2 级保持红色大约是 1 级的两倍。所以,过渡时间似乎是累加的,这不是我的意图。
  • @Josh 你解决了这个问题吗?我有同样的问题。我的内部文本比其他元素需要更长的时间来改变颜色。我尝试了许多 CSS 选择器的组合,没有任何效果
  • 我通过简单地为所有文本分配默认颜色解决了这个问题,这样它就不必等待其父级继承颜色(正如@5aledmaged 所推测的那样)。所以我使用了:* { color: var(--body-text-color); } 这解决了我的问题。
【解决方案2】:

通过使用 * 选择器并将 .parent 文本放在单独的 div 中,您可以选择父级的每个子级并应用过渡和颜色更改。

.parent 内容放在单独的 div 中可修复输出转换的延迟。

CSS

.parent * {
  transition: all 2s ease-out;
}

.parent:hover * {
  color: red;
}

HTML

<div class="parent">
  <div>Level 1</div> <!-- <-- Place in div -->
  <div>
    ...

使用这个,也不需要!important

div {
  font-size: 3rem;
  text-indent: 1rem;
}
.child {
  color: blue;
}

.parent * {
  transition: all 2s ease-out;
}

.parent:hover * {
  color: red;
}
<div class="parent">
  <div>Level 1</div>
  <div>
    Level 2
    <div class="child">
      Level 3
    </div>
  </div>
</div>

JSFiddle

【讨论】:

  • 谢谢,我很高兴删除 !important 规则。但是,您的更改会丢失 div 的嵌套,因此级别 1 是级别 2 的兄弟。如果存在嵌套,我们仍然会获得过渡的附加延迟,如下所示:jsfiddle.net/gr7gvz2f/7
  • @Josh 由于文本属于.parent 本身,如果您愿意,您可以使用&lt;span&gt; 或其他东西而不是div。 JSFiddle
  • 我用一个更好的例子修改了这个问题,展示了一个深度嵌套的结构。它表明嵌套越深,去除颜色所需的时间就越长。那是我不明白的部分,即。为什么嵌套元素的过渡会有延迟?
  • @Josh,感谢您的更新。我会看看我能做什么。
猜你喜欢
  • 2023-03-26
  • 2021-04-01
  • 2011-03-27
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
相关资源
最近更新 更多