Create a table using a list of definitions and a grid diagram

Here is my attempt to create a pseudo table using <dl> and display: grid .

Actually, it works. The only problem is that I am forced to use an ugly way of defining strings. This is a completely manual way. Therefore, if I have 30 rows in the table, it will be really really stupid to repeat dt + dd + ... + dd for each of them.

How can this problem be fixed?

(I do not want to use real tables, because this is for Markdown).

 dl { display: grid; grid-template-columns: repeat(3, 1fr); } dt { text-align: center; } dd { margin-left: 0; } dt, dd { border: 1px solid lightgray; padding: 0 1em; } /* Ugly part * (Red, yellow, and green colors are just for demo) */ dt { grid-row-start: 1; } dt + dd { grid-row-start: 2; color: rgb(244, 67, 54); } dt + dd + dd { grid-row-start: 3; color: rgb(255, 152, 0); } dt + dd + dd + dd { grid-row-start: 4; color: rgb(76, 175, 80); } 
 <dl> <dt><p>Term 1</p></dt> <dd> <p>Definition of term 1 long long long long</p> <p>Lorem ipsum...</p> <p>Lorem ipsum...</p> <p>Lorem ipsum...</p> </dd> <dd><p>Definition of term 1</p></dd> <dd><p>Definition of term 1</p></dd> <dt><p>Term 2</p></dt> <dd><p>Definition of term 2</p></dd> <dd><p>Definition of term 2</p></dd> <dd><p>Definition of term 2</p></dd> <dt><p>Term 3</p></dt> <dd><p>Definition of term 3</p></dd> <dd><p>Definition of term 3</p></dd> <dd><p>Definition of term 3</p></dd> </dl> 
+5
source share
3 answers

Assuming you are using Firefox or Chrome, but not IE / Edge: p, the solution here works with any number of terms and any number of definitions for each term:

➑️ Codepen

Explanations:

  • filling the grid column after the column ➑️ grid-auto-flow: column;
  • (grid elements) each member must be in line 1, so its definition is lower than it. dt { grid-row-start: 1 } acts as the "next column".
  • Create fairly explicit lines (say 50), but line N + 1 should show (have any height) only if any given member has at least N definitions (4 lines are visible if the maximum definitions for this member equal to 3. No 4) ➑️ grid-template-rows: repeat(50, min-content);
  • Then I tried to have the number of columns / terms undefined, but I could not achieve this with explicit columns (I needed something like "1fr if there is content other than 0 otherwise" with minmax (), min | max-content but to no avail). Worked like a charm with implicit columns: ➑️ grid-auto-columns: 1fr;

 dl { display: grid; grid-auto-flow: column; /* doesn't assume 3 terms but N */ grid-auto-columns: 1fr; grid-template-rows: repeat(50, min-content); /* doesn't assume 3 defs but M<50 */ } dt { grid-row-start: 1; /* reset, next column */ } 
+7
source

One alternative (cross-browser) approach is to give relative positioning of the list of parent definitions:

 dl {position: relative;} 

and then give each subelement an absolute position in the definition list.

 dt, dd {display: block; position: absolute;} 

(Naturally, since we are now using absolute positioning, this will only be a viable alternative if you have a good idea of ​​what maximum width of each data column and maximum height of each data row should be).

In this case, you still have to specify an explicit left value for each dt and dd , but the declaration is identical every time, except for the index (referenced three times), which increases so much ..

Example:

 Index 2: dt:nth-of-type(2), dt:nth-of-type(2) ~ dd {left: calc((1px + 1em + 200px + 1em + 1px) * (2 - 1));} Index 3: dt:nth-of-type(3), dt:nth-of-type(3) ~ dd {left: calc((1px + 1em + 200px + 1em + 1px) * (3 - 1));} Index 4: dt:nth-of-type(4), dt:nth-of-type(4) ~ dd {left: calc((1px + 1em + 200px + 1em + 1px) * (4 - 1));} 

and etc.

Working example:

 dl { position: relative; } dt { text-align: center; font-weight: bold; } dt, dd { display: block; position: absolute; width: 200px; height: 50px; min-height: 50px; margin-left: 0; border: 1px solid lightgray; padding: 0 1em; vertical-align: top; } dt { top: 0; } dd:nth-of-type(3n - 2) { top: 50px; height: 200px; color: rgb(244, 67, 54); } dd:nth-of-type(3n - 1){ top: 250px; color: rgb(255, 152, 0); } dd:nth-of-type(3n) { top: 300px; color: rgb(76, 175, 80); } /* LEFT CO-ORDINATES */ dt:nth-of-type(2), dt:nth-of-type(2) ~ dd { left: calc((1px + 1em + 200px + 1em + 1px) * (2 - 1)); } dt:nth-of-type(3), dt:nth-of-type(3) ~ dd { left: calc((1px + 1em + 200px + 1em + 1px) * (3 - 1)); } 
 <dl> <dt><p>Term 1</p></dt> <dd> <p>Definition of term 1 long long long long</p> <p>Lorem ipsum...</p> <p>Lorem ipsum...</p> <p>Lorem ipsum...</p> </dd> <dd><p>Definition of term 1</p></dd> <dd><p>Definition of term 1</p></dd> <dt><p>Term 2</p></dt> <dd><p>Definition of term 2</p></dd> <dd><p>Definition of term 2</p></dd> <dd><p>Definition of term 2</p></dd> <dt><p>Term 3</p></dt> <dd><p>Definition of term 3</p></dd> <dd><p>Definition of term 3</p></dd> <dd><p>Definition of term 3</p></dd> </dl> 
+2
source

Mostly based on FelipeAls answer, but simpler and without the need for artificial row counts.

Just change grid-auto-flow to a string and it will get easier.

 dl { display: grid; grid-auto-columns: 1fr; grid-auto-flow: row; } dt { grid-row: 1; background-color: lightgreen; } dt, dd { border: solid 1px silver; margin: 0; } 
  <dl> <dt><p>Term 1</p></dt> <dd> <p>A Definition of term 1 long long long long Lorem ipsum dolor sit amet, consectetur adipisicing elit. Non inventore impedit cum necessitatibus corporis, ratione culpa nesciunt corrupti recusandae voluptate, sint magni enim ullam quo, ipsum. Voluptatibus quos aliquid, optio!</p> <p>Lorem ipsum...</p> <p>Lorem ipsum...</p> <p>Lorem ipsum...</p> </dd> <dd><p>B Definition of term 1</p></dd> <dd><p>C Definition of term 1</p></dd> <dd>May the 4th</dd> <dt><p>Term 2</p></dt> <dd><p>A Definition of term 2</p></dd> <dd><p>B Definition of term 2</p></dd> <dd><p>C Definition of term 2</p></dd> <dt><p>Term 3</p></dt> <dd><p>A Definition of term 3</p></dd> <dd><p>B Definition of term 3</p></dd> <dd><p>C Definition of term 3</p></dd> </dl> 
+2
source

Source: https://habr.com/ru/post/1268132/


All Articles