Centering Responsive Images within a Table

I’ve successfully created a responsive table with images that are responsive inside of a table as seen here: http://jsfiddle.net/JoshuaLewis/pob8qp6h/10/

Here is the CSS I used to make it responsive:

.image img {
    height: auto !important;
    width: auto !important;
    max-width: 100%;
}

table {
    width: 100%;
    table-layout: fixed;
}

The problem is that I cannot center them like I can with a non
specified width table. I’m wanting my images centered close together
like this: http://jsfiddle.net/JoshuaLewis/ou2L6b34/10/

According to my understanding of responsive design, a table is
required to have a 100% width. This makes the images separate from each
other, I want them together. It looks okay in the responsive example,
but in other scenario’s it looks very strange having them far separated.

Joshua, would you be OK with a CSS based table or do you require an HTML table? The latter is not really recommended unless there is no other choice.

Joshua, I’m tossing this back to you in your HTML table format. I think that the styles assigned to the .image box would probably work better if selectively assigned to the table-cell and the box deleted. Check out the text at really narrow widths to see why. I recommend a CSS based design as being more semantically correct.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/stylesheet.css">
    <title>template</title>
<!--
http://www.sitepoint.com/community/t/centering-responsive-images-within-a-table/101814
Centering Responsive Images within a Table
Oct 24, 12:33 AM
Joshua
-->
    <style type="text/css">

body {font-family:Verdana,Arial,Helvetica,sans-serif;}

.center {
    width:80%;
    table-layout:fixed;
    border-spacing:10px 0;
    text-align:center;
    margin-left:auto;
    margin-right:auto;
}

.center td {
    vertical-align:top;
    text-align:center;
    background:#444;
    border-radius:5px;
    color:#fff;
}

.image {
    overflow:hidden;
    transition:all 0.3s linear 0s;
    border-left:1px solid #222222;
    border-right:1px solid #222222;
    border-top:1px solid #222222;
    padding:5px 5px 0;
}

.image img {
    border: 1px solid #222222;
    border-radius: 3px;
    box-shadow: 0 0 3px 2px #222222;
    width:100% !important;
    height:auto !important;
}

