Using tables for layout with PHP

As Paul said, that’s NOT when to use a table – with ONE exception; if you want the inputs to be dynamic width next to their labels. (and even then a SPAN around the input can often handle that).

Yes - I agree - better to use CSS.

I am also designing the actual basket. I suppose you would say avoid tables again? I have started building the basket as so:

<body>
<table><tr><td width="15%" height="25">
<font face="verdana" size="1" color="black">
<?php echo $row["productid"]; ?>
Product code:<?php echo $row["productid"]; ?>
</font>
</td>
<td width="55%" height="25">
<font face="verdana" size="1" color="black">
<?php echo $row["name"]; ?>
</font>
</td>
<td width="20%" height="25">
<font face="verdana" size="1" color="black">
$<?php echo number_format($row["price"], 2, ".", ","); ?>
</font>
</td>
<td width="10%" height="25">
<font face="verdana" size="1" color="black">
<a href="cart.php?action=remove_item&productid=<?php echo $row["productid"]; ?>">Remove</a>
</font>
</td>
</tr></table>

Would you use CSS again?

Matt.

No, a basket typically IS tabular data - you have the following columns: description, count, cost per unit, total cost for the row, and shipping… with multiple rows identically formatted. That’s what tables are for.

The problem I see with that code you just posted is all the stuff in the HTML that has been unnecessary since 1998 and has no business on a website after 2003. SPECIFICALLY width, height, font, face, size, color… That’s all HTML 3.2, and if you are still using them via a transitional doctype you are “in transition” from 1997 to 1998; Just a wee bit behind the curve.

I also wouldn’t be opening and closing PHP like a madman on that either… Use echo, it’s better. (I’m also making a wild guess as to your looping structure since you have none!)


<?php
echo '
<table class="basket">
	<thead>
		<tr>
			<th class="id">Product Code</th>
			<th class="description">Description</th>
			<th class="price">Price</th>
			<th class="controls">Options</th>
		</tr>
	</thead><tbody>';
	
foreach ($resultList as $row) {
	echo '
		<tr>
			<td class="id">',$row['productid'],'</td>
			<td class="description">',$row['name'],'</td>
			<td class="price">',number_format($row['price'],2,'.',','),'</td>
			<td class="controls">
				<a href="cart.php?action=remove_item&productid=',$row['productid'],'">Remove</a>
			</td>
		</tr>';
}

echo '
	</tbody>
</table>';
?>

EVERYTHING ELSE you are doing there has NO business in the PHP or HTML – that’s CSS’ job! As you can see, the above code is a good deal simpler… and all those classes could be axed if all the browsers supported nth-child or colgroups the same way; but don’t hold your breath on that.

Oh, and your totals should probably go in a TFOOT tag… (which goes before TBODY) thought that’s unreliable cross-browser, so most people just make a classed TR inside TBODY for that.

You can answer that question for yourself, by asking whether or not this is tabular data—that is, information that needs to be organized in rows and columns. Looks like that’s not the case here, so avoid the table.

You are also using some very outdated code there, with the font tags. Take all of that out and use CSS to target the text instead.

deathshadow60 suggests this is a job for tables. But you suggest I use a similar form to that of the Customer Details (as suggested a couple of posts before this one), right?

Also further back in this post, it was suggested the best way for design-layout (neat borders with rounded edge etc.) I use something like that explained at CSS Rounded Corners + Liquid + Images. For the look/design of the basket should I use the same technique suggested by Paul O’B? Or is this typically different for baskets?

Matt.

I would NEVER use a technique like the one you just linked to – it’s not only outdated methodology, it relies on a whole slew of separate images to do the job of a single file.

It’s why I came up with this technique in the first place:
Eight Corners Under One Roof
(which admittedly is just three sliding doors in a row)

The difference in server load for multiple files and handshakes, and the speed increase from less file requests client side more than make up for any increase in image size (within reason).

Though now that IE9 is starting to show signs of life, I would probably take a good hard look at CSS3’s border-radius to simplify it further. IE8- users will get square corners, OH WELL.

I got confused when I looked at your example.

