Skip to main content

Welcome to Geoff Hayward's Weblog

Commenting on Java, JavaFX, Java EE, Joomla, and IoT.

Tables have a habit of creeping into every other web development project. Finding a way to make them responsive has been a big issue and a hot topic this year. In this article a new way to make tables responsive has been explored and quite possibly a good solution has been found.

Let's Rule Out JavaScript in Making a Table Responsive

Why rule out JavaScript? JavaScript is a great wagon when it comes to progressive enhancements. The problem with JavaScript is it is not always available. If a table has been used in a project there is a good reason behind why it has been used. This is normally because the data is well suited to a table layout - or in other words it is tabular data.

You can choose to try and fix it with JavaScript, however, in this case you have to accept that some visitors will see a broken looking layout. As a Client-side Web Developer you are not doing your job properly if you accept this. Also, when you least expect it, someone will send your client a screen shot, and your client - quite rightly - will demand you fix it.

But First Let's Explore What a Table is

In order to begin to find a candidate solution, we need to understand the problem. We need to start by exploring briefly what the notion of a table is and what a table is used for. The simple answer, of course, is a table is a structure that semantically holds collections of comparable data; and we use tables to present data in such a way that information can be drawn.

This means that for a structure to act as a table it needs to support the concept of columns and of rows. Or otherwise no information can be reliably drawn from the data it holds. A HTML table fits this description perfectly after all it is what it was designed to do - its very name gives that away. The problem is HTML tables do not slim down on small screens. A row remains a row - full stop.

Now we have a good understanding of what the problem is, and while HTML tables fit the description, they do not fit the needs of a responsive layout. This is especially noticeable on mobile phone layouts as I am sure you are aware. This means if we can find an alternative HTML structure that can also fit the description of a table - to semantically holds collections of comparable data and present data in such a way that information can be drawn from it reliably, and fit the needs of a responsive layout then it is definitely worth looking for.

A Responsive Table from a Semantic Combination of HTML Elements

In any document headings (i.e. 'h*' elements) semantically indicate a section of a document. Therefore, an 'h*' element also makes a great contender as a row heading.

<h3>Row 1</h3>

By wrapping each row into an unordered list, we can begin to make a relationship between rows. You may ask what about the table's columns, and the column's headings? Definition lists, if structured well, make this possible - as shown below:

<ul class="responsive-table">
	<li class="first-row">
    	<h3>Row 1</h3>
        <dl>
            <dt>Heading 1</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 2</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 3</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 4</dt>
            <dd>data</dd>
        </dl>
	</li>
	<li>
    	<h3>Row 2</h3>
        <dl>
            <dt>Heading 1</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 2</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 3</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 4</dt>
            <dd>data</dd>
        </dl>
	</li>
	<li>
    	<h3>Row 3</h3>
        <dl>
            <dt>Heading 1</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 2</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 3</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 4</dt>
            <dd>data</dd>
        </dl>
	</li>
</ul>

As you can see, column headings are made constant for each item of each row. This thus creating continuity between each row and therefore, information can reliably be drawn from the data held in the semantic structure - fitting the description of a table. I believe that screen readers would also read this out in a way that makes the table's information attainable.

With a preconception of what a table looks like in a browser you may think that example 1 does not look very table like yet. However, I am sure you will agree information can be drawn from it in the same way that fits the discretion of a table.

At this point you can also see how it can easily take up less width to display - even without any styling.

Let's Style Our Responsive Table to Look Like a Table

Before we move on into the table, we need to fix up the containing unordered list and reset the margin, padding, line height and font-size of the 'ul', 'h*', 'dl', and the 'dd' elements. Once done, we need to make every definition list and h* elements sit next to each other both on the x-axes and on the y-axes. We can do this using the CSS's 'float: left' in combination with percentage widths. You can target each column width with classes if you like, as a proof of concept, I will keep this simple with a 20% width for row headings and 20% width for each column.

The trick to making it look like a normal table on a screen that is large enough to display a normal table is to use the first row's column headings. The conflict is, we do not wish to show any of the other row's headings in this layout. We will do this by making all 'dt' elements invisible except for the first row's 'dt' elements. Finally, the first row of the table needs the 'h*' element's padding at the top to be equivalent line height of the column headings: this gives the correct vertical alignment to the row's heading.

