Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS - drawing lines between dynamically sized boxes


I created something like this using CSS.
The tricky thing here is that the height of the boxes can change if the text is too long.

So, I don't know how to make the dashed lines always behave this way, because the size of the boxes is dynamic.
(There should always be a line from the middle of the first box to the middle of the next box)

This is the HTML and CSS I'm using now.

  • I'm actually using SCSS, and React (I'm printing the "row" div 4 times)

     <div class="wrapper">
       <div class="row">
         <div class="bordered-div"></div>
         <div class="step">
           <img src="placeholder.svg" alt="img" />
           <div class="step-text">
             <div class="step-title">Title</div>
             <div class="step-description">Decsription...</div>
           </div>
         </div>
       </div>
     </div>
    
    .wrapper {
     display: flex;
     flex-direction: column;
     align-items: center;
     gap: 30px;
    
     .row {
       display: flex;
       position: relative;
    
       &:last-child {
         .bordered-div {
           height: 0;
         }
       }
    
       .bordered-div {
         position: absolute;
         top: 50%;
         left: -50px;
         width: 50px;
         border-top: 1px dashed #c2c9d5;
         border-left: 1px dashed #c2c9d5;
         height: calc(100% + 30px);
       }
    
       .step {
         background: blue;
         min-height: 118px;
         width: 322px;
         padding: 20px;
         border-radius: 8px;
         display: flex;
         gap: 20px;
         filter: drop-shadow(0px 0px 4px rgba(183, 183, 183, 0.15))
           drop-shadow(0px 4px 4px rgba(217, 217, 217, 0.25));
    
         svg {
           width: 16px;
           align-self: center;
           flex: none;
         }
    
         .step-title {
           font-size: 0.875rem;
           font-weight: 600;
         }
    
         .step-description {
           font-size: 0.875rem;
         }
       }
     }
    }
    

boxes with dashed lines

like image 478
Guy Ben David Avatar asked Aug 04 '21 09:08

Guy Ben David


People also ask

How do I create a line between two divs?

To add a horizontal line between two divs, just put <hr> between the divs. You can use CSS to style this in a variety of ways such as adjusting the color and thickness of the line as well as the top and bottom margins.


Video Answer


1 Answers

Here is a quick proof of concept with a minimal markup.
I believe that you don't need any extra empty div.

li {
  position: relative;
  list-style: none;
  max-width: 77ch;
  background-color: #ccc;
  border-radius: 1em;
  padding: 1em;
  margin-bottom: 1em;
  z-index: 2;
}

li:before {
  content:'';
  position: absolute;
  display: block;
  height: 0px;
  width: 2em;
  top: 50%;
  left: -2em;
  border-top: 1px red dashed;
  z-index: -1;
}

li:after {
  content:'';
  position: absolute;
  display: block;
  height: calc(100% + 1em);
  width: 0px;
  top: -0.5em;
  bottom: -0.5em;
  left: -2em;
  border-left: 1px red dashed;
  z-index: -1;
}

li:first-child:after {
  top: 50%;
}

li:last-child:after {
  bottom: 50%;
}

li:first-child:after,
li:last-child:after {
  height: calc(50% + 0.5em);
} 
<ul>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
  </li>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
  </li>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
       <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p> 
  </li>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
  </li>  
</ul>
  • First, I create a before pseudo element for every li. This pseudo element is used to create the horizontal line. I've use a border to create the dashed effect, but you could use a linear gradiant or anything else.
  • Then, I create a after pseudo element for every li. This pseudo element is used to create the vertical line. You need to adapt the height of the first and last ones.

Edit:

In the exemple, the margin between the li is 1em.
This 1em value is also used here:

li:after {
  top: -0.5em; // <-- 1em / 2
  bottom: -0.5em; // <-- 1em / 2
}

li:first-child:after,
li:last-child:after {
  height: calc(50% + 0.5em); // <-- calc(50% - 1em / 2)
}

If you change the margin between the li, you should update those values accordingly.
As yo'ure using sass, juste use a variable and you'll be good.

like image 89
Amaury Hanser Avatar answered Sep 30 '22 11:09

Amaury Hanser