Search code examples
htmlcssfirefoxtext-indent

Text-indent has effect on the first child span element of div?


here is the code: https://jsfiddle.net/zz89emkr/1/

.menu-items {
  width: 400px;
  text-indent: 5%;
}    
<div class="menu-items">
    <span>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus quia maiores voluptatum adipisci iusto perferendis earum quasi, accusamus magni temporibus alias consectetur, provident vel quis nesciunt expedita sit nemo aliquam?</span>
    <div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Illo quas esse eius. Quos atque ea necessitatibus labore est error hic. At quae veritatis sit aperiam debitis animi provident dolorum dolore?</div>
    <span>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Cumque, eaque atque adipisci, fugiat fuga maiores repellendus voluptas non explicabo odio et ut tenetur sint iusto minima unde. Ex, voluptas sed?</span>
</div>

I know that text-indent will not work on inline element, however, in this example, the first span will get text-indent. What's more, in firefox, the text-indent in the first span element is larger than that in the div element.


Solution

  • Text-indent has effect on the first child span

    No, actually the indentation has nothing to do with the span. Being that you have set text-indent on a block element - .menu-items - indentation will be applied before:

    1) The first element/node in the container - regardless of whether that element is inline or block or whether the element is text or other content (such as an image) and...

    2) All subsequent block level text elements in the container (*)(see below)

    .wpr {
      text-indent: 5%;
    }
    <div class="wpr">
      This is just a regular text node. However, since it's the <strong>first node</strong> in the container - it is indented (due to text-indent being set on the wrapper div)
      <p>This is some block level text - it's indented</p>
      <span>Here is some inline level text</span>
      <div>Here's some more block level text - again, indented</div>
      This text node is <strong>not indented</strong>
    </div>
    <hr>
    <div class="wpr">
      <img src="http://via.placeholder.com/350x150" alt=""> 
      <p>Notice that the image above is indented (it's the first element in the container) This block level text - so it's also indented</p>
      <span>Here is some inline level text</span>
      <div>Here's some more block level text - again, indented</div>
      This text node is <strong>not indented</strong>
    </div>

    What's more, in firefox, the text-indent in the first span element is larger than that in the div element

    Firstly, this discrepancy on firefox can only be reproduced when:

    1) The container element has a set width (less than the viewport width)

    2) text-indent is set with a percentage value

    3) The first element in container is not block level

    (All 3 criteria are present in the example fiddle you provided)

    This looks like a bug, since firefox renders the indentation (before the first element) as a percentage value of the viewport width instead of a percentage of the container width!

    Codepen Demo (Resize in firefox to see this - and keep your eye on the indentation of the first line)

    Being that The spec clearly states (bold mine):

    Percentages: refers to width of containing block

    ...I'd say that firefox is doing it wrong.


    (*) That's my understanding of what is said in the spec:

    Unless otherwise specified by the each-line and/or hanging keywords, only lines that are the first formatted line [CSS21] of an element are affected. For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.

    The spec elsewhere elaborates on the meaning of "first formatted line":

    The "first formatted line" of an element may occur inside a block-level descendant in the same flow (i.e., a block-level descendant that is not positioned and not a float). E.g., the first line of the DIV in <DIV><P>This line...</P></DIV> is the first line of the P (assuming that both P and DIV are block-level).