Search code examples
htmlcsstextalignment

How does text alignments work in HTML/CSS


My Question is: How does alignment works for inline and inline-block elements? And how can I control this?

My goal is to align the content of the div to the same as the previous Text. But there is interesting alignment happen if you empty some elements or change their position.

It seem that the first character in the first-child of an inline/inline-block element is used to do the alignment on baseline. How can I specify which character or element is used for alignment?

 <p>
  <span>Text</span>

  <span class="box">
    <span class="icon">icon</span>
    <span class="content">content</span>
  </span>
</p>

Here is a fiddle to see what I mean: https://jsfiddle.net/u4kzhmpt/

.box {
  border: 1px solid black;
  display: inline-flex;
}

.icon {
  display: inline-block;
  padding: 20px;
  border-radius: 50%;
  background: gray;
}

.content {
  flex: 1;
  background: yellow;
  padding: 0 10px;
}
<p>
  <span>Text</span>

  <span class="box">
    <span class="icon">icon</span>
  <span class="content">content</span>
  </span>
</p>

<p>
  <span>Text</span>

  <span class="box">
    <span class="icon"></span>
  <span class="content">content</span>
  </span>
</p>

<p>
  <span>Text</span>

  <span class="box">
    <span class="icon">icon</span>
  <span class="content"></span>
  </span>
</p>

<p>
  <span>Text</span>

  <span class="box">
    <span class="content">content</span>
  <span class="icon">icon</span>
  </span>
</p>

<p>
  <span>Text</span>

  <span class="box">
    <span class="content">content</span>
  <span class="icon"></span>
  </span>
</p>

<p>
  <span>Text</span>

  <span class="box">
    <span class="content"></span>
  <span class="icon">icon</span>
  </span>
</p>

<p>
  <span>Text</span>

  <span class="box">
    <span class="content"></span>
  <span class="icon"></span>
  </span>
</p>



<p>
  <span>Text</span>

  <span class="box">
    <span class="icon">icon</span>
  <span class="content">content</span>
  </span>

  <span class="box">
    <span class="icon"></span>
  <span class="content">content</span>
  </span>

  <span class="box">
    <span class="icon">icon</span>
  <span class="content"></span>
  </span>

  <span class="box">
    <span class="content">content</span>
  <span class="icon">icon</span>
  </span>

  <span class="box">
    <span class="content">content</span>
  <span class="icon"></span>
  </span>

  <span class="box">
    <span class="content"></span>
  <span class="icon">icon</span>
  </span>

  <span class="box">
    <span class="content"></span>
  <span class="icon"></span>
  </span>
</p>


Solution

  • First how elements are aligned as sibling to inline elements. The first Element is used to align to baseline. If the first element does not contain text the element itself is aligned on baseline. If the first element contains text it will be aligned with that text.

    I recently found a solution. But this requires a helper element (.align).

    This element needs to be the first element in the Box to be able to align on the same baseline.

      <span class="box">
        <span class="content align"></span>
        <span class="icon">icon</span>
        <span class="content">content</span>
      </span>
    

    It can be styled by its own or use the same class as the aligned content. The element has to be invisible for the user and should also contain no content. The content is set to a zero-width-space. Without content align will not work.

    .align {
      margin-left: 0;
      margin-right: 0;
      border-left: 0;
      border-right: 0;
      padding-left: 0;
      padding-right: 0;
      width: 0;
    }
    .align::before {
      content: "\200B";
    }
    

    If no additional element should be used it is also possible to add style to the box itself.

    The box:before should be styled like the content with the additional invisibility part.

    .content, .box::before {
      /* style like your content */
      ...
    }
    
    .box::before {
      margin-left: 0;
      margin-right: 0;
      border-left: 0;
      border-right: 0;
      padding-left: 0;
      padding-right: 0;
      width: 0;
      content: "\200B";
    }
    

    Maybe there are some more styles needed in special cases to set to zero width.

    overflow: hidden does not seem to work. If overflow hidden is active, the alignment will not work anymore.