Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw lines of a tree structure

Tags:

I used css grid to output the exact structure of the element which is shown in the image. Only thing that is missing is the lines as you see in the image below. Most important thing is that the code is concise, clean and DRY. I was thinking about using pseudo-element, only it will not help to write readable code.

Please don't use SASS

.three {
  display: grid;
  grid-template-rows: repeat(7, 100px);
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 1em;
  
  grid-template-areas:
  
     ".  C  ."
     ".  .  B-1"     
     "A  B  B-2"     
     ".  .  B-3"
     ".  D  ."
     ".  E  .";
}

.A   { grid-area: A; }
.B   { grid-area: B; }
.C   { grid-area: C; }
.D   { grid-area: D; }
.E   { grid-area: E; }
.B-1 { grid-area: B-1; }
.B-2 { grid-area: B-2; }
.B-3 { grid-area: B-3; }

.unordered-list {
  background-color: lightgreen;
  list-style-type: none;
  display: flex;
  justify-content: center;
  align-items: center;
}
<ul class="three">
  <li class="unordered-list A">A</li>
  <li class="unordered-list B">B</li>
  <li class="unordered-list C">C</li>
  <li class="unordered-list D">D</li>
  <li class="unordered-list E">E</li>  
  <li class="unordered-list B-1">B-1</li>
  <li class="unordered-list B-2">B-2</li>
  <li class="unordered-list B-3">B-3</li>
</ul>
like image 338
Frontend employee Avatar asked Jul 18 '20 17:07

Frontend employee


2 Answers

This is my attempt using ::before and ::after:

.three {
  display: grid;
  grid-template-rows: repeat(7, 100px);
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 1em;
  width: 44rem;
  grid-template-areas: ".  C  ." ".  .  B-1" "A  B  B-2" ".  .  B-3" ".  D  ." ".  E  .";
}

li {
  position: relative;
}

.A {
  grid-area: A;
}

.B {
  grid-area: B;
}

.C {
  grid-area: C;
}

.D {
  grid-area: D;
}

.E {
  grid-area: E;
}

.B-1 {
  grid-area: B-1;
}

.B-2 {
  grid-area: B-2;
}

.B-3 {
  grid-area: B-3;
}

.A::after,
.B::after {
  content: "";
  position: absolute;
  right: 0;
  transform: translateX(100%);
  display: block;
  background: grey;
  width: 45px;
  height: 3px;
}

.B-1::before,
.B-3::before,
.C::before,
.D::before,
.E::before {
  content: "";
  position: absolute;
  left: 0;
  transform: translateX(-100%);
  display: block;
  background: grey;
  width: 20px;
  height: 3px;
}

.B::before,
.B-2::before {
  content: "";
  position: absolute;
  left: 0;
  transform: translateX(-23px);
  display: block;
  background: grey;
  width: 3px;
  height: 235px;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
}

.B::before {
  height: 583px;
  transform: translate(-23px, 58px);
}

.unordered-list {
  background-color: lightgreen;
  list-style-type: none;
  display: flex;
  justify-content: center;
  align-items: center;
}

li {
  border-top-left-radius: 5px;
  border-bottom-right-radius: 5px;
  width: 200px;
}
<ul class="three">
  <li class="unordered-list A">A</li>
  <li class="unordered-list B">B</li>
  <li class="unordered-list C">C</li>
  <li class="unordered-list D">D</li>
  <li class="unordered-list E">E</li>
  <li class="unordered-list B-1">B-1</li>
  <li class="unordered-list B-2">B-2</li>
  <li class="unordered-list B-3">B-3</li>
</ul>

It's not responsive but it get's the job done. If anyone could make it responsive I'd love to see it.

like image 189
Daniel_Knights Avatar answered Sep 21 '22 11:09

Daniel_Knights


I tried to solve your problem in order to show you the way you can do it but notice that you're viewing or running it in snippet in full screen or expand snippet otherwise lines wont fit


.three {
  display: grid;
  grid-template-rows: repeat(7, 100px);
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 1em;
  grid-template-areas: ".  C  ." ".  .  B-1" "A  B  B-2" ".  .  B-3" ".  D  ." ".  E  .";
}

.A {
  grid-area: A;
}

.B {
  grid-area: B;
}

.C {
  grid-area: C;
}

.D {
  grid-area: D;
}

.E {
  grid-area: E;
}

.B-1 {
  grid-area: B-1;
}

.B-2 {
  grid-area: B-2;
}

.B-3 {
  grid-area: B-3;
}

.unordered-list {
  background-color: lightgreen;
  list-style-type: none;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 300px;
  position: relative;
}

.A::before,
.B::before {
  content: '';
  position: absolute;
  left: 300px;
  width: 200px;
  height: 4px;
  background: #ccc;
}

.B-1::before,
.B-3::before,
.C::before,
.D::before,
.E::before {
  content: '';
  position: absolute;
  right: 300px;
  width: 80px;
  height: 4px;
  background: #ccc;
}

.row {
  background: #ccc;
  width: 4px;
}

.second {
  position: relative;
  top: 166px;
  right: 79.3px;
  height: 230px;
}

.first {
  position: relative;
  top: 50px;
  left: 356px;
  height: 580px;
}
<ul class="three">
  <li class="unordered-list A">A</li>
  <span class="first row"></span>
  <li class="unordered-list B">B</li>
  <li class="unordered-list C">C</li>
  <li class="unordered-list D">D</li>
  <li class="unordered-list E">E</li>
  <span class="second row"></span>
  <li class="unordered-list B-1">B-1</li>
  <li class="unordered-list B-2">B-2</li>
  <li class="unordered-list B-3">B-3</li>
</ul>
like image 37
Umutambyi Gad Avatar answered Sep 20 '22 11:09

Umutambyi Gad