4

How do I vertically center an image with css when I don't know what height of the image will be? The image, and thus the height, will be provided by the server at run-time, and it could be any number of heights. Knowing this, I created a div within a div, more or less following method 1 of the tutorial found here: http://phrogz.net/css/vertical-align/. But that only works when you know the height of the content you are trying to center, I believe. So how on earth do I vertically center this:

<div class="galleryItem">
    <a href="wherever">
    <img src="whatever" width="173" height="155">
       <div class="galleryTitle">
           <div class="galleryImg">
               <img src="centerMeVertically.jpg">
           </div>
       </div>
    </a>
</div>

Here is the CSS which is failing:

   .galleryItem {
    float: left;
    border-style: solid;
    border-width: 1px;
    border-color: #b78e18;
    margin: 7px 4px;
    padding: 5px;
    width: 173px;
    height: 190px;
    position: relative;
}

.galleryTitle {
    height: 33px;
    width: 173px;
    position: relative;
}

.galleryImg {
     width: 173px;
     height: 30px;
     position: absolute;
     top: 50%;
     margin-top: -15px;
 }

.galleryImg > img {
     display: block;
     margin-left: auto;
     margin-right: auto;
 }
Tepken Vannkorn
  • 9,648
  • 14
  • 61
  • 86
fildred13
  • 2,280
  • 8
  • 28
  • 52
  • I appreciate that, and I'm certainly considering it. But I really want to do it "the right way" and I'm hoping a guru here has some secret ninja-hacks to make it happen. I've sunk enough time into it now that it is more personal vendetta than job-requirement. Edit: And now I look silly for responding to a deleted comment. To sum up: table-layout - I know it is an option, but I'd rather not. – fildred13 Apr 17 '13 at 01:57
  • Correcting my previous comment, take a look at this one (kind of duplicate actually, correct me if I'm wrong: http://stackoverflow.com/questions/7206640/css-vertically-align-div-when-no-fixed-size-of-the-div-is-known) – Eran Medan Apr 17 '13 at 02:00
  • 1
    How about using positioning http://jsfiddle.net/m6GHX/ – Musa Apr 17 '13 at 02:06
  • @EranMedan that solution is perfect, except it absolutely blows up in internet explorer for me. Perfect in every other browser, and clearly it works on IE in many cases, but at least in my case something about the floating divs or something must be causing problems. – fildred13 Apr 17 '13 at 02:12
  • @Musa is that a cross-browser solution? Any idea how backwards compatible? – fildred13 Apr 17 '13 at 02:14
  • I doubt it, test it out and see. – Musa Apr 17 '13 at 02:15
  • Will do, but if it isn't then it isn't a solution. IE 7+ minimum. 8+ BARE minimum, and that is assuming on 7 it is passable. – fildred13 Apr 17 '13 at 02:16

6 Answers6

3

A table-cell has the ability to align its content to vertically center. So we need to change the behavior of div to table-cell by changing its 'display' property to 'table cell'.

Now please check with the below code, see the image in corresponding div gets vertically aligned to center.

.galleryImg {
   display: table-cell;
   height: 60px;
   vertical-align: middle;
   width: 173px;
}

Hope it will help you.

Prasanth K C
  • 7,073
  • 5
  • 39
  • 62
  • Yes, this answer is correct, but as I mentioned in previous comments I would love to do it WITHOUT relying on the old table-centering-methods, since I am trying to be forward-thinking and standards-compliant. Thanks for the answer though :) – fildred13 Apr 18 '13 at 14:30
  • 1
    I'm not sure there is another way to vertically center something with CSS other than this. It's rather dumb, but it might be the only way. There's nothing about it that goes against "standards" - it's all valid CSS. – Chris Barr Apr 19 '13 at 00:20
  • @ChrisBarr I did add another solution in my answer - you can use CSS3's new "flexbox" option. Though in fairness, I'd stick with table-cell myself. – daamsie Apr 22 '13 at 03:12
  • 1
    I've experimented with this a lot, cross-browser, back-compatible, and all that jazz. Moreover, I looked into Chris Barr's response about this being good with standards, and sure enough while actually USING tables is frowned upon, the display-properties are completely clear-skies. So thanks everyone, I learned a lot. For those who come after me with the same problem: just use the table display properties method. It works, and it is cross/backwards-compatible and up to standards to boot! – fildred13 May 06 '13 at 23:16
1

//JQuery

