Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inline <div> column elements with pure CSS

Tags:

html

dom

css

I have a table-like structure where the columns represent the logical entities. For my use case, it's the table rows that need to be visually grouped, preferably by flowing them inline.

Example source fragment:

<div>
  <div id="entity1" class="entities">
    <div>Ab</div>
    <div>Cdefg</div>
  </div>
  <div id="entity2" class="entities">
    <div>98224</div>
    <div>511</div>
  </div>
  <div id="entity3" class="entities">
    <div>αβγδ</div>
    <div>ε</div>
  </div>
</div>

Desired layout:

+----+-------+------+
| Ab | 98224 | αβγδ |
+----+--+----++---+-+
| Cdefg | 511 | ε |
+-------+-----+---+

Of course, it is easy to transform the document on the server-side purely for the presentation, but I wonder if I can keep the document hierarchy as it is and do the transformation on the (CSS) presentation layer. Is it at all possible?

like image 903
glts Avatar asked Feb 25 '12 20:02

glts


2 Answers

As mentioned in your comment and in the other answers, it's trivial to lay entire .entities elements as inline blocks or to float them in order to line up their contents in rows, resembling a proper table. (Ironically, you can't replicate this layout using CSS2.1 table properties.)

However, if you need to lay each content element inline such that each row does not act like a table row rather than simply a line of boxes, as shown in your diagram, it's not possible with your given structure due to the way inline formatting works in CSS. Restructuring your content to accommodate such a layout is as simple as arranging the content by row and not by column, which I'm sure you have covered so I won't get into that.

From the spec:

Inline-level elements are those elements of the source document that do not form new blocks of content; the content is distributed in lines (e.g., emphasized pieces of text within a paragraph, inline images, etc.). The following values of the 'display' property make an element inline-level: 'inline', 'inline-table', and 'inline-block'. Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context.

An inline formatting context can typically only be generated by a block container box:

A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes.

In your structure, the only possible block container boxes are generated by each div. So the first .entities contains its own two children, and likewise for the second and third for their own children. You cannot transfer child elements across different containing blocks that are siblings, therefore you cannot distribute children of different elements across the same line, even if you force all of them to display: inline or if you force the content elements to display: inline-block.

Note that the top-level div element creates an inline formatting context as well but it cannot be used by your inner elements in this manner for the same reason.

Also, to address this part of your bounty statement:

CSS does have quite a few devices that alter the flow and alignment of boxes.

Unfortunately, this isn't possible even with flexbox, as flex containers work similarly to block containers and are therefore subject to the same limitations described above with respect to inline-level descendants.

This may be doable to a certain extent with CSS regions, but I'm not familiar with that module, and there's too little support for it to be relevant at this time anyway (even compared to flexbox).

like image 91
BoltClock Avatar answered Sep 23 '22 18:09

BoltClock


How about this:

.entities{
display:inline-block;
}

but this gives the following format:

+-------+-------+------+
| Ab    | 98224 | αβγδ |
+-------+-------+------+
| Cdefg | 511   | ε    |   
+-------+-------+---+--+

if you want the format you desire, then you might want to change your HTML code up a bit:

    <div>
  <div id="entity1" class="entities">
    <span class="cell">Ab</span>        
    <span class="cell">98224</span>
    <span class="cell">αβγδ</span>
  </div>
  <div id="entity2" class="entities">
    <span class="cell">Cdefg</span>
    <span class="cell">511</span>
    <span class="cell">ε</span>
  </div>
  <div id="entity3" class="entities"> 
  </div>
</div>

CSS:

.cell{
display:inline-block;
}

this gives the following layout:

+----+-------+------+
| Ab | 98224 | αβγδ |
+----+--+----++---+-+
| Cdefg | 511 | ε |
+-------+-----+---+

well, if you want to use the exact same HTML as you provided then, the answer is no...

the exact one you wanted, hope it helped!

like image 37
Anshu Dwibhashi Avatar answered Sep 25 '22 18:09

Anshu Dwibhashi