94

I want to add a background image on the right side of the list items, and want to have some padding from the right side as well, but I'm unable to do that. Please have a look at following example:

HTML:

<ul>
    <li>Hello</li>
    <li>Hello world</li>
</ul>

CSS:

ul{
    width:100px;  
}

ul li{
    border:1px solid orange;
    background: url("arrow1.gif") no-repeat center right;
}

ul li:hover{
     background:yellow url("arrow1.gif") no-repeat center right;
}

I know we can set the image position by pixels, but since each of the li has different width, I can't do that.

Here's JSFiddle link: http://jsfiddle.net/QeGAd/1/

user966582
  • 3,225
  • 4
  • 32
  • 33

9 Answers9

236

You can be more precise with CSS background-origin:

background-origin: content-box;

This will make image respect the padding of the box.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Mladen Janjetovic
  • 13,844
  • 8
  • 72
  • 82
  • 1
    you saved my Bootstrap modal from ruining my background images on my fixed-position jumbotron – Prid Jun 20 '19 at 17:32
  • Superb approach @MladenJanjetovic – Timothy Dalton Apr 23 '20 at 17:01
  • 2
    Doesn't this offset the top left of the background to inside the padding, but still go outside the padding in the bottom right? The `background-clip` answer seems better. – mikemaccana Jun 27 '20 at 21:06
  • You are a god. - – Ali Jul 16 '20 at 08:09
  • that is the answer – Andre Elrico Sep 23 '20 at 14:43
  • This should be marked as the accepted answer – Gabriel Linassi Dec 09 '20 at 14:34
  • This does not make the image respect the box padding on all 4 sides. It only repositions the image relative to the `background-position`. For example, if the padding is 5px and the image position is `center left`, this will move the image 5px from the left. It will not resize or crop the image by 5px on the top, bottom or right. – Jargs Mar 10 '21 at 19:11
  • @mikemaccana @Jargs you will need to combine both `background-origin` and `background-clip` in some cases where you want the background to be resized to fit the content-box but then _also_ cropped to fit the content-box as well. The first one does the resizing, while the second does the cropping. – ADTC Apr 11 '21 at 04:29
  • 1
    @mikemaccana To fix the image extending past the bottom/right border, you have to combine the `background-origin: content-box;` with `background-size: contain;` (or other similar size-constraining options). – Venryx Jun 29 '23 at 01:57
58

You can use percent values:

background: yellow url("arrow1.gif") no-repeat 95% 50%;

Not pixel perfect, but…

Juan G. Hurtado
  • 2,057
  • 16
  • 25
23

Use CSS background-clip:

background-clip: content-box;

The background will be painted within the content box.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Eduard Kolosovskyi
  • 1,396
  • 12
  • 18
11

Use background-position: calc(100% - 20px) center, For pixel perfection calc() is the best solution.

ul {
  width: 100px;
}

ul li {
  border: 1px solid orange;
  background: url("https://placehold.co/200x125/e16d65/FFFFFF/png") no-repeat calc(100% - 10px) center;
}

ul li:hover {
  background-position: calc(100% - 20px) center;
}
<ul>
  <li>Hello</li>
  <li>Hello world</li>
</ul>
Mo.
  • 26,306
  • 36
  • 159
  • 225
  • 1
    This is nice if you want custom padding for background. Ex.: `background-position: 5px 10px; background-size: calc(100%-10px) calc(100%-20px);` – Steffan Dec 13 '17 at 12:23
  • 2
    @Steffan "The + and - operators must always be surrounded by whitespace", so `background-size: calc(100% - 10px) calc(100% - 20px)` https://stackoverflow.com/questions/30678942/does-calc-work-for-background-size-of-image-in-css/30679082#30679082 – rofrol Jan 17 '22 at 20:37
4

You can achieve your results with two methods:-

First Method define position values:-

HTML

 <ul>
 <li>Hello</li>
 <li>Hello world</li>
 </ul>

CSS

    ul{
    width:100px;    
}

ul li{
    border:1px solid orange;
    background: url("http://www.adaweb.net/Portals/0/Images/arrow1.gif") no-repeat 90% 5px;
}


ul li:hover{
    background: yellow url("http://www.adaweb.net/Portals/0/Images/arrow1.gif") no-repeat 90% 5px;
}

First Demo:- http://jsfiddle.net/QeGAd/18/

Second Method by CSS :before:after Selectors

HTML

<ul>
<li>Hello</li>
<li>Hello world</li>

CSS

    ul{
    width:100px;    
}

ul li{
    border:1px solid orange;
}

ul li:after {
    content: " ";
    padding-right: 16px;
    background: url("http://www.adaweb.net/Portals/0/Images/arrow1.gif") no-repeat center right;
}

ul li:hover {
    background:yellow;
}

ul li:hover:after {
    content: " ";
    padding-right: 16px;
    background: url("http://www.adaweb.net/Portals/0/Images/arrow1.gif") no-repeat center right;
}

Second Demo:- http://jsfiddle.net/QeGAd/17/

Shailender Arora
  • 7,674
  • 2
  • 31
  • 35
3

You can just add the padding to tour block element and add background-origin style like so:

.block {
  position: relative;
  display: inline-block;
  padding: 10px 12px;
  border:1px solid #e5e5e5;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  background-origin: content-box;
  background-image: url(_your_image_);
  height: 14rem;
  width: 10rem;
}

You can check several https://www.w3schools.com/cssref/css3_pr_background-origin.asp

Volodymyr Khmil
  • 1,078
  • 15
  • 13
2

The only option to actuall have this made pixel perfect is to create some transparent padding within the GIF itself. That way you can actually align it to the right of the LI and still have the background padding you are looking for.

Dennis Jamin
  • 398
  • 1
  • 10
0

setting direction CSS property to rtl should work with you. I guess it isn't supported on IE6.

e.g

<ul style="direction:rtl;">
<li> item </li>
<li> item </li>
</ul>
hjindal
  • 588
  • 7
  • 16
0

Adding box-sizing: content-box seems to also work. Note that you may have to adjust the height, width, and background-size to account for padding with this method.

Elyse Dawson
  • 116
  • 2
  • 5