【问题标题】:(SCSS - CSS) Grab every second child element(SCSS - CSS) 每隔一个子元素抓取一次
【发布时间】:2021-11-15 01:32:19
【问题描述】:

我有一个供个人使用的 CSS 框架,我希望它尽可能“自动”。我遇到了一个我无法解决的问题,但也许你可以帮助我。

假设我有 3 张卡片,其中一张是最上面的父母,其余的是彼此的孩子。我会表明我的意思。

<div class="card"> // Top parent
  Lorem!
  <div class="card"> // First child
    Lorem!
    <div class="card"> // Second child
      Lorem!
    </div>
  </div>
</div>

我的目标是让父卡的样式与正文相反的背景颜色和第一个孩子再次与正文相同,因此它与父卡相反。第二个孩子再次反对第一个孩子,也就是与顶级父母相同的背景。并让这种情况无限地持续下去。

可以为每个卡片设置背景颜色,但我希望在您将卡片添加到其他卡片中时,而不是手动执行此操作。

我目前正在解决这个问题 .card > .card 但这只能工作一次,我不希望用 .card > .card > .card > .card > .card 等向 css 发送垃圾邮件...

我尝试使用 div:nth-child(even) 但如果你一直在彼此之间做孩子,这将不起作用。

我怎样才能做到这一点?

当前代码:

SCSS:

@if #{$class} == card {
/* If parent card has a child card */
.#{$class} > .#{$class} {
  background-color: var(--clr-light-primary-background);
 }
}

CSS:

.card > .card {
  background-color: var(--clr-light-primary-background);
 }

HTML:

<div class="card column33 sm-rounded">
        <div class="card-header">
            <h2 class="card-title text-regular text-uppercase">TOP PARENT</h2>
        </div>
        <div class="card">
            <div class="card-header">
                <h2 class="card-title text-medium">1st CHILD</h2>
            </div>
            <div class="card">
                <div class="card-header">
                    <h2 class="card-title text-medium">2nd CHILD</h2>
                </div>
            </div>
        </div>
    </div>

【问题讨论】:

  • .card &gt; .card &gt; .card &gt; .card &gt; .card 是方式,还有:not(.card) &gt; .card 等。
  • 那么除了JS绝对没有别的办法了吗?我也可以做JS,但我不知道怎么做。你知道吗?
  • 您可以使用 var parents = document.getElementsByClassName('parentClassName')var children = parents[0].childNodes // this would also need to be iterated 遍历您的元素 - 如果您愿意,我可以尝试制作一个更完整的示例,尽管我觉得我会因为丑陋的代码而被处以私刑.
  • 继续!我不会评判你 :) 我不擅长编写漂亮的代码

标签: html css sass


【解决方案1】:

目前 CSS (AFAIK) 不提供基于嵌套级别增加 CSS 变量的方法 - 为什么您需要设置允许的有限嵌套级别... 但另一方面,如果您的 DOM 有 20 个嵌套卡片,这是否有意义 ;-)?

这是一个允许 5 个嵌套卡片的示例

body {
  --color-text: #fff;
  --color-back: #272b34;
  --color-back-alt: #323743;
  color: var(--color-text);
  background: var(--color-back);
  padding: 1rem;
}

.card {
  background: var(--color-back-alt);
  padding: 1rem;
}

:not(.card)>.card>.card>.card>.card>.card>.card,
:not(.card)>.card>.card>.card>.card,
:not(.card)>.card>.card {
  background: var(--color-back);
}
Body
<div class="card"> 1
  <div class="card"> 2
    <div class="card"> 3
      <div class="card"> 4
        <div class="card"> 5
          <div class="card"> 6
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

