Clip/Crop background-image with CSS

CssCss Sprites

Css Problem Overview


I have this HTML:

<div id="graphic">lorem ipsum</div>

with this CSS:

#graphic { background-image: url(image.jpg); width: 200px; height: 100px;}

The background image I'm applying is 200x100 px, but I only want to display a cropped portion of the background image of 200x50 px.

background-clip does not appear to be the right CSS property for this. What can I use instead?

background-position should not be used, because I'm using the above CSS in a sprite context where the image part I want to show is smaller than the element on which the CSS is defined.

Css Solutions


Solution 1 - Css

You can put the graphic in a pseudo-element with its own dimensional context:

#graphic {
  position: relative;
  width: 200px;
  height: 100px;
}
#graphic::before {
  position: absolute;
  content: '';
  z-index: -1;
  width: 200px;
  height: 50px;
  background-image: url(image.jpg);
}

#graphic {
    width: 200px;
    height: 100px;
    position: relative;
}
#graphic::before {
    content: '';
    
    position: absolute;
    width: 200px;
    height: 50px;
    z-index: -1;
    
    background-image: url(http://placehold.it/500x500/); /* Image is 500px by 500px, but only 200px by 50px is showing. */
}

<div id="graphic">lorem ipsum</div>

Browser support is good, but if you need to support IE8, use a single colon :before. IE has no support for either syntax in versions prior to that.

Solution 2 - Css

may be you can write like this:

#graphic { 
 background-image: url(image.jpg); 
 background-position: 0 -50px; 
 width: 200px; 
 height: 100px;
}

Solution 3 - Css

Another option is to use linear-gradient() to cover up the edges of your image. Note that this is a stupid solution, so I'm not going to put much effort into explaining it...

.flair {
  min-width: 50px; /* width larger than sprite */
  text-indent: 60px;
  height: 25px;
  display: inline-block;
  background:
    linear-gradient(#F00, #F00) 50px 0/999px 1px repeat-y,
    url('https://championmains.github.io/dynamicflairs/riven/spritesheet.png') #F00;
}

.flair-classic {
  background-position: 50px 0, 0 -25px;
}

.flair-r2 {
  background-position: 50px 0, -50px -175px;
}

.flair-smite {
  text-indent: 35px;
  background-position: 25px 0, -50px -25px;
}

<img src="https://championmains.github.io/dynamicflairs/riven/spritesheet.png" alt="spritesheet" /><br />
<br />
<span class="flair flair-classic">classic sprite</span><br /><br />
<span class="flair flair-r2">r2 sprite</span><br /><br />
<span class="flair flair-smite">smite sprite</span><br /><br />

I'm using this method on this page: https://championmains.github.io/dynamicflairs/riven/ and can't use ::before or ::after elements because I'm already using them for another hack.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDahieView Question on Stackoverflow
Solution 1 - CssBrentView Answer on Stackoverflow
Solution 2 - CsssandeepView Answer on Stackoverflow
Solution 3 - CssMingwei SamuelView Answer on Stackoverflow