Layout like this with div's?

Can this be done with div’s instead of tables?

<table style=“width:100%;table-layout:fixed”>
<tr>
<td style=“text-align:right”>some text here</td>
<td style=“width:200px”><img src=“/image-path.png” /></td>
<td style=“text-align:left”>some other text here</td>
</tr>
</table>

The design expands to fill the entire width of the browser window and the middle cell is centered.

You can use divs that behave similarly to a row of table-cells.
Here are 3 different ways of addressing them:

Class Everything


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!--



-->
<head>
    <title>class everything</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <style type="text/css">

.table {
    display:table;
    width:100%;
}
.table div {
    display:table-cell;
    vertical-align:top;
    background-color:#ddd;    /* test purposes */
    border:1px solid #f00;    /* test purposes */
}
.table .cell1 {
    text-align:right;
    width:49%;
}
.table .cell2 {
    text-align:center;
}
.table .cell3 {
    text-align:left;
    width:49%;
}
img {
    display:block;
    width:200px;
    height:200px;
}
    </style>
</head>
<body>

<div class="table">
    <div class="cell1"></div>
    <div class="cell2"><img src="image.png" alt="not found"></div>
    <div class="cell3"></div>
</div>

</body>
</html>

Adjacent Sibling Selector


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!--



-->
<head>
    <title>Adjacent Sibling Selector</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <style type="text/css">

.table {
    display:table;
    width:100%;
}
.table div {                  /* all cells */
    display:table-cell;
    vertical-align:top;
    text-align:right;
    width:49%;
    background-color:#ddd;    /* test purposes */
    border:1px solid #f00;    /* test purposes */
}
.table div + div {            /* cells 2 and 3 */
    text-align:center;
    width:auto;
}
.table div + div + div {      /* cell 3 only */
    text-align:left;
    width:49%;
}
img {
    display:block;
    width:200px;
    height:200px;
}
    </style>
</head>
<body>

<div class="table">
    <div></div>
    <div><img src="image.png" alt="not found"></div>
    <div></div>
</div>

</body>
</html>

nth-child pseudoclass


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!--



-->
<head>
    <title>nth-child pseudoclass</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <style type="text/css">

.table {
    display:table;
    width:100%;
}
.table div {                  /* all cells */
    display:table-cell;
    vertical-align:top;
}
.table div:nth-child(1) {
    background-color:#fcc;    /* test purposes */
    text-align:right;
    width:49%;
}
.table div:nth-child(2) {
    background-color:#ccc;    /* test purposes */
    text-align:center;
    width:auto;
}
.table div:nth-child(3) {
    background-color:#ccf;    /* test purposes */
    text-align:left;
    width:49%;
}
img {
    display:block;
    width:200px;
    height:200px;
}
    </style>
</head>
<body>

<div class="table">
    <div></div>
    <div><img src="image.png" alt="not found"></div>
    <div></div>
</div>

</body>
</html>

Nice work, Ron. This was my attempt, FWIW:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
	
<style media="all">
.container {display: table; width: 100%;}
.container div {display: table-cell; width: 50%; vertical-align: top;}
.first {text-align: right;}
.container div.mid {width: 200px;}
</style>
	
</head>

<body>

<div class="container">
	<div class="first">some text here</div>
	<div class="mid"><img src="/image-path.png" width="200"></div>
	<div>some other text here</div>
</div>
</div>

</body>
</html>

A problem is that the total percent width of the cells in the row cannot exceed 100%. It is perfectly fair if two of them total 98% and the other, which has no width declared, actually occupies most of the width because its contents push it wide, but the total percentages declared cannot exceed 100%.

Yeah, I don’t really understand table widths, but I find that, as long as the width set is more than I want, the table adjusts itself. Without some kind of weird width setting like that, I don’t get the result I want.

Sometimes, tables are like playing with springs. Definitely different than fixed width devices.

I spoke a tad too soon about your example, too. The width of that center div is given in pixels, which do not count toward the total percentage. Effectively, even though it says 200px, it is seen as 0%. In other words, your example will work.

Apply an outline to the cell divs and see how they are rendered. You’ll notice that the div.mid is practically absent. Then tinker with the width value of div.mid (including disabling it) and watch the behavior. It gets funky. Really interesting stuff. Be sure to give the image display:block, though, or the missing image will never fill the div.

Yep, I’ll play with it a bit.

The width="200" seemed to fix the issue of the image not appearing for me.

Are you using an detectable image on your computer? In my case, it’s missing, so {display:block} is required. Maybe that’s just Firefox.

Ah, right. Yes, I’m using Chrome.