.caption {
    background: linear-gradient(to bottom, #404040 0%, #353535 100%) repeat scroll 0 0 #393939;
    border-bottom: 1px solid #111111;
    border-radius: 0 0 5px 5px;
    border-top: 1px solid #494949;
    box-shadow: 2px -1px 21px -3px #000000;
    display: block;
    padding: 3px 0 5px;
    position: relative;
    font-size: 12px;
    margin-left: -5px;
    margin-right: -5px;
}

    </style>
</head>
<body>

<table class="center">
    <tbody>
        <tr>
            <td>
                <div class="image">
                    <a href="http://www.summitpost.org/sharkfin-tower-from-boston-basin/860738"><img width="200" height="150" data-src="http://www.summitpost.org/images/medium/860738.jpg" src="http://www.summitpost.org/images/small/860738.jpg" alt="Sharkfin Tower from Boston Basin"></a><br>
                    <span class="caption">Sharkfin Tower</span>
                </div>
            </td>
            <td>
                <div class="image">
                    <a href="http://www.summitpost.org/mixup-peak-s-north-face/860741"><img width="200" height="150" data-src="http://www.summitpost.org/images/medium/860741.jpg" src="http://www.summitpost.org/images/small/860741.jpg" alt="Mixup Peak s North Face"></a><br>
                    <span class="caption">Mixup Peak's North Face</span>
                </div>
            </td>
            <td>
                <div class="image">
                    <a href="http://www.summitpost.org/cascade-valley-looking-west/860736"><img width="200" height="150" data-src="http://www.summitpost.org/images/medium/860736.jpg" src="http://www.summitpost.org/images/small/860736.jpg" alt="Cascade Valley looking West"></a><br>
                    <span class="caption">Cascade Valley looking West</span>
                </div>
            </td>
        </tr>
    </tbody>
</table>
                
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text

</body>
</html>

Back on-topic… let us know if these image behave as you intend. You can use {border-spacing} to change the separation of the table-cells, if you wish.

1 Like

Withdrawn by author? I didn’t do anything to the post after submitting it.

Regarding the choice between tables and CSS tables, semantically tables are proper because it’s tabular data. The site I’m designing this for uses the table element which I know is not as flexible as div’s.

As for your third post, I am really impressed! :smile: You made my night, I’ve looked through all sorts of responsive table designs but could not get it to act like this. It works almost perfectly, the final bit is now that the caption area does not fill the space of the container because of the other images as seen here.

I posted a quick reply then realized that I had misread your post so I deleted my goofy reply.

table-layout:fixed should equalize the size of the images. It seems to be missing from your screen shot.

The caption box at the bottom cannot fill the height of the table-cell completely when the text is shorter than its peers. That is why I suggested deleting div.image and selectively moving those styles that are needed to the “td”. It should look just as good.

I changed the div.image object to the td object and still ran into the same problem (but at least it worked just like the image div). The problem is that I use a gradient color for my caption span which makes it look better. You said that the caption cannot fill the height of the box, right? So then would it be possible to have the image boxes not all have the same height? As in if one image box has more text than the other one (makes the box have more height) but still have the same image sizes as the other ones.

Hi,

You would need to separate the captions into their own row unfortunately.

e.g. Like this:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Untitled Document</title>
<style>
html {box-sizing: border-box;}
*, *:before, *:after {
	box-sizing: inherit;
}
body {font-family:Verdana, Arial, Helvetica, sans-serif;}
.gallery {
	width:80%;
	table-layout:fixed;
	display:table;
	text-align:center;
	margin:auto;
	border-spacing: 10px 0;
}
.tr {display:table-row;}
.gallery a, .base p {
	display:table-cell;
	margin:0;
	vertical-align:top;
}
.gallery a {
	padding:10px 5px 0;
	text-align:center;
	background:#444;
	border-radius:5px 5px 0 0;
	color:#fff;
}
.base p {
	vertical-align:bottom;
	background: linear-gradient(to bottom, #404040 0%, #353535 100%) repeat scroll 0 0 #393939;
	border-bottom: 1px solid #111111;
	border-radius: 0 0 5px 5px;
	border-top: 1px solid #494949;
	box-shadow: 2px -1px 21px -3px #000000;
	padding:10px 5px;
	position: relative;
	font-size: 12px;
	color:#fff;
}
.gallery img {
	width:100%;
	height:auto;
	border: 1px solid #222222;
	border-radius: 3px;
	box-shadow: 0 0 3px 2px #222222;
}
</style>
</head>

<body>
<div class="gallery">
		<div class="tr">
		<a href="http://www.summitpost.org/sharkfin-tower-from-boston-basin/860738"><img width="200" height="150" data-src="http://www.summitpost.org/images/medium/860738.jpg" src="http://www.summitpost.org/images/small/860738.jpg" alt="Sharkfin Tower from Boston Basin"></a> 
		<a href="http://www.summitpost.org/mixup-peak-s-north-face/860741"><img width="200" height="150" data-src="http://www.summitpost.org/images/medium/860741.jpg" src="http://www.summitpost.org/images/small/860741.jpg" alt="Mixup Peak s North Face"></a>
		<a href="http://www.summitpost.org/cascade-valley-looking-west/860736"><span><img width="200" height="150" data-src="http://www.summitpost.org/images/medium/860736.jpg" src="http://www.summitpost.org/images/small/860736.jpg" alt="Cascade Valley looking West"></span></a>
		</div>
		<div class="base tr">
				<p>Sharkfin Tower</p>
				<p>Mixup Peak's North Face</p>
				<p>Cascade Valley looking West</p>
		</div>
</div>
</body>
</html>

You can do it without separating the captions by using nested 100% height table elements but chrome is buggy with this and is not really viable.

The other option for modern browsers would be flexbox but is only supported in latest browsers and would be hard to supply fallbacks.

@PaulOB I appreciate the interesting method you came up with. Unfortunately the people I’m making this for are not coders, so they would not know how to place those div tags in a line like that. The CSS syntax is whatever I want it to be, the HTML is mostly what it will stay at but I could convince the site owner to add/remove any if it helps the situation.

I’m willing to go the flexbox route, while I generally try to support older browsers this is one of those issues that I prefer using good syntax (it only affects styling on older browsers). So how should I go about the flexbox method? I attempted it before making my last post but probably didn’t do something right.

Thank you all for your support, it goes very much appreciated. I’m pleased to announce that I got it working perfectly as seen here: http://www.joshlewis.name/whitehorse-in-a-day
It works in FireFox, Chrome, and IE 11. Now my template is completely responsive as well as the content which is something I’ve been focusing heavily on lately. I suppose I could do some more work with collapsing techniques.

Glad you got it fixed and are happy with it:)

Sorry if I lead you down the wrong path but I misunderstood the question a little as what you have is quite easy to achieve but I was assuming that you wanted all boxes on the line to remain equal height which my code would have achieved.

At the moment you have irregular height boxes as shown by the screenshot below.

I assumed you wanted those all to remain equal so glad you solved the problem regardless.:slight_smile:

I know that what it is right now is not perfect, but at least it’s responsive and looks good on big screens and decent for small screens instead of being bad on small screens. It would have been nice to have them equal height, but it’s way more important to maintain a simple HTML structure. I don’t have access to the backend of the site so any HTML changes would take convincing. For some crazy reason before I started this thread when I didn’t add a width 100% to tables the tables themselves did not shrink down. Perhaps changing from max-width 100% to width 100% helped?

Now I’m taking on a much harder issue which is getting videos from youtube to be responsive (iframe). I’ve seen the method for a fixed aspect ratio inside of a container, but outside of that there doesn’t seem to be good options. Lucky for me I don’t put in videos very often.

There is an easy trick using percentage padding-top to preserve the aspect ratio of the video. You just work out what the aspect ratio is (usually :16:9) which equates 56.25% (9/16). You then use 56.25% as padding-top (or bottom) on a container.

Set position:relative on that container then absolutely place the iframe to top:0 and left:0; and give the iframe a width and height of 100%. That will create a responsive video based on the width of the element in a 16:9 aspect ratio.

More info here.

Thanks for the well written response. I suppose I could create a class for 4:3 videos and the other for 16:9 ones. Glad to see the conversion is simple. Will have to see how tricky styling the video container will be. I prefer to use as few of div’s as possible. :wink: