Как сместить DIV по его индексу

Я пытаюсь создать треугольную сетку с помощью 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>

Хороший вопрос и неплохое начало. Возможно, вы можете что-то сделать, используя селекторы :nth-child.

Domino 15.03.2022 15:41

Интересно, а не нужен ли вам новый селектор css для каждого дочернего элемента? Я надеюсь на решение, которое масштабируется независимо от того, сколько треугольников я помещаю в каждую строку.

user2657799 15.03.2022 15:44

Да, теперь, когда я думаю об этом, селекторы :nth-child устранят необходимость в перевернутом классе, но это не сильно поможет с переменными CSS.

Domino 15.03.2022 15:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
3
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я создал тот же результат с отрицательным запасом. Таким образом, треугольники не должны перемещаться на большее расстояние влево.

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

Хороший улов! У меня была вспышка вдохновения, и я собирался опубликовать то же самое, ха-ха.

Domino 15.03.2022 15:53

По какой-то причине я думал, что margin-left также нужно будет увеличивать с каждым div, но имеет смысл, что следующий div будет просто отображаться в строке на основе новой правой стороны предыдущего div. Отличный ответ, СПАСИБО!

user2657799 15.03.2022 15:54

В качестве небольшого улучшения вы можете применить поле ко всем треугольникам строки, кроме первого, поэтому вам не нужно применять обратное поле к родителю.

Domino 15.03.2022 16:25

О, это хороший вклад. Я отредактировал свое решение.

YourBrainEatsYou 15.03.2022 16:26

Также использование nth-child(odd) позволит вам применить альтернативный путь отсечения без необходимости применять отдельный класс к каждому нечетному элементу.

Bryce Howitson 15.03.2022 21:49

@BryceHowitson за вклад. Я обновил свой ответ с помощью этого подхода.

YourBrainEatsYou 16.03.2022 09:17

Другие вопросы по теме