Search code examples
htmlcssalignment

Making HTML/CSS items stick/align to left and right edges of a row?


I want to have

  • a longish but not extremely long <h1> title, and as usual, I want it to align to left edge of page; and then,
  • I want a single normal word (so as first approximation, I've put it as <span>) on the same row, but I want it aligned right (i.e. so it sticks to right edge of the page; so essentially, it takes up the width it takes, and the rest of the row is filled by the heading); and finally
  • below that I want a paragraph. Something like:

<div id="dhead">
  <h1 id="htitle">Some longish title</h1>
  <span id="extra">Extra</span>
<div>

<p>
Hello. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Duis consequat blandit ultrices. Nullam tincidunt eu tortor vitae 
pretium. Vestibulum nec ultrices ipsum. Nulla tempus vitae eros 
varius rutrum. Sed condimentum convallis dui id interdum ...
</p>

... except in the above example, the heading and the word "extra" are not even on the same line.

I've tried the following flex approach as in CSS two divs next to each other :

#dhead {
  display: flex;
}
#extra {
  /* width: 200px; // don't want to set width of this explicitly; it should take the width of its content, the word) */
}
#htitle {
  flex: 1; /* Grow to rest of container (?) */
}
<div id="dhead">
  <h1 id="htitle">Some longish title</h1>
  <span id="extra">Extra</span>
<div>

<p>
Hello. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Duis consequat blandit ultrices. Nullam tincidunt eu tortor vitae 
pretium. Vestibulum nec ultrices ipsum. Nulla tempus vitae eros 
varius rutrum. Sed condimentum convallis dui id interdum ...
</p>

... and it is now even worse -- actually, awful -- since now the heading and the word AND the paragraph are on the same line (?!)

So, how can I align heading (to left) and word (to right) on the same line, with a paragraph below? And can I keep on using <h1>, <span> and <p>, or do I have to replace them with styled <div> to achieve something like this?


Solution

  • Option 1. Place span inside your h1

    Even though span is an inline element, because it directly follows a block-level element h1, it sits below the heading block.

    If it's semantically a part of h1, you might want to put it inside the heading and style the h1 element. Like the code snippet below.

    h1 {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
    }
    h1 span, p {
      font-size: 16px;
      font-weight: normal;
    }
    <div id="dhead">
      <h1 id="htitle">
        Some longish title
        <span id="extra">Extra</span>
      </h1>
    
      <div>
    
        <p>
          Hello. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis consequat blandit ultrices. Nullam tincidunt eu tortor vitae pretium. Vestibulum nec ultrices ipsum. Nulla tempus vitae eros varius rutrum. Sed condimentum convallis dui id interdum
          ...
        </p>

    Option 2. Use a ::after pseudo selector

    If the #extra doesn't serve a semantic, document-level purpose and solely an extra notation, you could simply use CSS ::after and do without a separate HTML markup. Like the snippet below.

    h1 {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
    }
    
    h1::after {
      content: "Extra";
      font-size: 16px;
      font-weight: normal;
    }
    <div id="dhead">
      <h1 id="htitle">
        Some longish title
      </h1>
    
      <div>
    
        <p>
          Hello. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis consequat blandit ultrices. Nullam tincidunt eu tortor vitae pretium. Vestibulum nec ultrices ipsum. Nulla tempus vitae eros varius rutrum. Sed condimentum convallis dui id interdum
          ...
        </p>