4
\$\begingroup\$

Prompted by a meta answer, here is an HTML page I'm deliberating over in JSBIN and I would like your review, please.

  1. I am not looking to implement the logic, just please focus on HTML & CSS.

  2. Are tables a good candidate to mark up purchase items? I've seen this implemented as a list in each column, which I thought was worse.

  3. How can I best add markup and style to the final total?

There is a known issue with the CSS border. I'm not asking for you to fix that, but I'm telling you because there is a comment in my code that could possibly make it sound broken. Any other good tips or examples would be great.

td, th { text-align: right; }
tr th:first-child, tr td:first-child { text-align: left; }
tbody tr:last-child td { font-weight: bold;  }
table { border-collapse: collapse; }
tbody tr:last-child { border-top: thick black solid; }
<table>
  <thead>
    <tr>
      <th>Description</th>
      <th>Quantity</th>
      <th>Rate</th>
      <th>Amount</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Moon cakes</td>
      <td>5</td>
      <td>100</td>
      <td>500</td>
    </tr>
    <tr>
      <td>Super biscuits</td>
      <td>1</td>
      <td>500</td>
      <td>500</td>
    </tr>
    <tr>
    <td></td>
	<td>Total value</td>
	<td></td>
	<td>1000</td>
	</tr>
</tbody>
</table>

\$\endgroup\$
  • \$\begingroup\$ @KaiHendry - I think you are really asking for constructive criticism on you layout. If that is correct although I appreciate that your layout is defined by the code I'm not really sure that you should listen to the comments of programmers. You need to seek assistance from people who make things look pretty for a living, maybe the 'User Experience' stack exchange? \$\endgroup\$ – Code Gorilla Oct 7 '15 at 12:04
  • \$\begingroup\$ Do you plan to use any framework or plain css only \$\endgroup\$ – Paritosh Oct 12 '15 at 10:32
5
\$\begingroup\$

Using a table here is the right choice, however I would put the total into a <tfoot> group where you can address its formatting needs specifically. In addition do use colspan="2" to collapse columns in the total, as well.

\$\endgroup\$
  • 1
    \$\begingroup\$ tfoot is a good HTML solution, though I would still use a class attribute for styling \$\endgroup\$ – Toni Leigh Dec 9 '15 at 23:17
3
\$\begingroup\$

Your html table mark-up is exactly right. You may encounter some debate on the use of a table, some people may suggest <ul> <li> is better, but I would consider that subjective. It's an unordered list of items, but it's also tabular data.

Two related ways you could improve the css would be to avoid using html entities in css selector declarations and name-space the the classes themselves.

By doing this you tie the css declarations to the HTML. For example, in your code, the styles defined can only be used if a table is used in the code and they'll apply to all tables in the HTML, regardless of whether you want it to or not.

Together this can result in a situation where styles leak unexpectedly and need to be over-ridden.

May seem like overkill in a trivial example like this but it's a very good thing to get into, particularly as css is complex in both apps and marketing sites / brochure-wear (it's often true that a brochure-wear site is very simple in every way apart from the HTML and CSS).

You can actually set things up in a way that means you can uses the css on anything in a way that doesn't leak.

Here's an example, which actually utilises a naming convention called BEM. You'll probably recognise BEM from some high profile websites like the BBC or Instagram, both of which use a hybrid. Not to mention numerous examples online from advanced front end devs.

.table {}
.table__row {}
.table__cell {}
.table__cell--first {}
.table__row--stand-out { /* styles for total */ }

You'll notice I haven't used last or total for the total row. This is to keep context to a minimum. Now you have a style that can be sensibly and easily re-used.

\$\endgroup\$
  • \$\begingroup\$ Yes, not a fan of having classes everywhere. :) \$\endgroup\$ – Kai Hendry Oct 12 '15 at 9:21
  • \$\begingroup\$ @KaiHendry why not? I've found it to be the best way to mark things up for css because it's clearer, less leaky, easier to re-use on other elements and more maintainable, amongst other things \$\endgroup\$ – Toni Leigh Oct 12 '15 at 11:51
  • \$\begingroup\$ Just seems redundant when I only have one table. \$\endgroup\$ – Kai Hendry Oct 12 '15 at 11:52
  • 1
    \$\begingroup\$ @KaiHendry yes in extremely simple cases it can work well, but I tend to find when things get more complex it becomes tricker, for example, if you have another table you want to style differently, or if you'd like another element structure to look like the table (I've hit these problems time and time again) \$\endgroup\$ – Toni Leigh Oct 12 '15 at 11:55
2
\$\begingroup\$
  • Yes, tables are a good solution for your example. This is the perfect example of tabular data. Something that you could also do in Excel.
  • For the total, use the colspan attribute instead of empty cells. Something like this:

    <td colspan="2">Total value</td><td colspan="2">1000</td>
    
  • Consider using classes rather than pseudo-attributes, especially for the alignments. In your case, it works well enough but it would be very tedious in a more complex table. Even in your case it would improve the readability of your stylesheet. An example:

    td.number {
      text-align: right;
    }
    
    td.test {
      text-align: left;
    }
    
    tr.total td {
      font-weight: bold;
    }
    
    th {
      font-weight: bold;
    }
    
\$\endgroup\$
0
\$\begingroup\$

Thank you all for your input and this is what I decided upon:

table {
  border-collapse: collapse;
  width: 100%;
}
td,
th {
  text-align: right;
  padding: .4em;
}
tr th:first-child,
tr td:first-child {
  text-align: left;
  width: 90%;
  /* Force description column to take more space */
}
tfoot tr td {
  font-weight: bold;
  border-top: 1px black solid;
  border-bottom: 1px black solid;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <meta name=viewport content="width=device-width, initial-scale=1">
</head>

<body>
  <table>
    <thead>
      <tr>
        <th>Description</th>
        <th>Quantity</th>
        <th>Rate</th>
        <th>Amount</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Moon cakes</td>
        <td>5</td>
        <td>100</td>
        <td>500</td>
      </tr>
      <tr>
        <td>Super biscuits</td>
        <td>1</td>
        <td>500</td>
        <td>500</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td colspan="3">Total value</td>
        <td>1000</td>
      </tr>
    </tfoot>
  </table>
</body>

</html>

Things I learnt:

  • border-collapse: collapse; CSS is needed to do full unbroken lines in a table
  • Forcing the width on the first column to make it look more like something you would actually see in a receipt
  • tfoot & colspan for the final total row

Outstanding: Would be nice if table columns could be adjustable natively.

\$\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.