Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move cousin html elements by css only

I am making a simple calendar that has days as columns, and multiple events each day. This is simple. However, some events go over two days and I wonder if it is possible to display this with css only. The content will of course be dynamic, so can't hardcode anything.

Here is the concept I'm trying to achieve:

simple design sketch

Requirements

  • The events shouldn't overlap (example: the event on Monday that goes into Tuesday should occupy place on Tuesday)
  • Events should be possible to drag from one day to another. Drag&drop will be solved with Javascript, but in order to solve it I need to know on which day the events are dropped onto. This affects how html is built, I think.

The html will look something like this:

<div class="week">
  <div class="day-column" data-date="2024-06-03">
    <div class="event">Event 1</div>
    <div class="event overnight">Event 2</div>
    <div class="event">Event 3</div>
    <div class="event">Event 4</div>
  </div>
  <div class="day-column" data-date="2024-06-04">
    <div class="event">Event 1</div>
    <div class="event">Event 2</div>
    <div class="event overnight">Event 3</div>
    <div class="event">Event 4</div>
  </div>
  <div class="day-column" data-date="2024-06-05">
    <div class="event">Event 1</div>
    <div class="event">Event 2</div>
    <div class="event">Event 3</div>
    <div class="event">Event 4</div>
  </div>
  <div class="day-column" data-date="2024-06-06">
    <div class="event">Event 1</div>
    <div class="event">Event 2</div>
    <div class="event">Event 3</div>
    <div class="event overnight">Event 4</div>
  </div>
  <div class="day-column" data-date="2024-06-07">
    <div class="event">Event 1</div>
    <div class="event">Event 2</div>
    <div class="event">Event 3</div>
    <div class="event">Event 4</div>
  </div>
</div>

Week will be a flex container, the days its children, with the events block elements.

Is this even possible to make with html and css only? Or am I doomed to make something super complicated setup where I have to make ghost objects with javascript, where events from previous day overlap only to push down overlapped events today?

Any ideas?

like image 296
Ollie Moss Avatar asked Jan 22 '26 13:01

Ollie Moss


1 Answers

Here's a way of laying things out as required while maintaining the HTML structure.

It uses CSS grid with the display: contents option on the days so their contents are included.

If an element is moved to a different day for example in the HTML it will pick up the correct CSS as the selectors are related to child positions.

Note: the CSS is spelled out here to make things clear. No doubt there are ways of shortening it e.g. with CSS variable (and getting rid of the importants??)

<style>
  .week {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    width: 90vw;
    grid-auto-flow: dense;
  }
  
  .day-column {
    display: contents;
  }
  
  .day-column:nth-child(1) .event {
    grid-column: 1 / span 1!important;
  }
  
  .day-column:nth-child(1) .event.overnight {
    grid-column: 1 / span 2!important;
  }
  
  .day-column:nth-child(2) .event {
    grid-column: 2 / span 1!important;
  }
  
  .day-column:nth-child(2) .event.overnight {
    grid-column: 2 / span 2!important;
  }
  
  .day-column:nth-child(3) .event {
    grid-column: 3 / span 1!important;
  }
  
  .day-column:nth-child(3) .event.overnight {
    grid-column: 3 / span 2!important;
  }
  
  .day-column:nth-child(4) .event {
    grid-column: 4 / span 1!important;
  }
  
  .day-column:nth-child(4) .event.overnight {
    grid-column: 4 / span 2!important;
  }
  
  .day-column:nth-child(5) .event {
    grid-column: 5 / span 1!important;
  }
  
  .day-column:nth-child(5) .event.overnight {
    grid-column: 5 / span 2!important;
  }
  
  .event.overnight {
    background-color: pink;
  }
  
  .event {
    background-color: cyan;
  }
</style>
<div class="week">
  <div class="day-column">
    <div class="event">Event 1.1</div>
    <div class="event overnight">Event 1.2</div>
    <div class="event">Event 1.3</div>
    <div class="event">Event 1.4</div>
  </div>
  <div class="day-column">
    <div class="event">Event 2.1</div>
    <div class="event">Event 2.2</div>
    <div class="event overnight">Event 2.3</div>
    <div class="event">Event 2.4</div>
  </div>
  <div class="day-column">
    <div class="event">Event 3.1</div>
    <div class="event">Event 3.2</div>
    <div class="event">Event 3.3</div>
    <div class="event">Event 3.4</div>
  </div>
  <div class="day-column">
    <div class="event">Event 4.1</div>
    <div class="event">Event 4.2</div>
    <div class="event">Event 4.3</div>
    <div class="event overnight">Event 4.4</div>
  </div>
  <div class="day-column">
    <div class="event">Event 5.1</div>
    <div class="event">Event 5.2</div>
    <div class="event">Event 5.3</div>
    <div class="event">Event 5.4</div>
  </div>
</div>
like image 91
A Haworth Avatar answered Jan 25 '26 08:01

A Haworth