【问题标题】:CSS transform without affecting child elements?CSS变换不影响子元素?
【发布时间】:2020-07-13 16:30:03
【问题描述】:

我试图让卡片元素在悬停时向上移动,然后在不再悬停时向下移动。我目前通过在 CSS 中使用 transformtranslate 来实现这一点。但是,我注意到这会影响子元素以及我希望此动画受其影响的元素。这是我目前拥有的卡片的 HTML 和 CSS:

.server :hover {
  -moz-transform: translate(0, -2px);
  -ms-transform: translate(0, -2px);
  -o-transform: translate(0, -2px);
  -webkit-transform: translate(0, -2px);
  transform: translate(0, -2px);
  transition-duration: 0.3s;
  transition-timing-function: ease-in-out;
}
<div class="server">
  <div class="card m-2 p-1 text-center">
    <p>Child element</p>
  </div>
</div>

【问题讨论】:

    标签: html css css-transforms


    【解决方案1】:

    由于子元素总是与它们的父元素一起移动(opacity 也是如此),您可以对所有子元素设置相反的变换。

    我在card 上添加了一个红色背景,并设置&gt; * 所有孩子都进行相反的变换。

    .server :hover {
      -moz-transform: translate(0, -2px);
      -ms-transform: translate(0, -2px);
      -o-transform: translate(0, -2px);
      -webkit-transform: translate(0, -2px);
      transform: translate(0, -2px);
      transition-duration: 0.3s;
      transition-timing-function: ease-in-out;
    }
    
    .server :hover > * {
      transform: translate(0, 2px);
      transition-duration: 0.3s;
      transition-timing-function: ease-in-out;
    }
    
    .card {
      background: red;
    }
    <div class="server">
      <div class="card m-2 p-1 text-center">
        <p>Child element</p>
      </div>
      
      
      <div class="card m-2 p-1 text-center">
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
      </div>
      
      
    </div>

    由于我不确定您的 card 元素实际显示的是什么,您还可以使用伪 ::before::after 并将转换分配给它:

    .server :hover::after {
      transform: translate(0, -2px);
      transition-duration: 0.3s;
      transition-timing-function: ease-in-out;
    }
    
    .card {
      position: relative;
      z-index: 1;
    }
    
    .card::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      background: red;
      width: 100%;
      height: 100%;
      z-index: -1;
    }
    
    .card>* {
      z-index: 5;
    }
    <div class="server">
      <div class="card m-2 p-1 text-center">
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
        <p>Child element</p>
      </div>
    </div>

    【讨论】:

    • 尽管这很可能有效,但 Mech 提供的解决方案似乎更加优雅和干净。对不起!
    • 别抱歉!这些解决方案仍然有效,但 Mech 的 :not 也是一个合适的解决方案。
    【解决方案2】:

    您可以使用:not指定

    .server :hover :not(p) {
      -moz-transform: translate(0, -2px);
      -ms-transform: translate(0, -2px);
      -o-transform: translate(0, -2px);
      -webkit-transform: translate(0, -2px);
      transform: translate(0, -2px);
      transition-duration: 0.3s;
      transition-timing-function: ease-in-out;
    }
    <div class="server">
      <div class="card m-2 p-1 text-center">
        <p>Child element</p>
        <div>Child element</div>
      </div>
    </div>

    【讨论】:

    • 我应该指定我在问题中使用的 HTML 是示例,并且卡片内的代码更复杂。如果有多个元素,我只需要用逗号添加元素吗? e.g. (p, div, img)@Mech
    • 你明白了。 :not(p, div, img)
    • 您可以更通用并使用通配符:not(*) 另外,请使用您发布的所有评论更新您的答案 - 让未来的访问者更容易 - 这样他们就不必浏览cmets 的最终答案。
    【解决方案3】:

    当您可能想要的是链式选择器时,您使用了复合选择器。只需将:hover 伪选择器(不带空格)直接添加到您想要影响的元素。

    .card {
      /* transitions are needed when hover state ends, so set up rules here */
      transform: translate(0, 0);
      transition-property: transform;
      transition-duration: 0.3s;
      transition-timing-function: ease-in-out;
    }
    .card:hover { /* note: no space */
      transform: translate(0, -2px);
    }
    <div class="server">
      <div class="card m-2 p-1 text-center">
        <p>Child element</p>
      </div>
    </div>

    【讨论】:

    • 这是一个更清晰的答案,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 2012-05-30
    • 2022-01-24
    • 2013-08-01
    • 2017-01-04
    • 1970-01-01
    • 2014-02-23
    相关资源
    最近更新 更多