Я пытаюсь создать треугольную сетку с помощью HTML и CSS, которая включает смещение каждого последующего треугольника в сетке влево на все большую и большую величину, чтобы каждый треугольник аккуратно помещался рядом с предыдущим. Поскольку количество перемещений каждого треугольника зависит от его индекса в родительском контейнере, в настоящее время я использую JS для установки этого смещения. Я ищу способ сделать это с помощью чистого CSS. Такое использование JS похоже на взлом, и мне интересно, не упускаю ли я что-то в CSS, что позволило бы мне получить доступ к индексу каждого треугольника div, или, возможно, в CSS есть другой способ добиться того, что я делаю.
let triangleRows = [...document.getElementsByClassName('triangle-row')]
triangleRows.forEach(row => {
let children = [...row.children]
// set each triangle's --tri-index variable to its index
children.forEach((tri, idx) => tri.style.setProperty('--tri-index', idx))
}):root {
--tri-width: 5rem;
--tri-ratio: 0.86603;
--offset: -2.25rem
}
.triangle-row {
display: flex;
margin-top: 0.2rem;
}
.triangle {
position: relative;
height: calc(var(--tri-width) * var(--tri-ratio));
width: var(--tri-width);
left: calc(var(--offset) * var(--tri-index));
background-color: red;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.triangle:hover {
background-color: yellow;
}
.flipped {
clip-path: polygon(0% 0%, 50% 100%, 100% 0%);
}<div class = "triangle-row">
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
</div>
<div class = "triangle-row">
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
</div>Интересно, а не нужен ли вам новый селектор css для каждого дочернего элемента? Я надеюсь на решение, которое масштабируется независимо от того, сколько треугольников я помещаю в каждую строку.
Да, теперь, когда я думаю об этом, селекторы :nth-child устранят необходимость в перевернутом классе, но это не сильно поможет с переменными CSS.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я создал тот же результат с отрицательным запасом. Таким образом, треугольники не должны перемещаться на большее расстояние влево.
:root {
--tri-width: 5rem;
--tri-ratio: 0.86603;
--offset: -2.25rem
}
.triangle-row {
display: flex;
margin-top: 0.2rem;
}
.triangle {
position: relative;
height: calc(var(--tri-width) * var(--tri-ratio));
width: var(--tri-width);
margin-left: var(--offset); /* add the offset */
background-color: red;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.triangle:first-child{
margin-left: 0;
}
.triangle:hover {
background-color: yellow;
}
.flipped {
clip-path: polygon(0% 0%, 50% 100%, 100% 0%);
}<div class = "triangle-row">
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
</div>
<div class = "triangle-row">
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
<div class = "triangle"></div>
<div class = "triangle flipped"></div>
</div>Редактировать: я реализовал ввод от @Bryce Howitson и удалил чередование перевернутых классов. CSS теперь немного сложнее, но теперь легко включить больше треугольников или больше линий треугольников.
:root {
--tri-width: 5rem;
--tri-ratio: 0.86603;
--offset: -2.25rem
}
.triangle-row {
display: flex;
margin-top: 0.2rem;
}
.triangle {
position: relative;
height: calc(var(--tri-width) * var(--tri-ratio));
width: var(--tri-width);
margin-left: var(--offset); /* add the offset */
background-color: red;
}
.triangle:hover {
background-color: yellow;
}
.triangle:first-child {
margin-left: 0;
}
.triangle-row:nth-child(odd) .triangle:nth-child(odd),
.triangle-row:nth-child(even) .triangle:nth-child(even) {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.triangle-row:nth-child(even) .triangle:nth-child(odd),
.triangle-row:nth-child(odd) .triangle:nth-child(even){
clip-path: polygon(0% 0%, 50% 100%, 100% 0%);
}<div class = "triangle-row">
<div class = "triangle"></div>
<div class = "triangle"></div>
<div class = "triangle"></div>
<div class = "triangle"></div>
<div class = "triangle"></div>
</div>
<div class = "triangle-row">
<div class = "triangle"></div>
<div class = "triangle"></div>
<div class = "triangle"></div>
<div class = "triangle"></div>
<div class = "triangle"></div>
</div>Хороший улов! У меня была вспышка вдохновения, и я собирался опубликовать то же самое, ха-ха.
По какой-то причине я думал, что margin-left также нужно будет увеличивать с каждым div, но имеет смысл, что следующий div будет просто отображаться в строке на основе новой правой стороны предыдущего div. Отличный ответ, СПАСИБО!
В качестве небольшого улучшения вы можете применить поле ко всем треугольникам строки, кроме первого, поэтому вам не нужно применять обратное поле к родителю.
О, это хороший вклад. Я отредактировал свое решение.
Также использование nth-child(odd) позволит вам применить альтернативный путь отсечения без необходимости применять отдельный класс к каждому нечетному элементу.
@BryceHowitson за вклад. Я обновил свой ответ с помощью этого подхода.
Хороший вопрос и неплохое начало. Возможно, вы можете что-то сделать, используя селекторы :nth-child.