.responsive-table {
	width:100%;
}
.responsive-table ,
.responsive-table h3,
.responsive-table dl,
.responsive-table dd{
	margin:0;
	padding:0;
	font-size: 1em;
	line-height:1em;
}
.responsive-table li{
	list-style:none;
	display:block;
	clear:both;
}
.responsive-table h3,
.responsive-table dl{
	float:left;
	display:inline;
	width:20%;
}
.responsive-table .first-row h3{
	padding-top:1em;
}
.responsive-table dt{
	display:none;
	font-weight:bold;
}
.responsive-table .first-row dt{
	display:inline;
}

You will now see a table that also fits our preconception of what a table should look like in example 2.

Let's Style Our Responsive Table to Fit on Small Screens

For a small screen set the break point of your media query to the place that makes the most sense to the data inside of your table. For this demo I have chosen 600 pixels. For this layout all you need to do is set the 'td' and 'dl' elements to float.

Here is all of the CSS for each layout of the responsive table:

.responsive-table {
	width:100%;
}
.responsive-table ,
.responsive-table h3,
.responsive-table dl,
.responsive-table dd{
	margin:0;
	padding:0;
	font-size: 1em;
	line-height:1em;
}
.responsive-table li{
	list-style:none;
	display:block;
	clear:both;
	padding:5px 0 0; 
}
.responsive-table dt{
	font-weight:bold;
}
@media all and (max-width:600px){
	.responsive-table dt,
	.responsive-table dd{
		float:left;
		display:inline;
		padding-left:10px;
	}
}
@media all and (min-width:600px){
	.responsive-table h3,
	.responsive-table dl{
		float:left;
		display:inline;
		width:20%;
	}
	.responsive-table .first-row h3{
		padding-top:1em;
	}
	.responsive-table dt{
		display:none;
	}
	.responsive-table .first-row dt{
		display:inline;
	}
}

Please see example 3. To get the best idea of how this looks and works, resize IE9 and up or any other browser on a large screen.

A Tip Worth Noting

If you need to give the table heading a background colour, apply the colour to the unordered list and set the list items back to their intended colour.

Conclusion

With an open way of thinking about what a table is and how else we can construct a table with HTML this approach to a responsive table works. The CSS to present it is very light-weight and much more agile than its HTML table counterpart. What do you think?

Acknowledgements

This solution was co-developed by Neal Stammers and myself.



Read

This article is written to impart a short cut in getting to the content of an XML document from within a JavaScript script quickly and consistently across browsers. You will see that by skipping the XML document's DOM all together time and bytes are saved.

There is also a second good to the solution that is conveyed in this article. To the best of my knowledge earlier than ie9 versions of Internet Explore do not treat RSS feeds as XML. This means in an Ajax's XMLHttpRequest object there is no responseXML document to work with and that can be a gotcha. Of course you may be able to change the header for RSS documents server side. However let's assume you cannot get access to do so as this article is about dealing with XML responses generally.

Getting the Text from XML the Normal Way

When the XMLHttpRequest object of an Ajax call returns with a responseXML you have a document. A handsome document full of information but, getting hold of the information is not so easy. There are traversals to make you dizzy, elements to store, and then there are cross browser issues for getting hold of the text nodes themselves.

An XML Traversal Example:

var items = responseXML.getElementsByTagName('item');
var title[3] = items[3].getElementsByTagName("title")[0];
var desc[3] = items[3].getElementsByTagName("description")[0];

And in reality there will be a for-each loop or for loop in there somewhere. There will be variables storing elements – allsorts going on. It may not be the hardest thing to do but the JavaScript file is growing byte by byte and the cross browser issues are afoot.

The XML Text Node Cross Browser Issue

Some browsers get hold of the text node like this:

.textContent
Others browsers get hold of the text node like this:

.text

This means making a function that will return the content whichever way the browser likes to work is a likely root. In other words, more bytes are added to the JavaScript file just to deal with cross browser differences. It is at this point you realise you are not working smart and are going down the wrong root. But, there is the better solution.

Getting the Text from XML the Smart Way

While the DOM is normally a good thing in this case it only serves to get in the way. Introduce regular expressions to the mix and add a little responseText and your smart cake is well on its way to tasty.

You may ask: What about the lack of single line mode in JavaScript's regular expression? And I would say good question. The answer is 'no problem' and it is all thanks to:

[\s\S]

This means from the group, denoted by the square brackets, of white space characters and not white space characters. That's right anything and including new line characters.

The example below uses regular expression to collect all the items from an RSS feed into an array. Then it takes the index for getting a random item. It then templates the item as appropriate and finally appends the templated item into the DOM of the main HTML page.

new Request({
    'url': '/testimonials.rss',
    onSuccess: function(responseText){
        //split items into an array 
        var items = responseText.match(/<item>[\s\S]*?<\/item>/g);
	
        // pick an item at random 
        var rand = Math.floor(Math.random()*items.length);

        // template the data 
        var html = '';
        html += /<div class="feed-description">(.*)<\/div>/.exec(items[rand])[1];
        html += '<p class="title">' + /<title>(.*)<\/title>/.exec(items[rand])[1] + '</p>';
        html += '</div>';

        //then wrap and append it to something 
        var testimonial = new Element('div', {
           'class': 'testimonial'
        }).set('html', html);
        $$('.testimonials')[0].grab(testimonial, 'bottom');
    }
}).send();

You can of course template all the items of the feed or nodes of your document the first few items or whatever you need. Using the same method you can get hold of any part of the item or whatever your XML document is. For example:

html += '<a href="' + /<link>(.*)<\/link>/.exec(items[rand])[1] + '">Read more</a>';

will add a link back to the article source as given in the RSS feed.

Conclusion

As XML is often the transport medium given in response to many Ajax requests, it is important to have a good cross browser solution that doesn't necessarily weight down the scripts size. This method is a way of dealing with what has been returned across all browsers without the need of extra functions that only serve to make your solution work a cross browsers. I am finding this approach works very well and it is worth sharing. What do you think about this approach?



Read

All the versions of Joomla I know have shipped with the GeSHi syntax highlighter. The GeSHi Syntax highlighter comes in the form of a plugin that is by default unpublished. Its power comes from the fact that it does all the syntax highlighting server side. Meaning caching can be taken full advantage of.

The GeSHi - Generic Syntax Highlighter is an award-winning piece of software released under the GNU GPL license and is packaged into a plugin by Joomla ready to be used by any author or publisher who needs to highlight the syntax of their examples.

When I found the Joomla GeSHi plugin, I discovered there was very little documentation on how to use the Joomla plugin. This may have been because it is quite easy to uses once you know how, however, I didn't know how at the time. I had to piece together very small snippets of information until the 'how to' for me came together.

Here is How to Use the Joomla GeSHi Plugin

