Tag Archives: css

Nicely format tables without using table-layout:fixed

I have recently helped to develop Signup Zone, a very handy app where people can easily create their own signup sheets and rosters. People have started using it for interesting purposes, including registering to help injured wildlife! And this has led to people entering in unexpected data, such as very long email addresses; and creating sheets with a lot of columns.

At its heart, the signup sheet is simply an HTML table such as this:

Date Name Contact email address
10/11/2014 Racing Tadpole racingtadpole@example.com

This table has the code:

<table>
    <thead>
        <tr>
            <th scope="col">Date</th>
            <th scope="col">Name</th>
            <th scope="col">Contact email address</th>
        </tr>
    <tbody>
        <tr>
            <td>10/11/2014</th>
            <td>Racing Tadpole</th>
            <td>racingtadpole@example.com</th>
        </tr>
    </tbody>
</table>

Since I don’t know in advance how to size the different columns, I actually really like the browser’s built-in ability to choose its own column widths.

However, the browser will not let any content spill outside a cell, and it only breaks words at white space. So if one user enters a long email address (or URL) into a cell, that column becomes very wide and the table either spills outside the page margins or looks unsightly – or both, like this:

Date Name Email
10/11/2014 Racing Tadpole racingtadpole@example.com
11/12/2014 Another Tadpole anotherracingtadpole@quitelong.verylong.superlong.megalong.example.com

Here are two solutions:

  • Use the new css command hyphens: auto. It won’t work in Opera, Chrome (!) or older browsers (eg. IE 9), and it can hyphenate too many words, but it looks ok, eg:
    Date Name Email
    10/11/2014 Racing Tadpole racingtadpole@example.com
    11/12/2014 Another Tadpole anotherracingtadpole@quitelong.verylong.superlong.megalong.example.com
  • Run some javascript to insert a “zero-width space” or an invisible soft hyphen in places where the offending text can break, eg. at the . or @ symbols. This gives you control over where the words break, eg:
    Date Name Email
    10/11/2014 Racing Tadpole racingtadpole@​example​.com
    11/12/2014 Another Tadpole anotherracingtadpole@​quitelong​.verylong​.superlong​.megalong​.example​.com

    However, if someone copies the email address it will also copy the invisible characters, which could cause trouble.

Here’s some javascript code to implement the second solution in Meteor:

<template name="example">
    ...
    <td>{{{email}}}</td>
    ...
</template>
function htmlEscape(str) {
    return String(str).replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
}

function myMarkup(str) {
    return String(str).replace(/@/g, '&#8203;@')
            .replace(/\./g, '&#8203;.')
            .replace(/\//g, '&#8203;/');
}

Template.example.email = function(){
    // suppose s is the string we want to show
    return myMarkup(htmlEscape(s));
}

The htmlEscape function is inspired by this Stack Overflow post. An alternative is to use Spacebars.SafeString.

Hope that’s helpful!

  

Alignment problem with jquerymobile and bold text – only on PC with Chrome

The following html and css works fine on most browsers, but try it on Chrome on a PC:

<!DOCTYPE  HTML>
<html>
<head>
	<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
	<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
	<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
</head>

<body>
	<style type="text/css">
		.detail { display: block; }
		.detail .fieldname { font-weight: bold; float: left; }
	</style>
	<div class='detail'>
		<div class='fieldname'>Name:</div><div>Mr Smith</div>
		<div class='fieldname'>Phone:</div><div>xxxx-xxxx</div>
	</div>
</body>
</html>

There is an alignment problem on Chrome on a PC.  Not on Chrome on a Mac, and not on IE on a PC – just Chrome on a PC.  You’ll see the word Phone starts under Mr Smith, instead of under Name.  (I am using the latest version of Chrome as I write this, 23.0.1271.64 m.)

This seems to be a strange interplay between the the bold text and jquery mobile. If you switch off either of these things, it works fine.

In fact there is a simple work-around: change font-weight: bold to font-weight: 600.  It won’t be quite as bold (which is weight 700), but hopefully it will be close enough.

All very mysterious!

  

My first HTML5 page

My plan is to put together a page that looks a little like the iPhone home screen, with a grid/table/gallery of icons and icon names. This is the first time I’ve written anything in HTML since the ’90s, so this may not be of interest to anyone but me.

  • This post nicely explains three different ways to do it, although it is a few years old and I suspect that now with HTML5 only the “div” approach is recommended.
  • This O’Reilly online book, “Building iPhone Apps with HTML, CSS, and JavaScript”, is a great starting point for how to make it look good.
  • This css-tricks post explains how to make an iPhone “springboard” webpage nicely.
  • This css-tricks post explains how to set gradients for the background instead of using an image, which could take longer to load.
  • I have also found some helpful code in Pro jQuery Mobile, a book by Brad Broulik, using class=”ui-grid-a” and “ui-block-a”. I thought this requires you to keep track of which column you’re up to (so the first column is ui-block-a, the second ui-block-b, etc), but in fact you can just always use the last column’s block (e.g. for a 4-column grid, use ui-block-d).  However, you must decide beforehand how many columns to use. I’d prefer not to have to do this: if the user is on a phone, 3 columns may be all that can fit, but on a desktop, you may want 8 columns.

Here is what I have come up with – it’s actually quite straightforward (once you know how).  This nicely has two columns when viewed on my phone, and more columns on my desktop.  The magic is css’s “float:left” command. In the html file:

<div class="gallery">
  <a href="#">
    <div class="icon">
      <img height=72 width=72 src="images/icon.png">
      <div class="caption" style="width:108px">My icon</div>
    </div>
  </a>
<!--more icons here -->
<p>  <!--finish with a p so the next thing is shown below - see the css -->
</div>

And in the css file:

.icon  {
  text-align: center;
  float: left;
  margin: 10px 10px;
}

.caption {
  vertical-align: top;
}

.gallery p {
  clear: both;
}

.gallery a, .gallery a:link, .gallery a:visited, .gallery a:hover, 
            .gallery a:active {
  text-decoration: none;
  font-style: normal;
  font-weight: normal; 
  text-shadow: none;
  color: black;
}

I had some trouble working out how to reset the “floating” behaviour once the grid (gallery) of icons is finished.  The css command “.gallery:after” should have done the trick, but doesn’t seem to work as expected.  So instead I came up with making <p> clear the behaviour through the css.  It means that you have to put a <p> at the end of the gallery though.

A caveat – I have only tested this on Safari and Chrome so far.

As an aside, I found it hard to include code snippets here – WordPress interpreted the html code even though it was between pre markers… I solved this by typing <pre>x</pre> using the HTML display, then typing the code itself into the visual display to replace the “x”.

Thoughts?