Ways to adjust the position of a DIV based on its index value

I'm currently working on a unique project that involves creating a triangular grid using HTML and CSS. The challenge I am facing is offsetting each triangle in the grid to the left by increasing amounts so they fit seamlessly next to one another. Right now, I am using JavaScript to achieve this by setting the offset based on the triangle's index within the parent container. However, it feels like a workaround and I am exploring if there is a way to accomplish this purely with CSS. I wonder if there might be a CSS feature that allows me to access each triangle div’s index or if there is an alternative method in CSS to achieve the same result.

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>

Answer №1

By incorporating a negative margin, I was able to achieve the same outcome without the triangles shifting further to the left.

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

Edit: Following @Bryce Howitson's suggestion, I have refined the CSS and eliminated the need for alternating "flipped" classes. This allows for easy addition of more triangles or rows of triangles.

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular seems to be experiencing issues with maintaining context when executing a function reference for a base class method

Imagine we have CtrlOne that extends CtrlTwo, with a componentOne instantiated in the template of CtrlOne. Here is some code to illustrate the issue: class CtrlOne extends CtrlTwo { constructor() { super(); } } class CtrlTwo { sayMyName(name: st ...

The placement of buttons in a responsive web design

Need help with adjusting button positions in mobile mode relative to text. Tried using different position settings like absolute and relative, but buttons are not staying aligned with the text on mobile devices. Can anyone assist? .button { display: b ...

invoking an API within a map function and utilizing the response

vm.owners = parents.children.map(function(e) { getparentById(e.Id) .then(function(getresponse) { var parentLink = '<a href="/#/parent/onboard/' + e.Id + '" target="_blank">' + e.Number + "-&qu ...

Is it possible to incorporate npm modules into a browser and utilize them locally on a personal computer?

This is my first time working with npm modules and node.js, so I find it quite challenging. I have a JavaScript code with multiple data points and I need to find the closest city to each of them. In response to another question on Stack Overflow (Reverse ...

Exploring the use of v-model in Vue3 child components

After some exploration, I recently discovered that in Vue3, the v-model functionality does not work responsively or reactively with child Component. The following code snippet showcases how the username data gets updated: <template> <div> ...

Combining two objects by aligning their keys in JavaScript

I have two simple objects that look like this. var obj1 = { "data": { "Category": "OUTFLOWS", "Opening": 3213.11, "Mar16": 3213.12, "Apr16": 3148.13, "May16": 3148.14, "Jun16" ...

Adjust the vertical positioning according to the percentage of the width

Currently, I am attempting to modify the position of my navigation bar on the screen in relation to the screen width rather than the height. I previously attempted using top: 10% in CSS, but realized this is based on the screen's height instead of its ...

What is the importance of including the source name when redirecting?

In a recent discussion (jQuery Ajax PHP redirecting to another page), it was mentioned that when utilizing ajax for redirection to a PHP page, an event needs to be set in the following manner: $.ajax({ type: "POST", url: "ajax.php", data: dataString, ...

A skeleton framework lacking a data storage backend

I am currently developing an offline javascript application that must be compatible with IE7, ruling out the use of localStorage. The app does not require any information persistence, as a refresh clears everything. My query is regarding setting up Backbo ...

When comments are submitted via AJAX, they are displayed twice, but upon reloading the page, they only appear once

After using the codes below to add a comment to a post and display it without refreshing the page, I encountered an issue where the comment is displayed twice instead of once. However, the comment is only saved once in the database. Interestingly, when the ...

Having trouble getting the jQuery autocomplete feature to function properly?

On my page, there is a button labeled "Add a Skill." Clicking on this button should trigger the display of an input box where you can enter your skill, another input box for your skill level, and a horizontal slider to select the skill level. In my databa ...

Ways to toggle the display of a div depending on various radio button selections

Currently, I am working on a project using HTML along with Bootstrap and Jquery. My objective is to dynamically hide a div based on the selection of multiple radio buttons without requiring a submit button. The code snippet that I have provided below works ...

What is the process for extracting the period value from SMA technical indicators within highcharts?

Can someone assist me in retrieving the period value from SMA indicator series by clicking on the series? series : [{ name: 'AAPL Stock Price', type : 'line', id: 'primary', ...

Sorting alphanumeric strings in React Bootstrap Table Next on a dynamic table

I am facing an issue with sorting columns in a dynamic table with over 70 columns using React-Bootstrap-Table-Next. The problem arises when trying to sort the columns in alphanumerical order, as some columns contain numbers and others contain letters. The ...

Guide to loading an image and incorporating it into a canvas using Gatsby's server-side rendering

I encountered an issue where I was unable to create an image using any of the supported types like CSSImageValue, HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap, or OffscreenCanvas in my SSR application with Gatsby. De ...

swap out a JavaScript function for a fresh function

In our ordering system, there is a hidden function that I cannot access. Interestingly, this function contains a spelling error which causes a grammar issue to appear in a popup when a user interacts with it. Is there any way for me to either modify the t ...

Having all elements at the same height

I am looking to enhance my JavaScript code to only impact 4 items at a time. The goal is to target the first 4 instances of .prodbox, adjust their height accordingly, then move on to the next set of 4 and repeat the process. This sequential adjustment will ...

Utilizing a JavaScript class method through the onchange attribute triggering

I am facing an issue with a simple class that I have created. I can instantiate it and call the init function without any problems, but I am unable to call another method from the onchange attribute. Below is the code for the class: var ScheduleViewer = ...

Sending the method's URL in the controller through an AJAX call

Below is the code snippet for an ajax call: <script> jQuery(document).ready(function() { $("#VEGAS").submit(function(){ var form_data = $("#VEGAS").serialize(); var routeUrl = "<?= url('/'); ?> /PUBLIC/vpage"; $.ajax({ ...

Personalized tooltips for numerous data sets in Highcharts

I am currently in the process of constructing a highchart that is capable of accommodating up to five different types of data series. I have arranged similar series together, resulting in three distinct y-axes for the various series. However, I have encou ...