|
1 | 1 | --- |
2 | 2 | comments: true |
3 | 3 | date: 2011-01-29 18:53:10 |
4 | | -last_modified_at: 2023-09-29 |
| 4 | +last_modified_at: 2025-06-04 |
5 | 5 | layout: post |
6 | 6 | slug: create-a-centred-horizontal-navigation |
7 | 7 | title: Create a centred horizontal navigation |
|
12 | 12 | - CSS |
13 | 13 | --- |
14 | 14 |
|
15 | | -<p class="c-highlight"><strong>N.B.</strong> This article is kind of old now. |
16 | | -While the technique definitely still works, I’d recommend looking into <a |
17 | | -href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a> |
18 | | -for this nowadays. Happy coding!</p> |
19 | | - |
20 | 15 | {% include promo.html %} |
21 | 16 |
|
22 | | -Centring block level elements is easy, just define a width and set `margin: |
23 | | -0 auto;`, but what if you don’t know that fixed width? You could use |
24 | | -`text-align: center;` but that won’t work on 100%-width block-level elements |
25 | | -either… that’ll only work on text-level elements. |
| 17 | +This article was originally written in 2011 and used `text-align`ment and |
| 18 | +`display: inline;` to manipulate lists as text-level, inline elements. However, |
| 19 | +in 2025, I completely rewrote it to utilise Flexbox: the much more suitable |
| 20 | +approach for the times. |
26 | 21 |
|
27 | | -Defining explicit widths and heights should always be avoided wherever possible, |
28 | | -as doing so will make the document a lot less future-proof, flexible and |
29 | | -extensible… Suppose you have four items in your navigation menu--you can work |
30 | | -out the width of these and use `margin: 0 auto;` to centre them. Adding a fifth |
31 | | -will increase the width, meaning you’d need to alter the CSS, too. This is far |
32 | | -from ideal, and more so with a CMS to power the site (a client can add pages, |
33 | | -but perhaps can’t edit CSS). |
| 22 | +It massively simplified the amount of CSS needed to build a horizontally centred |
| 23 | +nav, so while this post may now seem a little underwhelming, it does serve as |
| 24 | +a great example of just how powerful CSS has gotten in the last decade. |
34 | 25 |
|
35 | | -However, there is a way to have a centred horizontal navigation without knowing |
36 | | -an explicit width, and without adding CSS. It’s also remarkably easy. |
| 26 | +```html |
| 27 | +<ul class=c-nav> |
37 | 28 |
|
38 | | -The markup: |
| 29 | + <li class=c-nav__item> |
| 30 | + <a href=# class=c-nav__link>Home</a> |
| 31 | + </li> |
| 32 | + |
| 33 | + <li class=c-nav__item> |
| 34 | + <a href=# class=c-nav__link>About</a> |
| 35 | + </li> |
| 36 | + |
| 37 | + <li class=c-nav__item> |
| 38 | + <a href=# class=c-nav__link>Work</a> |
| 39 | + </li> |
| 40 | + |
| 41 | + <li class=c-nav__item> |
| 42 | + <a href=# class=c-nav__link>Clients</a> |
| 43 | + </li> |
| 44 | + |
| 45 | + <li class=c-nav__item> |
| 46 | + <a href=# class=c-nav__link>Content</a> |
| 47 | + </li> |
39 | 48 |
|
40 | | -```html |
41 | | -<ul class="nav"> |
42 | | - <li><a href="/">Home</a></li> |
43 | | - <li><a href="/about/">About</a></li> |
44 | | - <li><a href="/services/">Work</a></li> |
45 | | - <li><a href="/clients/">Clients</a></li> |
46 | | - <li><a href="/contact/">Contact</a></li> |
47 | 49 | </ul> |
48 | 50 | ``` |
49 | 51 |
|
50 | | -Pretty standard, an unordered list of menu items. The CSS is where it’s at. |
51 | | -I have highlighted the bits that do the majority of the work: |
| 52 | +Pretty standard, an unordered list of menu items. The CSS is where it’s at: |
52 | 53 |
|
53 | 54 | ```css |
54 | | -.nav { |
55 | | - border: 1px solid #ccc; |
56 | | - border-width: 1px 0; |
57 | | - list-style: none; |
58 | | - margin: 0; |
59 | | - padding: 0; |
60 | | - text-align: center; /* « The magic. */ |
| 55 | +.c-nav { |
| 56 | + border: 1px solid #ccc; |
| 57 | + border-width: 1px 0; |
| 58 | + list-style: none; |
| 59 | + margin: 0; |
| 60 | + padding: 0; |
| 61 | + |
| 62 | + display: flex; |
| 63 | + justify-content: center; |
| 64 | + gap: 10px; |
61 | 65 | } |
62 | 66 |
|
63 | | -.nav li { |
64 | | - display: inline; /* « More magic. */ |
65 | | -} |
| 67 | + .c-nav__item { } |
66 | 68 |
|
67 | | -.nav a { |
68 | | - display: inline-block; /* « Last bit of magic. */ |
69 | | - padding: 10px; |
70 | | -} |
| 69 | + .c-nav__link { |
| 70 | + display: block; |
| 71 | + } |
71 | 72 | ``` |
72 | 73 |
|
73 | | -What I’ve done here is simply create a navigation list and given it a border top |
74 | | -and bottom (purely to highlight its centred text). Instead of floating the |
75 | | -_block-level_ `<li>`s left I’ve given them `display: inline;`, that is to say |
76 | | -they no longer occupy 100% the available width and they now stack up nicely |
77 | | -against each other. |
| 74 | +The workhorses here are simply `display: flex;` and `justify-content: center;`. |
| 75 | +This creates a Flex context and forces items to pack from the centre outward. |
78 | 76 |
|
79 | | -Next we use (the much underused) `display: inline-block;` to make sure the links |
80 | | -themselves don’t break onto new lines but still obey any padding values |
81 | | -accordingly. Here I have given them a larger hit area by adding `padding: 10px;` |
82 | | - |
83 | | -You could have, if you wanted, applied inline-block to the `<li>`s. however |
84 | | -IE6-7 will only allow `inline-block` to work on elements that are inherently |
85 | | -inline elements. `display: inline-block;` will not work on block-level elements. |
| 77 | +`gap` optionally spaces the items by `10px`, which creates an un-clickable |
| 78 | +‘dead’ zone between each link. Whether you want this or not is entirely up to |
| 79 | +you, so feel free to modify or exclude to suit your needs. |
86 | 80 |
|
87 | 81 | ## [Demo](/demos/centred-nav/) |
88 | 82 |
|
89 | | -[Here’s a quick demo](/demos/centred-nav/). Try using Firebug or similar to add |
90 | | -other list items on the fly, and watch as they seamlessly centre in the list. I |
91 | | -have tested this in IE7-8 to find it works perfectly. I haven’t checked IE6 but |
92 | | -I imagine it’ll be fine. |
93 | | - |
94 | | -## Update |
95 | | - |
96 | | -You asked and I heard; I have made [a CSS powered dropdown version of this](/demos/centred-nav/dropdown.html) |
97 | | -for you. The line `top: 100%;` will make the dropdown work in IE7, but kinda |
98 | | -ruins the experience a little in all other browsers. Whether you leave it in or |
99 | | -not is up to you. Again, view source for the how-to… |
| 83 | +[Here’s a quick demo](/demos/centred-nav/)! It works in all major current |
| 84 | +browsers. |
0 commit comments