【讨论】:

    【解决方案2】:

    想不出用足够动态的 CSS 来做这件事的方法,所以这里有一些 JS。

    它从外层卡片开始,然后通过它们交替背景颜色继续向下直到没有更多。

    let odd = true;
    let cards = document.querySelectorAll('.card');
    do {
      cards[0].style.backgroundColor = (odd) ? 'blue' : 'red';
      odd = !odd;
      cards = cards[0].querySelectorAll('.card');
    } while (cards.length > 0)
    <div class="card column33 sm-rounded">
      <div class="card-header">
        <h2 class="card-title text-regular text-uppercase">TOP PARENT</h2>
      </div>
      <div class="card">
        <div class="card-header">
          <h2 class="card-title text-medium">1st CHILD</h2>
        </div>
        <div class="card">
          <div class="card-header">
            <h2 class="card-title text-medium">2nd CHILD</h2>
          </div>
        </div>
      </div>
    </div>

    【讨论】:

    • 这确实有效,但它有一个缺陷。我知道我现在必须使用 JS 来做到这一点,因为没有任何纯 CSS 方法可以做到这一点。但是使用 JS 它会将 style="" 添加到元素中。虽然我相信 JS 可以改变 CSS。有没有相关的方式将 JS 添加到 SCSS 中?
    • 不确定我是否理解 - SCSS 是一个预处理器。你想让 JS 更新 CSS 样式表吗?我可能遗漏了一些东西,但我不确定这会有什么帮助。您可以向卡片添加一个类,而不是更改其内联样式,并拥有几个类,如果这样可以更轻松地稍后更改内容,但我看不出更改 CSS 有什么帮助。
    【解决方案3】:

    CSS 解决方案

    这对于 CSS 框架可能不实用,但您可以尝试使用 CSS 过滤器,看看是否可以得到有效的颜色组合。

    注意这里的 JS 只是为了演示。

    document.querySelector("button").addEventListener("click", () => {
      const cards = document.querySelectorAll(".card");
      const lastCard = cards[cards.length - 1];
    
      lastCard.innerHTML = `${cards.length} <div class="card">${
        cards.length + 1
      }</div>`;
    });
    
    document.querySelector("input").addEventListener("input", (e) => {
      const newColor = e.target.value;
    
      document.documentElement.style.setProperty("--card-bg-color", newColor);
    });
    :root {
      --card-bg-color: #666;
    }
    
    .card {
      padding: .5rem;
      border-radius: 0.25em;
      background: var(--card-bg-color);
      >
    }
    
    .card>.card {
      filter: invert(100%);
    }
    
    
    /* Demo */
    .control {
      position: fixed;
      bottom: 0;
      left: 0;
      display: grid;
      grid-gap: .5rem;
      background: black;
      color: white;
      padding: 1rem;
    }
    <div class="card">1
      <div class="card">2
        <div class="card">3</div>
      </div>
    </div>
    
    <!-- Demo -->
    <div class="control">
      <button>Add card</button>
      <label for="color">Change colour <input type="color" value="#666666"></label>
    </div>

    JavaScript 解决方案

    const setCardBackgroundColors = () => {
      const cards = [...document.querySelectorAll(".card")];
    
      cards && cards.length && cards.forEach((card, index) => {
        index % 2 && card.classList.add('has-bg-dark');
      })
    }
    
    
    // Just for demo
    const template = (level) => {
      return `
        <article class="card">
           <p>${level}</p>
        </article>
        `
    }
    document.querySelector("button").addEventListener("click", () => {
      const cards = document.querySelectorAll(".card");
      const lastCard = cards[cards.length - 1];
    
      lastCard.insertAdjacentHTML('beforeend', template(cards.length + 1));
      setCardBackgroundColors();
    });
    .card {
      background-color: #555;
      color: white;
      padding: 1rem;
      border-radius: 0.25em;
      position: relative;
    }
    
    .card.has-bg-dark {
      background-color: #222;
    }
    
    /* demo styles */
    * {
      box-sizing: border-box;
    }
    
    body {
      font: 18px/1.2 system-ui;
      padding: 1rem;
    }
    
    .control {
      position: fixed;
      bottom: 0;
      left: 0;
      display: grid;
      grid-gap: 0.5rem;
      background: black;
      color: white;
      padding: 1rem;
    }
    <article class="card">
      <p>1</p>
    </article>
    
    <!-- Demo -->
    <div class="control">
      <button>Add card</button>
    </div>

    【讨论】:

    • 虽然用纯 CSS 实现它是一种天才的方式,但似乎没有任何方法可以控制反转颜色。所以在这种环境下使用是不切实际的。不过谢谢你的想法!
    • 我不确定是否可以使用纯 CSS 或 SCSS 获得您想要的效果。你愿意接受 JavaScript 解决方案吗?
    • 绝对是@sol。
    • 已添加。你只需要遍历你的卡片并添加一个你可以用你的 CSS 定位的类。此处的函数假定页面上只有一个 .card 父级。您可能需要根据需要对其进行修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 2011-08-15
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多