104

I've got a horizontal navigation bar made from an unordered list, and each list item has a lot of padding to make it look nice, but the only area that works as a link is the text itself. How can I enable the user to click anywhere in the list item to active the link?

#nav {
  background-color: #181818;
  margin: 0px;
  overflow: hidden;
}

#nav img {
  float: left;
  padding: 5px 10px;
  margin-top: auto;
  margin-bottom: auto;
  vertical-align: bottom;
}

#nav ul {
  list-style-type: none;
  margin: 0px;
  background-color: #181818;
  float: left;
}

#nav li {
  display: block;
  float: left;
  padding: 25px 10px;
}

#nav li:hover {
  background-color: #785442;
}

#nav a {
  color: white;
  font-family: Helvetica, Arial, sans-serif;
  text-decoration: none;
}
<div id="nav">
  <img src="/images/renderedicon.png" alt="Icon" height="57" width="57" />
  <ul>
    <li><a href="#">One1</a></li>
    <li><a href="#">Two</a></li>
    <li><a href="#">Three</a></li>
    <li><a href="#">Four</a></li>
  </ul>
</div>
<div>
  <h2>Heading</h2>
</div>
j08691
  • 204,283
  • 31
  • 260
  • 272
Curyous
  • 8,716
  • 15
  • 58
  • 83

11 Answers11

121

Don't put padding in the 'li' item. Instead set the anchor tag to display:inline-block; and apply padding to it.

Aaron Butacov
  • 32,415
  • 8
  • 47
  • 61
Stussa
  • 3,375
  • 3
  • 24
  • 35
  • `display: inline; zoom: 1;` in a conditional comment for IE6 and IE7 will replace `display: inline-block;` though yes, if list items are already floated, `display: block;` will be OK too – FelipeAls Jun 19 '10 at 06:06
  • That worked nicely only one complaint, it didn't seem to work with the :after selector. I wanted a `>` symbol to appear after my link text, but not put it in the content... I ended up just putting it in the content. Would be curious if there's a better way to accomplish that. – counterbeing Dec 10 '13 at 23:43
48

Define your anchor tag css property as:

{display:block}

Then the anchor will occupy the entire list area, so your click will work in the empty space next to your list.

JSK NS
  • 3,346
  • 2
  • 25
  • 42
suren
  • 481
  • 4
  • 2
13

Make the anchor tag contain the padding rather than the li. This way, it will take up all the area.

Aaron Butacov
  • 32,415
  • 8
  • 47
  • 61
  • 3
    I would also suggest moving the hover state to the anchor as well off of the li for better browser support. – NinjaBomb Jun 19 '10 at 05:40
13

Super, super late to this party, but anyway: you can also style the anchor as a flex item. This is particularly useful for dynamically sized/arranged list items.

a {
  /* This flexbox code stretches the link's clickable 
   * area to fit its parent block. */
  display:        flex;
  flex-grow:      1;
  flex-shrink:    1;
  justify-content: center;
}

(Caveat: flexboxes are obvs still not well supported. Autoprefixer to the rescue!)

crisis.sheep
  • 389
  • 4
  • 15
11

Use following:

a {
  display: list-item;
  list-style-type: none;
}
gdoron
  • 147,333
  • 58
  • 291
  • 367
Sabby62
  • 1,707
  • 3
  • 24
  • 37
7

Or you could use jQuery:

$("li").click(function(){
   window.location=$(this).find("a").attr("href"); 
   return false;
});
Kieran
  • 87
  • 1
  • 1
  • 3
    One can say that this solution is 'dirty jquery solution which is not needed because you can do it easily with css'. But to be honest - sometimes you find yourself in situation working with not-your-code and you simply don't have a time to get to know all DOM structure and css stylesheets (and trying to understand 'what coder was thinking'). So +1. – lemoid Sep 25 '15 at 12:16
  • Agree with @lemoid, we have to remember "pretty" solutions are not always practical in Real Life. – UncaAlby May 16 '19 at 15:47
1

You should use this CSS property and value into your li:

pointer-events:all;

So, you can handle the link with jQuery or JavaScript, or use an a tag, but all other tag elements inside the li should have the CSS property:

pointer-events:none;
danvitoriano
  • 1,181
  • 10
  • 12
0

Just simply apply the below css :

<style>
  #nav ul li {
    display: inline;
  }

  #nav ul li a {
    background: #fff;// custom background
    padding: 5px 10px;
  }
</style>
vabi
  • 1
  • 1
0

here is how I did it

Make the <a> inline-block and remove the padding from your <li>

Then you can play with the width and the height of the <a> in the <li>

Put the width to 100% as a start and see how it works

PS:- Get the help of Chrome Developer Tools when changing the height and width

0

If you have some constraint where you need to keep <li> structure as is and would like your a tag to take up the full area within the li element you can do the following:

a {
    display: flex !important;
    width: -webkit-fill-available;
    height: -webkit-fill-available;
    justify-content: center;
    align-items: center;
}
greaterKing
  • 317
  • 1
  • 4
  • 12
-2

Put the list item within the hyperlink instead of the other way round.

For example with your code:

<a href="#"><li>One</li></a>
gdoron
  • 147,333
  • 58
  • 291
  • 367
Spudious
  • 39
  • 1
  • 8
  • @DannyBeckett It's valid in HTML5. – Tek Jul 18 '15 at 18:04
  • 1
    @Tek [No it isn't](https://validator.w3.org/nu/?showsource=yes&useragent=Validator.nu%2FLV+http%3A%2F%2Fvalidator.w3.org%2Fservices&doc=data%3Atext%2Fhtml%3Bcharset%3Dutf-8%3Bbase64%2CPCFET0NUWVBFIGh0bWw%2BPGh0bWw%2BCjxoZWFkPjx0aXRsZT5UZXN0PC90aXRsZT48L2hlYWQ%2BCjxib2R5Pgo8YSBocmVmPSIjIj48bGk%2BT25lPC9saT48L2E%2BCjwvYm9keT4KPC9odG1sPg%3D%3D). – Danny Beckett Jul 18 '15 at 18:24
  • You're right, I was thinking of block elements allowed inside anchors but I didn't know ul children were one of the exceptions to the rule. http://www.w3.org/html/wg/drafts/html/master/introduction.html#restrictions-on-content-models-and-on-attribute-values Thanks for the speedy correction. – Tek Jul 18 '15 at 18:30
  • Oh no no no... your syntax and semantic markup just went out the window. Never do this again my friend, it just makes the web a horrible place. – Teodor Sandu Jul 29 '16 at 09:52