$(function(){
    // vertical align images
    $.fn.vAlign = function() {
        return this.each(function(i){
            var ah = $(this).height();
            var ph = $(this).parent().height();        
            var mh = Math.ceil((ph-ah) / 2); //var mh = (ph - ah) / 2;
            $(this).css('margin-top', mh);
            //console.log(mh);
        });
    };
    $('.galleryItem img').vAlign();
});
Pramod Bhoi
  • 197
  • 1
  • 7
  • This is very good. I would like to avoid using jquery and javascript if I can, if only to feel "clean" about it all. But if no pure CSS solution is found, I will certainly accept this answer, since I see no reason why it won't be bother cross-browser and backwards compatible. (<3 jQuery.) – fildred13 Apr 18 '13 at 14:28
1

Here is the live example ,how you can center image to any div There is some extra css for beautifying but u can ignore it

http://jsfiddle.net/pratswinz/vCBnD/

<div class="span2 cen_eventspan2">
            <figure class="span12 cen_event">
                <img class="img-polaroid-user" src="https://www.dropbox.com/s/j4x8plvaupv0ftp/AC_Feedback-box-buttons_unlcear_b.png" />
            </figure>
        </div>

/-----------------css--------------------/

.cen_event {
    background-color: #FFFFFF;
    border: 1px solid rgba(0, 0, 0, 0.2);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    height: 172px;
    line-height: 159px;
    padding: 4px;
    text-align: center;
    width: 182px;
}
.cen_event .img-polaroid-user {
    max-height: 160px;
    max-width: 172px;
    vertical-align: middle;
    border:1px solid #f00;

}
Pratswinz
  • 1,476
  • 11
  • 24
0

I would calculate first what is the difference in height between the container and image, then divide that in two and make that the margin-top

requiredMargin=(containerheight-imageheight)/2

You could do this through JS or server side would be even better to handle situations where people have JS turned off for whatever reason.

.galleryImg img {margin-top:<requiredMargin>px;}

That is a reliable method of doing it.

OR, the CSS3 way

If you want to only use CSS and are comfortable only supporting the latest browsers, then you can consider using Flexbox:

<div class="imageContainer">
    <img src="http://placehold.it/350x100">
</div>

<style>
.imageContainer {
   height:300px;
   display: -webkit-box;
    -webkit-box-align: center;
   display: -moz-box;
   -moz-box-align: center;
   display: -ms-flexbox;
   -ms-box-align: center; 
   display: box;
   box-align: center; 
}
</style>

http://jsfiddle.net/gp5Ry/1/

To support older browsers as well, you might consider using Flexie. Though I haven't used this myself, it seems like a good option.

daamsie
  • 1,539
  • 10
  • 15
  • But there is no way to do this with only html and css, which is unfortunate. – fildred13 Apr 18 '13 at 14:32
  • Well there is a way. You're just not accepting it as valid. The "display: table-cell;" only requires html and css and is perfectly legitimate. Not everything is always perfectly semantic in CSS. I wouldn't waste time overly worrying about that. – daamsie Apr 18 '13 at 23:58
  • @fildred13 after a bit more digging for you, I've updated the answer to provide another option that doesn't require any table-cell options. I'd personally still use the table-cell just to cover the older browsers though. But for the purist, this should tick all boxes. – daamsie Apr 19 '13 at 00:13
0

Use table display properties on your divs. It's not pretty, but it works.

http://jsfiddle.net/staircasebug/dv9RS/

.galleryTitle {
display: table;
width: 100%;
height: 300px;
background: #eee;
}

.galleryImg {
display: table-cell;
vertical-align: middle;
}

img {
margin: 0 auto;
display: block;
}
staircasebug
  • 144
  • 3
  • Thanks, unfortunatley I am looking for a non-table way to do it, as I mentioned in other comments. I'll update the main question with this caveat. – fildred13 Apr 18 '13 at 14:31
  • We're not using tables here, we're just adding css display properties to divs. – staircasebug Apr 19 '13 at 19:14
-3

Add following to the css;

vertical-align:central; or vertical-align:middle;

Sweety
  • 159
  • 3
  • 1
    a) there is no `vertical-align:central;` and b) this wouldn't work. – j08691 Apr 17 '13 at 03:00
  • better check it 1st before comment. There is vertical-align:central; and is working. – Sweety Apr 17 '13 at 04:57
  • vertical-align only works as expected on elements which are displayed in ways related to a table. While I'm aware of that solution, I am trying to be a little more standards-compliant by avoiding using a table for positioning. If you know a way to make vertical-align: central work on a non-table element, could you expand your answer and show us how? I'd consider you a genius, personally, and I would certainly start to offset your down votes :) – fildred13 Apr 18 '13 at 14:27
  • @fildred13 Try using following `position: relative; font-size: 11px; margin-top: expression(this.offsetHeight < this.parentNode.offsetHeight ? parseInt((this.parentNode.offsetHeight - this.offsetHeight) / 2) + "px" : "0");` I haven't tested it on IE7. Let me know if it's not working – Sweety Apr 22 '13 at 03:27