13

So I have a div in my body that's a percentage width, and inside that a div with inline style as follows:

text-align: center; margin-left: -15px; margin-right: -15px; overflow: hidden;

As you can see, I have text-align: center; on, which would, if the image was small enough for the div, center the image. But the percentage width div is definitely not going to be big enough on my 1280x800 screen.

The negative margins are to overcome some padding on it's parent div. The overflow:hidden makes things look like I want, not messy. So, it's kind of working like I want it, like the header image at onenaught.com. It will become more visible on the right as you make the browser wider, but not expand from both sides, because it's not centered.

So, I wonder if there's any way to center the image. Know of any?

Edit: page here.

Mathijs Flietstra
  • 12,900
  • 3
  • 38
  • 67
Nathaniel
  • 375
  • 2
  • 4
  • 11

5 Answers5

33

You can actually do this by setting the margin-left and margin-right on the image to -100%.

Here's a jsFiddle demonstrating this. (use the one below instead, it's better)

It is an even better idea to set the margin-left and margin-right on the image to a much larger negative number, e.g. -9999%, as with the -100% value, the image starts to move off-center as soon as the div's containing element becomes less wide than 3 times the width of the div:

margin-left: -100% + the div's width: 100% + margin-right: -100% = 3x div width

You can check the difference in behaviour between this jsFiddle and the previous one by toggling the overflow to visible and resizing the result window to less than 300% of the width of the div.

Quoting @MaxOriola on the range of supported browsers (from the comments):

I've retested second fiddle ... in Firefox, Chrome, Safari (last versions) and Explorer 8, 9, 10. Works fine in all of them.

Note: Image element has to be displayed inline or inline-block and centered horizontally with text-align: center (on wrapper element).

// ALL of the JS below is for demonstration purposes only

$(document).ready(function() {
  $('a').click(function() {
    $('body > div').toggleClass('overflow');
  });
})
img {
  margin: 0 -9999% 0 -9999%;
}


/* ALL of the CSS below is for demonstration purposes only */

body {
  text-align: center;
  font-family: verdana;
  font-size: 10pt;
  line-height: 20pt;
}

body>div {
  margin: 0px auto;
  width: 40%;
  background-color: lightblue;
  overflow: hidden;
}

img {
  vertical-align: top;
}

.overflow {
  overflow: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>40% wide div [<a href="#">toggle overflow</a>]
  <div>
    <img src="http://via.placeholder.com/400x200" />
  </div>
  400px wide image
</div>
Mathijs Flietstra
  • 12,900
  • 3
  • 38
  • 67
  • 2
    +10 This totally works and saved a rewrite of the underlying HTML. – Dave Hilditch Jun 20 '14 at 17:33
  • Does someone knows the range of supported browsers? – jmarceli Aug 06 '15 at 09:09
  • 1
    I wish there was a way to bookmark answers. This is one of those rare gems that are not documented and saves hours of work. P.S. IMO this should have been an accepted answer. – MadOgre Dec 22 '15 at 06:35
  • Testing in Chrome, it only works if you don't set image width and height attributes. – Max Oriola Apr 04 '16 at 06:26
  • @MaxOriola, can you elaborate? I don't observe a difference in behaviour between [this fiddle](http://jsfiddle.net/c2ppS/271/) (with image width and height attributes set) and the one supplied in the answer. So I think it works fine in Chrome whether you set the image width and height attributes or not... – Mathijs Flietstra May 10 '16 at 20:48
  • 1
    Sorry, I tested outside jsFiddle and I can't reproduce it. Probably using first fiddle with very wide image. I've retested second fiddle (the one with margin: 0 -9999% 0 -9999%) in Firefox, Chrome, Safari (last versions) and Explorer 8, 9,10. Works fine in all of them. Thanks. – Max Oriola May 14 '16 at 06:25
28

One option would be to absolutely position the image with left: 50% and then use a negative margin-left on the image equal to half of the image's width. Of course, this requires the containing div to have its positioning set to relative or absolute in order to provide the proper container type for the image to be absolutely positioned within.

The other option (and probably better) is instead of using an image tag, just set the image as the background for the parent div, and use the background positioning CSS attributes to center it. Not only does this make sure it's centered without forcing absolute positioning, but it also automatically crops overflow, so the overflow attribute isn't necessary.

Amber
  • 507,862
  • 82
  • 626
  • 550
  • Marking answer because it mostly covers both answers submitted. Couldn't get things working with the background method, and haven't yer trued the absolute positioning. Thanks, though. – Nathaniel Sep 18 '09 at 04:20
  • +1 because the first solution will also work for non-images. The question does specify images, but I came here looking to centre a `div` in a too-small container. Thanks. – Johno Jun 07 '12 at 11:07
  • link seems broken found it here http://www.w3schools.com/cssref/pr_background-position.asp now, solution was "background-position:center;" thanks – John Aug 13 '15 at 08:08
5

Using css transform, for an image inside a container with overflow: hidden and a set width:

img {
    position: relative;
    left: 50%;
    transform: translateX(-50%);
    display: block; /* optional */
}

jsFiddle here (I borrowed part of Mathijs Flietstra's jsFiddle, so thanks).

Max Oriola
  • 1,296
  • 12
  • 8
2

consider using the image as a background ;)

use background-position to get what you want.

you may need a javascript solution to achieve consistent cross-browser results

Ahmed Khalaf
  • 1,220
  • 12
  • 28
  • I would encourage this solution if image is purely decorative. A `background-position: 50% 50%` works fine everywhere. – Max Oriola Dec 05 '16 at 09:16
2

I have found another solution

<style type="text/css">
    .container {
        width:600px; //set how much you want
        overflow: hidden; 
        position: relative;
     }
     .containerSecond{
        position: absolute; 
        top:0px; 
        left:-100%; 
        width:300%;
     }
     .image{
        width: 800px; //your image size 
     }           
</style>

and in body

<div class="container">
   <div class="containerSecond">
       <image src="..." class="" />
   </div>
</div>

This will center your image whenever your container is bigger or smaller. In this case your image should be bigger than 300% of container to not be centered, but in that case you can make with of containerSecond bigger, and it will work

Ruben
  • 290
  • 3
  • 14