6
\$\begingroup\$

I read that, in HTML, it is better to display non-tabular data using the <div> tag instead of the <table> tag. I have a website that is displaying a lot of things as tables, because I like the look of it.

Here's what it looks like:

Screenshot

Screenshot of web page

Here are the CSS and HTML for the table:

table{width:100%; border-collapse:collapse; table-layout:auto; vertical-align:top; margin-bottom:15px; border:1px solid #CCCCCC;}
table thead th{color:#FFFFFF; background-color:#666666; border:1px solid #CCCCCC; border-collapse:collapse; text-align:center; table-layout:auto; vertical-align:middle;}
table tbody td{vertical-align:middle; border-collapse:collapse; border-left:1px solid #CCCCCC; border-right:1px solid #CCCCCC;}
table thead th, table tbody td{padding:5px; border-collapse:collapse;}
table tbody tr:nth-child(odd){color:#666666; background-color:#F7F7F7;}
table tbody tr:nth-child(even){color:#666666; background-color:#E8E8E8;}

.table_sign_up{width:600px;}
.table_sign_up th:nth-child(1){width:200px;}
.table_sign_up th:nth-child(2){width:400px;}
.table_sign_up input[type="text"] {width:380px;}

::-webkit-input-placeholder{color: #B0B0B0;}
::-moz-placeholder{color: #B0B0B0;}
:-ms-input-placeholder{color: #B0B0B0;}
:-moz-placeholder{color: #B0B0B0;}
<!-- *************************************************************************** -->
<h1>Your Info</h1>
<!-- *************************************************************************** -->

<p>Volunteers under 14 should be accompanied by an adult.</p>

<table class="table_sign_up">
	<thead>
		<tr>
			<th>Info Needed</th>
			<th>Enter It Here</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				E-Mail Address
			</td>
			<td>
				<input type="text" name="email" value="" required maxlength="254" />
			</td>
		</tr>
		<tr>
			<td>
				First Name
			</td>
			<td>
				<input type="text" name="firstname" value="" required maxlength="100" />
			</td>
		</tr>
		<tr>
			<td>
				Last Name
			</td>
			<td>
				<input type="text" name="lastname" value="" required maxlength="100" />
			</td>
		</tr>
		<tr>
			<td>
				Cell Phone
			</td>
			<td>
				<input type="text" name="phone" value="" required placeholder="111-111-1111" maxlength="30" />
			</td>
		</tr>
		<tr>
			<td>
				Shirt Size
			</td>
			<td>
				<select name="shirt_size" required>
					<option value=""  selected="selected" ></option>
					<option value="Extra Small"  >Extra Small</option>
					<option value="Small"  >Small</option>
					<option value="Medium"  >Medium</option>
					<option value="Large"  >Large</option>
					<option value="Extra Large"  >Extra Large</option>
					<option value="2XL"  >2XL</option>
					<option value="3XL"  >3XL</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>
				How did you hear about this race?
			</td>
			<td>
				<select name="source" required>
					<option value=""  selected="selected" ></option>
					<option value="The race e-mailed me"  >The race e-mailed me</option>
					<option value="My volunteer group told me"  >My volunteer group told me</option>
					<option value="marathonvolunteers.com"  >marathonvolunteers.com</option>
					<option value="craigslist.org"  >craigslist.org</option>
					<option value="idealist.org"  >idealist.org</option>
					<option value="volunteermatch.org"  >volunteermatch.org</option>
					<option value="createthegood.org"  >createthegood.org</option>
					<option value="allforgood.org"  >allforgood.org</option>
					<option value="eventbrite.com"  >eventbrite.com</option>
					<option value="marathonvolunteers.com"  >marathonvolunteers.com</option>
					<option value="Facebook Ad"  >Facebook Ad</option>
					<option value="Race Facebook"  >Race Facebook</option>
					<option value="Marathon Volunteers Facebook"  >Marathon Volunteers Facebook</option>
					<option value="My friend told me"  >My friend told me</option>
					<option value="google.com"  >google.com</option>
					<option value="bing.com"  >bing.com</option>
					<option value="yahoo.com"  >yahoo.com</option>
					<option value="Other"  >Other</option>
				</select>
			</td>
		</tr>
	</tbody>
</table>

I experimented with converting my code from <table> to <div>. It renders exactly the same to the user, but the code is a lot different.

.data-collection {display:table; width:600px; border-collapse:collapse; table-layout:auto; vertical-align:top; margin-bottom:15px; border:1px solid #CCCCCC;}
.data-collection div {display:table-row;}
.data-collection div:nth-child(1) {color:#FFFFFF; background-color:#666666; border:1px solid #CCCCCC; border-collapse:collapse; text-align:center; table-layout:auto; vertical-align:middle; font-weight:bold;}
.data-collection div:nth-child(1) span {vertical-align:middle; border-collapse:collapse; border-left:1px solid #CCCCCC; border-right:1px solid #CCCCCC; padding:5px; border-collapse:collapse;}
.data-collection div:nth-child(2n+2){color:#666666; background-color:#F7F7F7;}
.data-collection div:nth-child(2n+3){color:#666666; background-color:#E8E8E8;}
.data-collection div span {display:table-cell; padding:5px; border-collapse:collapse;}
.data-collection div span:nth-child(1){width:200px;}
.data-collection div span:nth-child(2){width:400px;}
.data-collection input[type="text"] {width:380px;}
.data-collection input[type="password"] {width:380px;}

::-webkit-input-placeholder{color: #B0B0B0;}
::-moz-placeholder{color: #B0B0B0;}
:-ms-input-placeholder{color: #B0B0B0;}
:-moz-placeholder{color: #B0B0B0;}
<!-- *************************************************************************** -->
<h1>Your Info</h1>
<!-- *************************************************************************** -->

<p>Volunteers under 14 should be accompanied by an adult.</p>

<div class="data-collection">
	<div>
		<span>Info Needed</span>
		<span>Enter It Here</span>
	</div>
	<div>
		<span>
			E-Mail Address
		</span>
		<span>
			<input type="text" name="email" value="" required maxlength="254" />
		</span>
	</div>
	<div>
		<span>
			First Name
		</span>
		<span>
			<input type="text" name="firstname" value="" required maxlength="100" />
		</span>
	</div>
	<div>
		<span>
			Last Name
		</span>
		<span>
			<input type="text" name="lastname" value="" required maxlength="100" />
		</span>
	</div>
	<div>
		<span>
			Cell Phone
		</span>
		<span>
			<input type="text" name="phone" value="" required placeholder="111-111-1111" maxlength="30" />
		</span>
	</div>
	<div>
		<span>
			Shirt Size
		</span>
		<span>
			<select name="shirt_size" required>
				<option value=""  selected="selected" ></option>
				<option value="Extra Small"  >Extra Small</option>
				<option value="Small"  >Small</option>
				<option value="Medium"  >Medium</option>
				<option value="Large"  >Large</option>
				<option value="Extra Large"  >Extra Large</option>
				<option value="2XL"  >2XL</option>
				<option value="3XL"  >3XL</option>
			</select>
		</span>
	</div>
	<div>
		<span>
			How did you hear about this race?
		</span>
		<span>
			<select name="source" required>
				<option value=""  selected="selected" ></option>
				<option value="The race e-mailed me"  >The race e-mailed me</option>
				<option value="My volunteer group told me"  >My volunteer group told me</option>
				<option value="marathonvolunteers.com"  >marathonvolunteers.com</option>
				<option value="craigslist.org"  >craigslist.org</option>
				<option value="idealist.org"  >idealist.org</option>
				<option value="volunteermatch.org"  >volunteermatch.org</option>
				<option value="createthegood.org"  >createthegood.org</option>
				<option value="allforgood.org"  >allforgood.org</option>
				<option value="eventbrite.com"  >eventbrite.com</option>
				<option value="marathonvolunteers.com"  >marathonvolunteers.com</option>
				<option value="Facebook Ad"  >Facebook Ad</option>
				<option value="Race Facebook"  >Race Facebook</option>
				<option value="Marathon Volunteers Facebook"  >Marathon Volunteers Facebook</option>
				<option value="My friend told me"  >My friend told me</option>
				<option value="google.com"  >google.com</option>
				<option value="bing.com"  >bing.com</option>
				<option value="yahoo.com"  >yahoo.com</option>
				<option value="Other"  >Other</option>
			</select>
		</span>
	</div>
</div>

Both sets of code feel messy to me. Which approach is better? Is there anything else I could do to make my CSS code more readable?

\$\endgroup\$
  • \$\begingroup\$ I just thought of something too. The same way that we can use CSS display:table, display:table-row, and display:table-cell to make non-table tags act like table tags, I'll bet CSS lets us do the reverse. I'll bet you could use CSS to make table tags act like something that's not a table. Knowing that, there's really no reason not to use table tags when you have data that can be printed in a grid layout. It doesn't handicap a CSS developer re-vamping your website's look via only the CSS file. \$\endgroup\$ – AdmiralAdama Feb 27 '17 at 20:18
5
\$\begingroup\$

Specification

In the HTML specifications you can find the following:

The HTML table model allows authors to arrange data -- text, preformatted text, images, links, forms, form fields, other tables, etc. -- into rows and columns of cells.

From w3.org "11.1 Introduction to tables"

So, technically it's fine to have form elements within a table.

Layout

Your layout definitely looks tabular. As mentioned in the comments, you even have a heading for each columns. So from that point it's fine, too.

Markup

Two things that can be improved in your markup:

Form element

You don't have a <form>-element currently. You can wrap the whole table into a form:

<form>
    <table></table>
</form>

Or you can make use of the HTML5 option, to link elements to a form, even if they aren't children of the form:

<form id="my-form"></form>

<table>
    <tbody><tr><td>
        <input form="my-form">
    </td></tr></tbody>
</table>

See w3.org: 4.10.18.3 Association of controls and forms

Link between label and form-element

Currently there's no connection between your labels and the actual input. Use a <label> element to create a link between those two. The advantage is also, that if somebody clicks the label the input will be focussed:

<td>
    <label for="email">E-Mail Address</label>
</td>
<td>
    <input type="text" id="email" name="email" value="" required maxlength="254">
</td>

Screenreader

Using form elements in a table is fine for screenreader as well. However, you should keep those things in mind:

Forms should be clear and intuitive. They should be organized in a logical manner. Instructions, cues, required form fields, field formatting requirements, etc. should be clearly identified to users. Provide clear instructions about what information is desired. If any form elements are required, be sure to indicate so. Make sure that the order in which form elements are accessed is logical and easy. This can sometimes be problematic if tables are used to control layout of form items.

From webaim.org "Creating Accessible Forms: Ensure Forms are Logical and Easy to Use"

As your form is very simple, this shouldn't be a problem. If your form grows or becomes more complex, e.g you use labels to address multiple inputs, here's a good read, where tables are used for the layout: Advanced Form Labeling: Handling Multiple Labels


To sum it up, you're approach is fine, and it's even better than the other one, where "Info Needed" and "Enter It Here" aren't associated with the columns in any way.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.