Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Challenging diagram with breakout labels explanation

Tags:

html

css

I have some cryptic nomenclature labels for some products and I'd like to explain them using a diagram with breakout labels, something like that:

Breakout diagram example

That is, I have some sort of long and cryptic label ("A-253-QZ" in this example, in real world there are typically 8-10-12 components), and I need to explain its parts, that "A" means series designator, "253" is, for example, "max speed" and "QZ" is acceptable batteries type.

I need to generate these diagrams on the fly, so I'd prefer it to be laid out with HTML + CSS.

My best effort so far is a complex table that uses its borders to draw these breakout lines - JSBin. It looks like that:

HTML table rendering

I understand that it's quite suboptimal:

  • it uses HTML tables for formatting, that is evil
  • vertical lines are properly centered, but it generates hell of a columns to do it
  • horizontal lines are not aligned to center of the line, but to its bottom
  • horizontal lines do not touch the end of the explanation captions

Any ideas how to do it better / without tables / fix mentioned issues? Any ideas on better representation of a concept?

like image 913
GreyCat Avatar asked Oct 13 '15 10:10

GreyCat


3 Answers

Hope this is decent! LoL. Just a try, I know this is not the optimal:

Full Code

<table class="breakout">
  <tr>
    <td></td>
    <td colspan="2" class="comp label">A</td>
    <td class="label">-</td>
    <td colspan="2" class="comp label">253</td>
    <td class="label">-</td>
    <td colspan="2" class="comp label">QZ</td>
  </tr>
  <tr>
    <td rowspan="2" class="caption">series</td>
    <td class="ruler-hv"></td>
    <td></td>
    <td></td>
    <td class="ruler-v"></td>
    <td></td>
    <td></td>
    <td class="ruler-v"></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td class="ruler-v"></td>
    <td></td>
    <td></td>
    <td class="ruler-v"></td>
    <td></td>
  </tr>
  <tr>
    <td rowspan="2" class="caption">max speed</td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-hv"></td>
    <td></td>
    <td></td>
    <td class="ruler-v"></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td class="ruler-v"></td>
    <td></td>
  </tr>
  <tr>
    <td rowspan="2" class="caption">batteries type</td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-h"></td>
    <td class="ruler-hv"></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

Fiddle: http://output.jsbin.com/yalacoceda

like image 67
Praveen Kumar Purushothaman Avatar answered Oct 19 '22 15:10

Praveen Kumar Purushothaman


You are trying to display the following information:

series: A
max-speed: 253
batteries type: QZ

It would be appropriate if you change your markup to dl, dd and dt. The following example displays the data just the way you want but with following constraints:

  • Width and height of labels is fixed
  • Height of values is fixed

dl, dt, dd {
  margin: 0;
}
dl {
  padding-top: 48px;
  overflow: hidden;
}
/* labels */
dt {
  float: left;
  clear: left;
  width: 96px;
  line-height: 24px;
  background-color: #FFFFFF;
}
/* values */
dd {
  display: inline-block;
  position: relative;
  top: -48px;
  line-height: 48px;
  border-bottom: 1px solid;
  font-size: 32px;
}
/* connector */
dd::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: 100%;
  right: 50%;
  left: -999px;
  border-right: 1px solid;
  border-bottom: 1px solid;
}
dd:nth-of-type(1)::after {
  height: 12px;
}
dd:nth-of-type(2)::after {
  height: 36px;
}
dd:nth-of-type(3)::after {
  height: 60px;
}
<dl>
  <dt>series</dt>
  <dd>A</dd>
  <dt>max-speed</dt>
  <dd>253</dd>
  <dt>batteries type</dt>
  <dd>QZ</dd>
</dl>

Here is a CodePen which uses LESS variables. You can edit the width and height variables to re-generate CSS.

like image 4
Salman A Avatar answered Oct 19 '22 17:10

Salman A


Here is my try. Just trying to be semantic, as few extra elements as I could

.container {
  width: 400px;
  height: 200px;
}

.container * {
  display: inline-block;
  float: left;
  margin: 4px;
  position: relative;
}

.item:first-of-type {
  margin-left: 200px;
}


.item:before {
  content: attr(data-label);
  text-align: right;
  position: absolute;
  right: calc(100% + 10px);
  height: 30px;
  width: 200px;
} 

.item:nth-of-type(1):before {
  bottom: -50px;
} 

.item:nth-of-type(2):before {
  bottom: -80px;
} 

.item:nth-of-type(3):before {
  bottom: -110px;
} 

.item:after {
  content: "";
  position: absolute;
  width: 100%;
  left: 0px;
  box-shadow: inset 0px 2px 0px blue;
  background-image: linear-gradient(blue, blue), linear-gradient(blue, blue);
  background-position: 50% 0%, 0% calc(100% - 10px);
  background-size: 2px calc(100% - 10px), 50% 2px;
  background-repeat: no-repeat;
} 

.item:nth-of-type(1):after {
  top: 30px;
  height: 30px;
  z-index: -1;
} 

.item:nth-of-type(2):after {
  top: 30px;
  height: 60px;
  z-index: -2;
} 

.item:nth-of-type(3):after {
  top: 30px;
  height: 90px;
  z-index: -3;
}
<div class="container">
    <div class="item" data-label="Category 1">FIRST</div>
    <p>-</p>
    <div class="item" data-label="Category 2">SEC</div>
    <p>-</p>
    <div class="item" data-label="Category 3">THIRD</div>
</div>

Another example, a little better, and shrink-wrapping the container.

The pseudo elements are no longer absolute positioned, so the container can adjust the size. And avoiding some calc uses, that always are harded than maintain than padding, for instance.

I still need a padding set before hand on the container, though. Can't see how to avoid this ...

.container {
  border: solid 1px red;
  display: inline-block;
  padding-left: 200px;
}

.container * {
  display: inline-block;
  float: left;
  margin: 4px;
  position: relative;

}

.item:before {
  content: attr(data-label);
  text-align: right;
  position: absolute;
  display: inline-block;
  right: 100%;
  height: 30px;
  width: 200px;
  padding-right: 8px;
} 

.item:nth-of-type(1):before {
  top: 30px;
} 

.item:nth-of-type(2):before {
  top: 55px;
} 

.item:nth-of-type(3):before {
  top: 85px;
} 

.item:after {
  content: "";
  display: inline-block;
  width: 100%;
  left: 0px;
  box-shadow: inset 0px 2px 0px blue;
  background-image: linear-gradient(blue, blue), linear-gradient(blue, blue);
  background-position: 50% 0%, 0% calc(100% - 10px);
  background-size: 2px calc(100% - 10px), 50% 2px;
  background-repeat: no-repeat;
} 

.item:nth-of-type(1):after {
  height: 30px;
} 

.item:nth-of-type(2):after {
  height: 60px;
} 

.item:nth-of-type(3):after {
  height: 90px;
} 
<div class="container">
    <div class="item" data-label="Category 1">FIRST</div>
    <p>-</p>
    <div class="item" data-label="Category 2">SEC</div>
    <p>-</p>
    <div class="item" data-label="Category 3">THIRD</div>
</div>
like image 3
vals Avatar answered Oct 19 '22 17:10

vals