It already works! (kinda)
text-align: right
is working! It just appears not to work because its surrounding element is so small that it doesn't have any visible effect.
Here's a quick mock-up, with header
in red, nav
in purple-ish and ul
in blue. Analogically to your code, we set nav {text-align: right}
. But as you can see, nav
is so small that it doesn't have any effect:
ul {list-style-type:none}
div, nav, li {display:inline-block}
nav {text-align:right}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
header {
padding: 4px;
background-color: lightcoral;
}
div, li {
border: 1px solid black;
background-color: white;
}
nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<header>
<div>Title</div>
<nav>
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</nav>
</header>
</main>
We can prove that nav
's size is the issue by testing text-align: right
with a larger (fixed) size:
ul {list-style-type:none}
div, nav, li {display:inline-block}
nav {
width: 12rem;
text-align: right;
}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
header {
padding: 4px;
background-color: lightcoral;
}
div, li {
border: 1px solid black;
background-color: white;
}
nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<header>
<div>Title</div>
<nav>
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</nav>
</header>
</main>
Let's fix it
There are a ton of ways to right-align ul
. I'll go over several, from outdated approaches to modern methods.
Recommended approaches
Prefer to use the following approaches that use modern and well-supported CSS properties.
CSS Grid
Since our design is supposed to be structured and layout-driven, we may want to choose CSS Grid for our solution.
With CSS Grid we can specify a grid and its dimensions. In our case, we want a 1 by 2 grid, where the element in the second column is right-aligned:
header {
display: grid;
grid-template-columns: repeat(2, auto);
align-items: center; /*Vertical align*/
}
header>div {justify-self:start} /*Horizontal align*/
nav {justify-self:end} /*Horizontal align*/
ul {list-style-type:none}
div, nav, li {display:inline-block}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
header {
padding: 4px;
background-color: lightcoral;
}
div, li {
border: 1px solid black;
background-color: white;
}
nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<header>
<div>Title</div>
<nav>
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</nav>
</header>
</main>
CSS Flexbox
We can also use Flexbox, which I personally recommend for flow-like and content-driven designs.
Since we want a one-dimensional (flow-like) layout, we can use Flexbox. Many find this easier than CSS Grid.
We specify a flex-parent, and tell it to lay out its children with as much space in between as possible:
header {
display: flex;
justify-content: space-between; /*Put space between children*/
align-items: center; /*Vertical align*/
}
ul {list-style-type:none}
div, nav, li {display:inline-block}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
header {
padding: 4px;
background-color: lightcoral;
}
div, li {
border: 1px solid black;
background-color: white;
}
nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<header>
<div>Title</div>
<nav>
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</nav>
</header>
</main>
Alternative approaches
These approaches are either outdated or playfully bad ways. Generally, these approaches are highly discouraged. I include them for educational purpose only, so that you can identify them and know not to use these.
Positioning
We can position the left- and right-aligned elements manually with position: absolute
.
To position them relative to header
, header
needs to have its position
property set to something different than static
:
#header-wrapper {position:relative}
nav {
position: absolute;
right: 0;
}
ul {list-style-type:none}
#title, nav, li {display:inline-block}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
header {
padding: 4px;
background-color: lightcoral;
}
#title, li {
border: 1px solid black;
background-color: white;
}
nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<header>
<div id="header-wrapper">
<div id="title">Title</div>
<nav>
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</nav>
</div>
</header>
</main>
As you can see, by using position: absolute
we take the element out of the flow. It is essentially on another "layer", and doesn't influence the "base layer's" layout. That is why the header doesn't automatically adjust to fit it inside.
Floating
We can simply tell nav
to float: right
. This is usually recommended for supporting content in documents, but can also be used to float elements to one side.
Floating an element aside makes it a no-block-level element, so other content can "flow around" it. If you want to stop this behaviour, you may have to use the clear-fix hack. This may be a point of confusion, so your editor might tell you to avoid using float
.
nav {float:right}
.clearfix::after {
content: "";
display: table;
clear: both;
}
ul {list-style-type:none}
div, /*nav,*/ li {display:inline-block}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
header {
padding: 4px;
background-color: lightcoral;
}
div, li {
border: 1px solid black;
background-color: white;
}
nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<header class="clearfix">
<div>Title</div>
<nav>
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</nav>
</header>
</main>
Since the parent element is artificially stretched to fit the floated element, vertically centering its children may be difficult for non-fixed lengths.
Tables!
In the early days of the web, many layouts were realized by misusing tables.
Tables allow us to specify rows and columns, and how to lay out content in the cells. However, tables are only intended for tabular data, not for layout!
#header {width:100%}
td:last-child {text-align:right}
ul {list-style-type:none}
li {display:inline-block}
/*IGNORE; make bounding boxes visible*/
* {
margin: 0;
padding: 0;
}
#header {
padding: 4px;
background-color: lightcoral;
}
td:first-child, li {
border: 1px solid black;
background-color: white;
}
#nav {
padding: 4px;
background-color: darkslateblue;
}
ul {
padding: 4px;
background-color: lightblue;
}
html {height: 100%}
body {
min-height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
<main>
<table id="header">
<tr>
<td>Title</td>
<td id="nav">
<ul>
<li>Button 1</li>
<li>Button 2</li>
</ul>
</td>
</tr>
</table>
</main>