It says you use just 1 image for the background. But your link (http://www.cutcodedown.com/tutorials/eightCorners/images/eightCorners.png) shows 2 images (1st one is a thin line with rounded corners and 2nd is next to it with straight edges. The CSS refers to 1 image “images/eightCorners.png”.

So I am confused about how many images and how they work together. When it says “Making a Dynamic Border Using Only One Image” I expected it to be one massive image, which is the size needed for the web site. Do the thin images you show need to be resized for each job or is there a way that one size fits all?

Matt.

That is only one image file – as your copying of the link illustrates – it may “contain” two sections – corners/top/bottom on the left, repeat-y for the content area on the right, but that’s still only one image FILE.

The part on the left is a sliding doors effect for the top and bottom, the part on the right is repeat-y for the sides, also done as a sliding doors.

That’s why I made the blown-up and greatly reduced width version to show the parts:

Though I think the gradient shows it better:

In any case, it’s still only one file where the one you linked to uses nine.

Though yes, the image has to be customized for each appearance, but the net result is dynamic width up to half the width of the image file (sliding doors), and infinite dynamic height (since the right half is a repeat-y tile)

So does the “-1270px” make it so it only uses 1 of the 2 images? You hide/don’t use one when using the other? (You either use the left or right image). So you only load 1 image to the computer but use it as two images - effectively you could have 2 images but you suggest using just the 1.

Is this correct?

Matt.

Correct. Basically you slide the one image around as a background to show just the part you need where you need it. Overlapping elements (like the nested div) can erase the parts that interfere with your desired appearance too. That’s how “sliding doors” works – one image over the other – as they spread apart more of the “center” is revealed.

Except that if you count it out – left border repeat-y, right border repeat-y, the four corners, and then the top repeat-x and the bottom repeat-x – Most older code that tries to do this with tables and even many sliding doors approaches would need NINE images, maybe ten if you count the content background if doing anything fancy there!

I’m talking nine to ten separate files vs. just the one. Since a handshake for a file can take anywhere from 200ms to 1 full second, reducing the number of files on a site is ALWAYS a good thing.

See why I laugh at the people who load 14 separate stylesheets to “all”, 10 to twenty separate javascripts, and a few hundred separate images. Enjoy the minute long pageload the first time someone visits even on broadband. :smiley:

If preventing that from being an issue means using half a k of sandbag divs and creating one massively wide image – so be it. Generally if you figure in packet rounding up (all files have their size of download rounded up to the nearest TCP packet size), requests on the server side, separate palettes for each image (if optimizing to 8 bit or lesspalette – which is ALWAYS a good idea) the single image file often consumes less bandwidth even if the file is bigger, and most often it’s actually smaller!

It’s why I make the width in the horizontal like that. PNG in a program with a good compressor (basically anything other than photoshop) is BRUTALLY efficient at compressing long horizontal runs of the same or very close colors.

Of course SOME DAY we’ll be able to use CSS3’s “border-image” property, and do away with all those extra DIV and most of that pesky extra CSS too… We’re just still a ways off from that though as the browser makers are still arguing over how it should even work.

To be fair I linked to that old article of mine to explain the process but I linked to your example three times as the example to follow.

My old article does use too many images I agree (but only 6 and not the nine you mentioned) and mainly for the reason that it wasn’t a uniform design as the shadows were different at the bottom and sides as they were at the top so although it could be reduced to a single sprite it wouldn’t be so easy to manage and indeed at the time was less images than most other examples were using.

Of course my example works in IE6 unlike yours where the corners are misplaced by 1px at odd sizes due to the absolute positioning method you are using. It’s fine for fixed width layouts of even pixels but looks ugly in fluid layouts where the corners jog in an out at every odd pixel.

For IE8 and under support I would likely use a two sprite method that allows for fully fluid height and width with transparent corners and no constraints unlike yours. However, as time goes by it is now worth considering giving the older browsers square corners and just using border-radius for the newer browsers and save all the extra code and heartache.

That doesn’t mean I am running your example down as I think its a good method and I wouldn’t have linked to it three times in answer to the original question but fairs fair.

deathshadow60,

You said that a basket would be best done with a table. But how do I use backgrounds with tables?

You might be interested to know I have just found a technique like yours done at: hmv.com: Music CDs, DVDs, Games & More

The image they use is a long horizontal one can be viewed at:
http://www3.hmv.co.uk/hmv/graphics/uk/components/genre_pane/h1_bg.png

Again, with the HMV web site I cannot see how to create a table and have a background appear within/around it. Surely if I design a table with cells then the background would only appear in one cell?

Matt.

Hi,

Responding to post 75 Paul O’B suggested using

.smallmenu {
margin:0;
padding:0;
list-style:none;
float:right;
}
.smallmenu li {
float:left;
color:#ccc;
}
.smallmenu li a {
color:#f00;
text-decoration:none;
padding:0 5px;
font-size:85%;
}

I have had to add this within a column like this:

.smallmenucolumn {
float: right;
width:800px;
}

The only way I can get another column to appear below this column is to set the width of the one above to 800px. So the next one (below) fits below it.

.cart {
margin:0;
padding:0;
list-style:none;
width:300px;
float:right;
font-size:85%;
text-align:right;
}

If I set the first column to 600px then the second column appears before the first one! It seems to me I am ‘asking for problems in the future’ by setting the column width of the first column wider than required. Am I doing this positioning technique correct or is there a better way?

Matt.

If you want an element to start under a float then you need to clear the float.

If you want to clear right floated elements then use:


[B].cart{clear:right;}[/B]

If you want to clear left floats use clear:left and if you want to clear all floats then use clear:both.

I have tried as a test columns called

  • outer
  • column1
  • column2

In the web page I use tags in this order

<div id=“outer”>
<div id=“column1”>
</div>
<div id=“column2”>
</div>
</div>

For some reason there is a thin line at the top of the page (dark colour).

If I remove <div id=“outer”>

it goes away.

Any ideas what is wrong?

Matt.

Using my telepathic powers I would guess that #outer contains two floated elements only and that #outer also has a background color or border that is collapsing to zero height because the floats have not been contained.

Try adding overflow:hidden to #outer or some other clearing mechanism if visible overflow is required.

If that’s not the problem then I’ll need either the full html css or a bigger telepathic brain :slight_smile:

Yes!

You were right. Spot on. Cheers,

Matt.

Hi again,

I have a problem with this CSS

.bullet {
list-style:none;
margin:0;
padding:0;
font-family: arial,sans-serif;
font-size: 12px;
}
.bullet li {
padding:0 0 0 12px;/* make space for image*/
margin:0 0 0px;
background:url(…/bullet.gif) no-repeat 0px 7px;/* adjust to suit*/
font-family: arial, sans-serif;
}

Different browser treat this bit differently:

background:url(…/bullet.gif) no-repeat 0px 7px;/* adjust to suit*/

If you change 7 to 3 the amount the bullet moves up is different between Internet Explorer and Safari.

What is happening? I need the bullet in the centre of the line of text as is common with a bullet. May be there is CSS code for ‘add bullet’ rather than using a image for the bullet.

Matt.

What’s your line-height? You aren’t stating one! As such the height of that line could be anything from 110% to 130% by default across browsers, much less that the browsers don’t even round off percentages consistently.

There’s a reason that IF 12px (ick, absurdly/uselessly small) in that font were to be used in my code, I always state the full condensed font property if I change the size:

font:normal 12px/16px arial,helvetica,sans-serif;

So I can know for a fact I get a 16px line-height in ALL browsers… because just saying “font-size:12px” you’ve got no clue what it’s going to use. (since the specification only SUGGESTS a size)

Though if you are trying to center it left, why not “center left” for the positioning instead of “0 7px” or “0 3px”? Then you might not even have to deal with px for the font size if it’s just a bullet and could use the more ‘proper’ %/em.

… but if you just want bullets and not a image, why are you turning them off with list-style?

the center left works well apart from when a bullet is so long is goes onto a second line - in this case the bullet appears between 2 lines (in the middle of the 2 lines). Can I center it in relation to the first line?

Matt.