Search code examples
csscross-browserfluid-layoutmultiple-columnsjustify

How do I create a row of justified elements with fluid spacing using CSS?


How do I create a row of block elements with auto widths using text-align:justify, display: flex, column-count and/or other CSS properties?


Solution

  • Use the following components:

    • A text-align:justify container for the row
    • An inline-block container for each column
    • An inline-block placeholder with width:100% to stretch the inside

    `

        /*Row container is justified*/
        #container { width: 100%; text-align: justify; }
    
        /*Column container and placeholder are inline-block*/
        object, span { display: inline-block; }
    
        /*Placeholder is stretched to enforce shrink-wrapping*/
        span { width: 100%; }
     
          <!--row-->
          <div id="container">
            <!--column-->
            <object>
              <!--content-->
              <div>
              foo
              </div>
            </object>
            <object>
              <div>
              bar
              </div>
            </object>
            <object>
              <div>
              baz
              </div>
            </object>
            <object>
              <div>
              bop
              </div>
            </object>
            <object>
              <div>
              bip
              </div>
            </object>
            <!--placeholder-->
            <span></span>
          </div>

    Or use a text-align:justify container with a nested inline-block and column-count row where column-count is a number equal to the number of child elements:

    #main, #container { width: 100%; }
    #main { text-align: justify; }
    #container { display:inline-block; } 
    #container { -moz-column-count: 5; -webkit-column-count: 5; column-count: 5;}
    <!--full width container-->
    <div id="main">
    
    <!--justified inline-block row-->
      <div id="container">
         <!--columns-->
          <div>
          foo
          </div>
          <div>
          bar
          </div>
          <div>
          baz
          </div>
          <div>
          bop
          </div>
          <div>
          bip
          </div>
      </div>
    </div>

    Or a full-width container with display:flex; flex-direction: row and columns with flex:auto:

    #flex-container {
    	display: -webkit-flex;
    	display: flex;
    	-webkit-flex-direction: row;
    	flex-direction: row;
      width: 100%;
    }
    
    #flex-container > .flex-item {
    	-webkit-flex: auto;
    	flex: auto;
    }
    <div id="flex-container">
        <div class="flex-item">Foo</div>
        <div class="flex-item">Bar</div>
        <div class="flex-item">Baz</div>
        <div class="flex-item">Bop</div>
        <div class="flex-item">Bip</div>
    </div>

    Or display:grid with auto for each column in grid-template-columns and justify-content: space-between:

    #grid-container {
      display: grid;
      grid-template-columns: auto auto auto auto auto;
      justify-content: space-between;
      }
        <div id="grid-container">
            <div>Foo</div>
            <div>Bar</div>
            <div>Baz</div>
            <div>Bop</div>
            <div>Bip</div>
        </div>

    Or display: inline-grid with auto for each column in grid-template-columns and text-align: justify:

    #grid-container {
      display: inline-grid;
      grid-template-columns: auto auto auto auto auto;
      width: 100%;
      text-align: justify;
      }
        <div id="grid-container">
            <div>Foo</div>
            <div>Bar</div>
            <div>Baz</div>
            <div>Bop</div>
            <div>Bip</div>
        </div>

    block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme.

    Some block-level elements may generate additional boxes in addition to the principal box: 'list-item' elements. These additional boxes are placed with respect to the principal box.

    non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes.

    Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.

    When the total width of the inline-level boxes on a line is less than the width of the line box containing them, their horizontal distribution within the line box is determined by the 'text-align' property. If that property has the value 'justify', the user agent may stretch spaces and words in inline boxes (but not inline-table and inline-block boxes) as well.

    References