Reputation: 361
Bonjour,
I would like to make sure to always have the same padding in <li>
, but when it's a link that the padding is in the <a>
(for large selection area).
li a {
padding: 1rem;
}
li:not(a) {
padding: 1rem;
}
<ul>
<li><a href='#'>Text</a></li>
<li>Text</li>
<li><a href='#'>Text</a></li>
</ul>
<a>
when it exists and no more in the <li>
<a>
the padding is in the <li>
Upvotes: 5
Views: 99
Reputation: 7291
There are few ways to do this, Mr Lister's answer is sufficient but I'm opposed to using negative margins so thought I'd offer another couple of options.
CSS Only (works in all browsers):
In this example, I've added a span around all li contents that are not <a>
's. I use calc to work out a height we want each <li>
.
There is also a CSS variable, this is just so you can change the padding in one place and can be left out if need be.
:root {
--li-padding: 1em;
}
li {
height: calc(100% + (var(--li-padding) * 2));
line-height: calc(100% + (var(--li-padding) * 2));
background: tomato;
}
li>* {
padding: 0 var(--li-padding);
}
li a {
display: inline-block;
background: rgba(255, 255, 255, 0.6);
}
<ul>
<li><a href="#">Line 1</a></li>
<li><span>Line 2</span></li>
<li><a href="#">Line 3</a></li>
</ul>
CSS Only (works in no browsers, yet):
This is a proposed standard for CSS Level 4, currently, it's not in any browsers but I thought it worth mentioning just for future proofing.
li:not(::has(> a)) {
padding: 1em;
}
li>a {
padding: 1em;
}
<ul>
<li><a href="#">Line 1</a></li>
<li>Line 2</li>
<li><a href="#">Line 3</a></li>
</ul>
Use Javascript:
Using javascript we can look through all the <li>
tags and decide what we want to do depending on what they contain, here's a quick example (again I used colour to show where the <a>
tags start).
let liSelector = document.querySelectorAll('li');
for (let i = 0; i < liSelector.length; i++) {
let str = liSelector[i].innerHTML;
if (str.includes("</a>")) {
liSelector[i].querySelector('a').style.padding = "1em";
liSelector[i].querySelector('a').style.display = "inline-block";
} else {
liSelector[i].style.padding = "1em";
}
}
li {
background: tomato;
}
li a {
background: rgba(255, 255, 255, 0.6);
}
<ul>
<li><a href="#">Line 1</a></li>
<li>Line 2</li>
<li><a href="#">Line 3</a></li>
</ul>
Summary: Mr Lister's answer should be all you need but I think it's good to have all your options as it helps understand the problem and solve other problems in the future, I hope you find this helpful 🙂
Upvotes: 2
Reputation: 46549
The solution is to use negative margins on the a
, and then the a
's padding will be in the same position as the li
's.
li {
padding: 1rem;
}
li a {
margin: -1rem;
padding: 1rem;
}
<ul>
<li><a href='#'>Text</a></li>
<li>Text</li>
<li><a href='#'>Text</a></li>
</ul>
Upvotes: 6
Reputation: 241
Here you go in jQUery :
$('li').each(function() {
if($(this).find('a').length) {
$(this).addClass('extrapadding');
}
});
.extrapadding a {
padding: 1rem;
}
li:not(.extrapadding) {
padding: 1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li><a href='#'>Text</a></li>
<li>Text</li>
<li><a href='#'>Text</a></li>
</ul>
Upvotes: 0