(SCSS - CSS) 每秒抓取一个child元素

(SCSS - CSS) Grab every second child element

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

假设我有 3 张牌,其中一张是顶部 parent,其余的是 children of eachother。我会证明我的意思。

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

我的目标是让 Parent 的样式与 body 的背景颜色相反,第一个 child 与 [=56] 相同=] 所以它反对 parent 卡片。第二个 child 再次反对第一个 child,也就是与顶部 parent 相同的背景。并为此无限地继续下去。

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

我目前正在通过 .card > .card 解决这个问题,但这只有效一次,我不想用 .card > .card > .card > .card > 向 css 发送垃圾邮件。卡等...

我试过使用 div:nth-child(even) 但是如果你继续在另一个里面做 children 就没用了。

我怎样才能做到这一点?

当前代码:

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>

想不出使用足够动态的 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>

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 (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>