Thanks Ron and Ralph. Which of those layouts is generally preferred? Which has the best browser support?

“Class Everything” and “Adjacent Sibling Selector” have the broadest range of browser support. If you unfamiliar with the adjacent sib selector, then go with classes.

If you are applying widths to cells then you should probably use the table-layout:fixed algorithm which will make Ralph’s example work in all browsers.


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
.container {
	display: table;
	width: 100%;
[B]	table-layout:fixed;[/B]
}
.container div {
	display: table-cell;
	width: 50%;
	vertical-align: top;
}
.first { text-align: right; }
.container div.mid { width: 200px; }
</style>
</head>

<body>
<div class="container">
		<div class="first">some text here</div>
		<div class="mid"><img src="/image-path.png" width="200"></div>
		<div>some other text here</div>
</div>
</div>
</body>
</html>

Or alternatively just remove the 50% width and then the browser will most likely choose the fixed algorithm anyway because of the single 200px width.

The table width and height algorithms are complicated and the browsers will try and re-distribute the widths where they are over constrained. Indeed this behaviour of over-constraining or setting small widths can be useful for effects such as images and captions where you want text to wrap within the confines of an images width (which is accomplished by setting the cell width to 1px). A similar effect can be seen in the [URL=“http://www.pmob.co.uk/temp/sticky-footer-auto-height.htm”]table sticky footer where the cell height is set to 1px but will expand with content and not overflow or increase the table height.

The behaviour of tables to redistribute widths is what gave rise to the dreaded and ubiquitous spacer gif which was like scaffold to hold cells open to the correct width.

Are there any browsers out there these days that don’t work so well with either “Class Everything” or Ralph’s example? I’m still a little hesitant to switch from tables to div’s because of the older browsers.

Is Class Everything preferable to Ralph’s suggestion?

The display table properties work well in all browsers from ie8 upwards. You only need to class elements when needed but reliance on structure to style a page can be awkward if you later insert or change elements so rules such as #elem + #elem need to be considered carefully as they rely on the structure not changing whereas a class will work on whatever element it is applied to.

However the bigger question is what are you actually trying to code?

Why are you mimicking table structures? Unless its a specific equal column (equal spread) effect then there may be other methods such as floating. It’s ok to use display:table for the awkward elements that need specific table behaviour but generally you don’t build the whole site like that.

Virtually no one uses tables for layout these days so if you are still very old school you will need to brush up on more modern techniques although they may not seem as easy at first as the behaviour and approach is different.

It may help if we saw or you could describe what you were aiming for? :wink:

I’m trying to put an image in the center of the screen with some text right-aligned against the image on the left side, and some other text left-aligned against the image on the right side. Should I use one of these techniques or would a different one be better? I’m going for maximum browser compatibility.

“Class Everything” was a poor choice of words. “Class As Needed” would have been more appropriate. My bad.

Everybody designs for “maximum browser compatibility” within the range of browsers they expect their target audience to be using.
Which browsers will your targeted users be using? Backwards compatibility has a price, either in extra code or code compromises required to achieve that compatibility, or by staying with old coding techniques like table framed pages. IE8 forward is generally considered to be an economically efficient range of browsers to design for. In which case, the css table properties are fine. As far as I know, either my poorly named “class everything” or Paul’s example are equally compatible from IE8+. If you wish IE7 or earlier compatibility, then other techniques will have to be considered.

If its just a one off effect rather than a layout structure then you could do something simpler like this:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
p { margin:0 }
.col1, .col3 {
	width:50%;
	float:left;
	text-align:right;
	margin:0 -101px 0 0;
}
.col3 {
	float:right;
	text-align:left;
	margin:0 0 0 -101px;
}
.col1 p { margin-right:101px }
.col3 p { margin-left:101px }
.image img {
	display:block;
	background:red
}
p.image {
	overflow:hidden;
	zoom:1.0
}
</style>
</head>

<body>
<div class="col1"><p>This is the right aligned text</p></div>
<div class="col3"><p>This is the left aligned text</p></div>
<p class="image"><img src="" width="200" height="200" ></p>
</body>
</html>


As usual with CSS there are many ways of doing the same thing but usually only one is appropriate for the task in hand and it all depends on context and on what happens next. That’s why we usually never give a straight answer because it depends on what you are doing next :slight_smile:

Off Topic:

Thanks very much for the w3 link. Spent last night playing “what if” and I think the :fixed algorithm is starting to sink in. It’s very efficient! Your example based on Ralph’s code provided a great foundation for comparisons that make good memory aids. --Cheers

Thanks everyone for your help with this.