0

How can I center text vertically and horizontally in responsive (bootstrap) container? I've been playing around with various table and table-cell display methods, but cannot get anything to work correctly.

Here is the html, I'm trying to center the contents of the span tag over the image.

  • I need the image to control the size of the container's height, without it the container just collapses to the height of the line.
  • I cannot set a static height on the div>div>div either since it scales with the browser size/view.

HTML

<div class="row  media-thumbs">
    <div class="col-sm-4 col-xs-12">
        <div>
            <span>Some copy should go here</span>
            <a href="#">
                <img class="img-responsive" src="default-tile.gif">
            </a>
        </div>
    </div>
</div>

WORKING CODE

With Alexander's help/clues, I modified the plugin ( https://github.com/PaulSpr/jQuery-Flex-Vertical-Center )to get the correct width and height

(function( $ ){

    $.fn.flexVerticalCenter = function( onAttribute ) {

        return this.each(function(){

            var $this       = $(this);              // store the object
            //var attribute = onAttribute || 'margin-top'; // the attribute to put the calculated value on
                //alert($this.css('padding-top'));
            // recalculate the distance to the top of the element to keep it centered
            var resizer = function () {
                // get parent height minus own height and devide by 2
                $this.css({
                    'margin-top' : ((( $this.parent().height() - $this.height() ) / 2) - parseInt($this.css('padding-top')) ),
                    'width' : ($this.parent().width())
                });
            };

            // Call once to set.
            resizer();

            // Call on resize. Opera debounces their resize by default. 
            $(window).resize(resizer);

            // Apply a load event to images within the element so it fires again after an image is loaded
            $this.find('img').load(resizer);

        });

    };

})( jQuery );
Sean Kimball
  • 4,506
  • 9
  • 42
  • 73
  • 1
    For vertical centering, try this plugin: it's really simple and easy to implement. https://github.com/PaulSpr/jQuery-Flex-Vertical-Center – Alexander Lozada Feb 02 '14 at 01:44
  • Hmm, it's not working because it is in the same container as the image. – Sean Kimball Feb 02 '14 at 01:55
  • If the container around the image is the same height as the image, shouldn't it work? Perhaps make the span a display: block; and set the jQuery plugin to vertically center by using padding-top. Let me make sure I'm getting what you want to do correctly; something like the second box of [this](http://citycafescranton.com/) website, how the text is vertically and horizontally centered responsively? – Alexander Lozada Feb 02 '14 at 01:58
  • Actually I just did a bit of tinkering with the plugin, it seems to require that the parent element has a set height. However, maybe the real solution here is to write my own jquery plugin [or find one ;)] – Sean Kimball Feb 02 '14 at 02:08
  • Huh, I thought the containing element would be set to the same height as the image, or am I reading this wrong? – Alexander Lozada Feb 02 '14 at 02:14
  • *edit: I think I figured out what you mean. Is it possible to use a background image instead of an image element? – Alexander Lozada Feb 02 '14 at 02:22
  • Unfortunately, no on the background image. the image is what is forcing the container div to be of a certain height. which varies with screen size. :( – Sean Kimball Feb 02 '14 at 02:25
  • 1
    I think I might have got something to the same effect as what you were asking. Does this work? http://jsfiddle.net/piedoom/QaKgy/1/ – Alexander Lozada Feb 02 '14 at 02:28
  • It does work, I found the issue. the height of the parent div is not set until after the page is completely loaded [it appears] placing the code in the $(window).load(function(){ solves this neatly. – Sean Kimball Feb 02 '14 at 02:37
  • oh good! I'll make it an answer. – Alexander Lozada Feb 02 '14 at 02:45

3 Answers3

2

JSFiddle

Explanation:

CSS:

span
{
    position: absolute;  /* this makes the text able to be placed over the image without getting pushed over */
    width: 100%; /*set to 100% so text-align will fall in the center of the image*/
    text-align: center; /*text will be horizontally centered in the image*/
    color: white; /*purely aesthetic*/
}

img
{
    width: 100%;   /* The image is set to 100% to take up the container and be responsive */ 
}

Javascript:

I used a jQuery plugin called Flex Vertical Center (also available in vanilla javascript) to vertically center the <span>, as CSS can be impossibly bothersome. After including the javascript source in the HTML, the following code was simple call to the function:

$('span').flexVerticalCenter();
Alexander Lozada
  • 4,019
  • 3
  • 19
  • 41
  • Almost, I updated the plugin a little myself as the width 100% forces the div to be as wide as the column container. Plugin code added to my question. – Sean Kimball Feb 02 '14 at 03:02
  • Omg at last an instant solution for this horrible problem. I will totally use it every single time I come across vertical centering! Thanks!! – drake035 Dec 11 '15 at 18:31
  • Note to future readers: please consider using FlexBox instead! – Alexander Lozada May 15 '18 at 21:44
-1

Use text-align: center to center horizontally and you can try vertical-align: middle (thought there are a few gotchas with vertical alignment), or set a line-height equal to the parent container height.

helion3
  • 34,737
  • 15
  • 57
  • 100
-1

Depending on outer elements styles, a very effective method is margin: 0 auto; for elements you want to set horizontally centered. This method requires a defined width of the parent element. text-align:center; will work in most cases, as told Sean, but vertical-align:middle; needs a lot of css-work to the parent element. I try not to use this, it never works as expected, from scratch :-) I remember, if the parent element is set to a defined height and display:table-cell; it works, otherwise not.

ddlab
  • 918
  • 13
  • 28