3

I have the following HTML code:

<header>
    <h1>Title</h1>

    <nav>
        <ul>
            <li>One</li>
            <li>Two</li>
            <li>Three</li>
        </ul>
    </nav>
</header>

I am looking to turn this into a single line on the top of my web page by floating right the <nav>.

However, because the <h1> has a much bigger font size than the <li> elements the text gets misaligned. I want the elements to be aligned on the baseline. In a picture:

Visual description.

Note the red line for the baseline. This is what I have right now:

#float, #nofloat { width: 300px; }

ul, h1, nav, p { margin: 0; padding: 0; }

h1 {
  display: inline-block;
  font-size: 3rem;
}

nav { display: inline-block; }
ul { list-style-type: none; }
ul > li { display: inline; }
ul > li:after { content: " | "; }
ul > li:last-child:after { content: ""; }

#float nav { float: right; }
<p>Everything is aligned to baseline before floating:</p>
<div id="nofloat">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>

<p>But after floating it's messed up:</p>
<div id="float">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>
orlp
  • 112,504
  • 36
  • 218
  • 315
  • Downvoter, care to explain why my question _'does not show any research effort; it is unclear or not useful'_? – orlp May 06 '15 at 10:45
  • 1
    Hard to say why the down vote; your question is well posed, concise and shows a snippet/effort. Perhaps there is a similar question in the SO archive, but try searching for it... – Marc Audet May 06 '15 at 10:49
  • 2
    @MarcAudet I did search for duplicates, there were similar questions, but none that tried to align the text inside the blocks on the baseline. Regardless, if it's a duplicate, that's not a valid reason to downvote - the close button is for that (or flag button if you don't have enough reputation). – orlp May 06 '15 at 10:51
  • Sometimes, finding a pre-existing solution on SO is like finding a needle in a haystack; similar questions can be worded in such different ways that they would never come up in a search, no matter how creative your search terms are. – Marc Audet May 06 '15 at 10:55

2 Answers2

2

You can simply add text-align:right to your nav if you have a fixed width

#float,
#nofloat {
  width: 300px;
}

ul,
h1,
nav,
p {
  margin: 0;
  padding: 0;
}
h1 {
  display: inline-block;
  font-size: 3rem;
  width:auto;
}
nav {
  display: inline-block;
  width:200px
}
ul {
  list-style-type: none;
}
ul > li {
  display: inline;
}
ul > li:after {
  content: " | ";
}
ul > li:last-child:after {
  content: "";
}
#float nav {
 text-align:right
}
<p>Everything is aligned to baseline before floating:</p>
<div id="nofloat">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>

<p>But after floating it's messed up:</p>
<div id="float">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>

Plus since inline-block has gap issues (fixable) you can use use display:table/table-cell

#float,
#nofloat {
  width: 300px;
  display: table;
}

ul,
h1,
nav,
p {
  margin: 0;
  padding: 0;
}
h1 {
  display: table-cell;
  font-size: 3rem;
  width:auto;
}
nav {
  display: table-cell;
  width:200px
}
ul {
  list-style-type: none;
}
ul > li {
  display: inline;
}
ul > li:after {
  content: " | ";
}
ul > li:last-child:after {
  content: "";
}
#float nav {
 text-align:right
}
<p>Everything is aligned to baseline before floating:</p>
<div id="nofloat">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>

<p>But after floating it's messed up:</p>
<div id="float">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>
dippas
  • 58,591
  • 15
  • 114
  • 126
  • 1
    The `nav` doesn't have a fixed width. But using your answer I made this, which seems to work fine: https://jsfiddle.net/dnzdvwjo/ . – orlp May 06 '15 at 10:36
  • Yes thats the other solution, applying the `display:table` to `nav` parent instead `nav` grand parent, if you didnt wnt to use fixed `width` on your `nav`. – dippas May 06 '15 at 10:42
2

Your HTML mark-up lends itself to a solution using CSS tables.

Apply display: table to header, and set the width to 100% which will force it to take on the width of the parent container.

Apply display: table-cell to nav and set width: 1% to force it to have a shrink-to-fit width. To prevent text wrapping, set white-space: nowrap.

This will work fine as long as your title can fit in the remaining space, but you can probably adjust the details based on your layout.

#float, #nofloat { width: 300px; }

ul, h1, nav, p { margin: 0; padding: 0; }

h1 {
  display: inline-block;
  font-size: 3rem;
}

nav { display: inline-block; }
ul { list-style-type: none; }
ul > li { display: inline; }
ul > li:after { content: " | "; }
ul > li:last-child:after { content: ""; }

header {
  border: 1px dotted gray;
}

#float header {
  display: table;
  width: 100%; /* the parent div has a width */
}

#float nav { 
  display: table-cell;
  width: 1%; /* forces this cell to shrink-to-fit */
  white-space: nowrap;
  border: 1px dotted blue;
}
<p>Everything is aligned to baseline before floating:</p>
<div id="nofloat">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>

<p>But after floating it's messed up:</p>
<div id="float">
  <header>
    <h1>Title</h1>

    <nav>
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </nav>
  </header>
</div>
Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • How does this compare to the solution I found in response to dippas's answer? https://jsfiddle.net/dnzdvwjo/ The 1% width and `white-space` seems hacky compared to my solution. – orlp May 06 '15 at 10:40
  • Essentially the same, dippas posted his solution while I was working on my answer, so we both came up with the same technique. The only difference is that I handle the table-cell width a bit differently. – Marc Audet May 06 '15 at 10:46