The first step is to go to Joomla's plugin manager. Search for 'GeSHi' and publish the result. The Joomla GeSHi plugin will then be active ready for the Joomla's advanced event system (sometimes referred to as hooks in other CMS's terminology) to call it during 'onContentPrepare'.

Now when adding content simply use the HTML pre tag with the GeSHi xml:lang attribute. The value of the attribute needs to be the language that is to be syntax highlighted. For example:

<script type="text/javascrpt">
	/* Highlighted JavaScript stuff  */
</script>

will give you a syntax highlighted JavaScript snippet.

TinyMCE Gets in the Way of the Joomla GeSHi Plugin

Be warned TinyMCE is a bit of a pain when it comes to using the GeSHi plugin. The best solution is to just disable TinyMCE. What about the non-technical users? - you may ask. Well you can disable TinyMCE for your account only or the user group of authors who need syntax highlighting - for example you could set up a 'Technical Author' group. Another alternative I have found is to use the JCE editor. When the JCE editor is configured properly, it will play nicely with the GeSHi Joomla plugin.

What Languages Will the Joomla GeSHi Plugin Highlight?

Version 3 of Joomla will get GeSHi to highlight following:

  • CSS
  • Diff (Diff File Format)
  • HTML
  • ini (Configuration files)
  • JavaScript
  • MySQL
  • PHP
  • SQL
  • XML

They are All Triggered Respectively as Follows:

<pre xml:lang="CSS">
<pre xml:lang="Diff">
<pre xml:lang="HTML">
<pre xml:lang="INI">
<pre xml:lang="Javascript">
<pre xml:lang="MySQL">
<pre xml:lang="PHP">
<pre xml:lang="SQL">
<pre xml:lang="XML">

Conclusion

The Joomla GeSHi Plugin is a great tool for authors and publishers were syntax highlighting is in need. The Joomla GeSHi Plugin is not difficult to use as this article tries to show and help with. Out-of-the-box the Joomla GeSHi Plugin has a good selection of languages that technical bloggers and writers are likely to need. If the language you need is not included, please see below for: What if the language I need is not included? Otherwise I hope this article was helpful.

What if the Language I Need is Not Included?

Well you could just add it to the GeSHi folder within the plugin - that is how GeSHi itself works. However, as I am sure you know, this is hacking the Joomla core and is bad and unnecessary. The solution is to copy the Joomla GeSHi plugin folder to your local machine. Then add whichever languages you need that are available from the GeSHi project to the plugin's GeSHi folder. Then repackage it up with an amended install XML file, zip it, and install it back into Joomla. Do not forget to publish your extended version and you're away.

Here is one I prepared earlier that has all the languages GeSHi has available:

Note:

  • For performance reasons I recommend removing the languages you will not be using
  • It comes with no warranty

Tags: GeSHiJoomla

Read

At the time of writing this article I have not seen websites with completely successful attempts at loading icons which appear when html anchor tags are clicked. I therefore decided to find my own solution.

By completely successful I mean the website continues to function as if the icons where not there at all. For example pressing 'Ctrl' and left clicking the link of an anchor tag a new tab should appear within the user's browser. The original tab from which the click was initiated should remain the same.

At no time should the loading icons prevent the default behaviour of the browser. Not when it is a link away from the page either internally or externally relative to the website. The reason being: You do not want to upset search engine spiders, accessibility etc.. Remember we are trying to enhance the website's usability without taking anything away.

The CSS Problem with Anchor Tags Loading Icons

The main problem I had to overcome first was: Browsers, with the exception of Firefox, just do not request images from the server once a page has received an anchor click that goes to a new page. So how do we solve a problem like this? The solution is to already have the requested loading icon image before the anchor tag is clicked.

So now the question becomes: Where to hide the loading icon ready for the click of the anchor tag? I admit I got very inventive whilst experimenting with this problem. However, the solution I found and settled on was simple. That is to simply hide the loading icon on the anchor itself. In other words the icon is always there with a negative 100% on the x-axes. Then all that needs to be done is shift the position of the loading icon image into view once you need it. So now the CSS class called 'loading' is put into the stylesheet ready for action.

.menu a {
    background: url("../images/loading.gif") no-repeat scroll -100% 50% transparent;
}
.menu a.loading {
    background-position: 100% 50%;
}

Solved! Or is it? That at least solves the CSS part of the loading icons on the anchor tag problem.

JavaScript for Anchor Tags Loading Icons

Now all we need to do is to shift the x-axes of the loading icon image by adding the class named 'loading' to the anchor when clicked. This of course, is easier said than done.

Sticking to the discipline that HTML provides structure, CSS provides presentation and JavaScript provides behaviour all the JavaScript in the solution I found loads from a JS file.

The first thing the solution needs to do is to wait for the DOM to be loaded. It then needs to find all the anchor tags that are going to have loading icons. Once it has found the anchor tags, it needs to add a click event. As this is pretty standard functionality given by JavaScript abstraction layers, I made my life easier by using Mootools. However, there is nothing library specific in the solution that I am giving here. Prototype JS, jQuery, etc. will work just fine.

So the click event! This is the tricky part that can stop the user's browser working as it should. When the anchor is clicked, we add the class named 'loading' to the anchor tag. However, the 'Ctrl' click, 'Alt' click and 'shift' click need to not have an effect when the event is fired. So an if not statement needs to wrap around the event to stop the class 'loading' being added.

For example:

if(!event.control && !event.alt && !event.shift){
  node.addClass('loading');
}

That is all there is to it! It was easy once I solved it.



Read

For those of you that do not know the JSON format; JSON stands for JavaScript Object Notation and is a very powerful and fast way of getting and using data. It is fast because the client does not need to parse it unlike XML. At your keyboarding finger tips you have a JavaScript collection ready to roll. But the best part of it is it circumvents the cross domain malarkey. That's right no proxy needed.

So let me give you a demo using a well-known website that lets you feed on their data. Of course this demo is only a demo and I would not use script tags in the body of the document if it was a live website.

<div id="twitter"><!-- a Handle --></div>
 
// This function must be known before the call
function getTweets(data)
{
    var html = '';
    for (var i = 0; i < data.length; i++){
        html += '<p>' + data[i].text + '</p>';
    }
    document.getElementById('twitter').innerHTML = html;
}
 
<script type="text/javascript" src="https://twitter.com/statuses/user_timeline.json?screen_name=YOURUSERNAME&callback=getTweets" ></script>

The example I created about will right out the main text from all of your tweets paragraph by paragraph thus demonstrating the elegance of JSON. Try it yourself but, remember to check the API of the data feed you are getting JSON from to see what tasty nibbles are in store.



Read

Mailing List


Responsive Media

With the ResponsiveMedia plugin for Joomla it is easy to add 3rd party content from YouTube, Vimeo, and Instagram right in to any Joomla! article.

ResponsiveMedia