182

Let's say I want a way to display just the the center 50x50px of an image that's 250x250px in HTML. How can I do that. Also, is there a way to do this for css:url() references?

I'm aware of clip in CSS, but that seems to only work when used with absolute positioning.

2

6 Answers 6

187

As mentioned in the question, there is the clip css property, although it does require that the element being clipped is position: absolute; (which is a shame):

.container {
  position: relative;
}
#clip {
  position: absolute;
  clip: rect(0, 100px, 200px, 0);
  /* clip: shape(top, right, bottom, left); NB 'rect' is the only available option */
}
<div class="container">
  <img src="http://lorempixel.com/200/200/nightlife/3" />
</div>
<div class="container">
  <img id="clip" src="http://lorempixel.com/200/200/nightlife/3" />
</div>

JS Fiddle demo, for experimentation.

To supplement the original answer – somewhat belatedly – I'm editing to show the use of clip-path, which has replaced the now-deprecated clip property.

The clip-path property allows a range of options (more-so than the original clip), of:

  • inset — rectangular/cuboid shapes, defined with four values as 'distance-from' (top right bottom left).
  • circlecircle(diameter at x-coordinate y-coordinate).
  • ellipseellipse(x-axis-length y-axis-length at x-coordinate y-coordinate).
  • polygon — defined by a series of x/y coordinates in relation to the element's origin of the top-left corner. As the path is closed automatically the realistic minimum number of points for a polygon should be three, any fewer (two) is a line or (one) is a point: polygon(x-coordinate1 y-coordinate1, x-coordinate2 y-coordinate2, x-coordinate3 y-coordinate3, [etc...]).
  • url — this can be either a local URL (using a CSS id-selector) or the URL of an external file (using a file-path) to identify an SVG, though I've not experimented with either (as yet), so I can offer no insight as to their benefit or caveat.

div.container {
  display: inline-block;
}
#rectangular {
  -webkit-clip-path: inset(30px 10px 30px 10px);
  clip-path: inset(30px 10px 30px 10px);
}
#circle {
  -webkit-clip-path: circle(75px at 50% 50%);
  clip-path: circle(75px at 50% 50%)
}
#ellipse {
  -webkit-clip-path: ellipse(75px 50px at 50% 50%);
  clip-path: ellipse(75px 50px at 50% 50%);
}
#polygon {
  -webkit-clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%);
  clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%);
}
<div class="container">
  <img id="control" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="rectangular" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="circle" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="ellipse" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="polygon" src="http://lorempixel.com/150/150/people/1" />
</div>

JS Fiddle demo, for experimentation.

References:

9
  • 14
    amazing find, thanks a lot :) Just FYI, it is not as limited as one would think. If you have a image container div (id="img_container") around img tag, just make img_container position relative, and make img absolute, you can clip the image that way Commented Nov 25, 2011 at 11:00
  • "position: absolute; (which is shame)" Commented Mar 19, 2014 at 12:55
  • Not that I'm aware of, no. Commented Oct 13, 2014 at 20:44
  • 6
    clip is deprecated. Newer clip-path doesn't require positioning
    – eagor
    Commented Jan 15, 2015 at 12:09
  • 3
    while clip is deprecated many modern browsers do not yet support clip-path. developer.mozilla.org/en-US/docs/Web/CSS/clip-path Commented Nov 9, 2016 at 21:06
130

One way to do it is to set the image you want to display as a background in a container (td, div, span etc) and then adjust background-position to get the sprite you want.

3
  • 2
    Just to clarify, you’d set the width and height of the container td, div, span or whatever to 50px to make this work. Commented Apr 27, 2009 at 8:38
  • 7
    @Espo, This seems to be a fairly standard approach, however what if you have a sprite image which contains several individual images of size 32x32, and you want to display 1 of these on a div, span etc that is bigger than 32x32...setting the background-position no longer works. Commented May 30, 2013 at 12:01
  • 2
    @series0ne You could probably combine with background-size Commented Jun 19, 2015 at 15:13
45

Another alternative is the following, although not the cleanest as it assumes the image to be the only element in a container, such as in this case:

<header class="siteHeader">
  <img src="img" class="siteLogo" />
</header>

You can then use the container as a mask with the desired size, and surround the image with a negative margin to move it into the right position:

.siteHeader{
    width: 50px;
    height: 50px;
    overflow: hidden;
}

.siteHeader .siteLogo{
    margin: -100px;
}

Demo can be seen in this JSFiddle.

Only seems to work in IE>9, and probably all significant versions of all other browsers.

2
  • 2
    Although it is a bitc hacky, it has the plus side that this works in all browsers (clip is deprecated and clip-path does not work in IE) and that it works when You try to print the webpage (background images are skipped by default) Commented Dec 2, 2015 at 9:45
  • This is the only truely accross browsers method. All other ways have issues. "Clip" has been depreciated and background-position is not read accurately in all browsers.
    – Kareem
    Commented Jan 21, 2016 at 14:12
3

Adjust the background-position to move background images in different positions of the div:

div { 
  background-image: url('image url');
  background-position: 0 -250px; 
}
1
  • 1
    Type: backgroud-image -> background-image. I was wondering why is my browser not aware of such CSS property and finally I realised it was due to the type. Commented Oct 20, 2020 at 23:14
0

div{
width: 50px;
height: 50px;
background: no-repeat -100px -100px/500% url("https://qce.quantum.ieee.org/2022/wp-content/uploads/sites/6/2022/02/[email protected]")
    };
<html>
<head>
</head>
<body>
<div></div>
</body>
</html>

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Ethan
    Commented Jul 11, 2022 at 22:37
0

I ran into this problem just recently trying to work on one of my own projects for Codecademy. I found out that if you have an image and want to display only a portion of the picture you can position it by doing

'background-position: 95% 5%;'

Play around with the percentage to see what suits you best. But I believe that this works if you have already displayed your image as a background image.

Not the answer you're looking for? Browse other questions tagged or ask your own question.