Skip to main content

Welcome to Geoff Hayward's Weblog

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

In this post I describe how the logic needed to add a CSS current marker to a webpage can be achieved very simply with very little logic on the website's server. I look at why a current page marker is important and why we need to use them.

Good User Centered Design

When a website user sees a distinctly marked menu item he/she is instantly orientated to where within the website they are in terms of the website structure. Without a distinct marking a user cannot easily determine where they are within the website. A lack of marking leads to avoidable extra cognitive work on the user's part.

Basic illustration

In providing a good user experience the burden of identifying where a user is, should be the concern of the website itself. Using CSS, the information can be conveyed to a normal sighted user with colour. The colour needs to unambiguously highlight the corresponding menu item related to the page the user is currently on.

It's common practice to achieve this by adding a marker via the use of a CSS class within the mark-up. The CSS class may have a name akin to 'current'. The CSS class is added, often server side, to the menu item during the creation of the menu. For example:

<ul id="nav">
	<li class="current"><a href="home">Home</a></li>
	<li><a href="about">About</a></li>
</ul>

Then using CSS such as the example below, the item will appear highlighted.

.current a
.current a:link
.current a:visited{
	Background-colour: # 

}

Braking the Rules Elegantly

Here is the problem with adding a 'current' class. During the menu creation you have to get the server to repeat the decision: is this the item to add the class to? Ok, not a big problem and if you have already implemented this logic in old projects, it is probably better to leave it in.

However before you implement this logic into your next project, be aware there is a second way. I had this idea recently looking at this problem for myself for the first time. The solution that dawned uses less logic and not one 'if' statement.

I normally would say 'no way' to using a style attribute directly in a webpage's source because it breaks the rule of separation. Sometimes, however, breaking the rules can lead to a very elegant solutions. Elegant in this case because of a large reduction in the logic is removed from the menuing process.

How to Reduce the Logic

First, give a unique name to each page. Then simply use the unique name as a CSS class on every menu item.

<ul id="nav">
	<li class="home-page"><a href="home">Home</a></li>
	<li class="about-page"><a href="about">About</a></li>
</ul>

Second, output the name of the current page, as a CSS class, in the head element of the page's HTML each time the page is dispatched. Here is an example of how this may look using EL in JSP:

<style>
.${page.clsss} a
.${page.clsss} a:link
.${page.clsss} a:visited{
	Background-colour: # 

}
</style>

Then, using the homepage as an example, the output would look like this:

<style>
.home-page a
.home-page a:link
.home-page a:visited{
	Background-colour: # 

}
</style>

The CSS would then highlight the homepage as the current page. As soon as the user moves to another page, the class name within the style tag will change to reflect the name of the next current page.

This also means that the menu can be created and cached once for every time the menu is edited.


Tags: CSSJSP

Read

Before CSS3 came along turning HTML 'A' tags into cool dynamic text buttons was not as simple as it is now. However, I had a solution that worked back then. Now I use this old solution to provide fall-back for the old IE browsers.

The first step in providing fall-back buttons for old IE with CSS2 is to follow an HTML pattern. This pattern puts a HTML 'SPAN' within the HTML 'A' tag. The 'SPAN' then wraps all the dynamic text as shown in the example below:

<a class="button"><span>BUTTON TEXT</span></a>

This HTML pattern means you get two items within the DOM to style. For this solution you need both items. As you will see below the outer item, the HTML 'A' tag, mainly provides a hook for the styling of the left hand side of the button. The inner item, the HTML 'SPAN' tag, mainly provides a hook for the styling of the right hand side of the button. I use the word 'mainly' loosely here because the CSS2 pattern works in accord.

.button,
.button:link,
.button:visited
{
    background: url("button.gif") no-repeat scroll left top transparent;
    padding: 0px 0 0px 28px;
    color:#FFFFFF;
    display:inline-block;
    width:auto;
    height:38px; 
    border:none;
    cursor:pointer;   
    font-size: .9em;
}
.button span,
.button:link span,
.button:visited span
{
    background: url("button.gif") no-repeat scroll right top transparent;
    padding: 0 40px 0 0;
    height: 38px;
    display:inline-block;
    border:none;
    line-height:38px;
    margin-right: -20px;
}
.button:hover,
.button:focus,
.button:active
{
     background-position: left bottom;
}
.button:hover span,
.button:focus span,
.button:active span
{
     background-position: right bottom;
}

You will notice from this CSS example that a background image is being used. Remember, the goal is to get rid of the image text. We get rid of image text because actual text is accessible and image text is not accessible.

This method turned out to be a good way to do buttons a couple of years ago. The background image makes it possible to have round corner and or horizontal gradients and or a graphic next to the dynamic text.

For the background you will need to put the button's normal default state and its hover state onto its own image sprite. I always opt for a silly length so that the dynamic text can also be a dynamic size on the X axis (limited at size silly of course). The sprite needs to be of a height dividable by two.

In your CSS the height and line-height needs to agree with the buttons background height. In the example CSS shown above the button is 40 pixels high. The HTML 'A' tag gets the left padding and the HTML 'SPAN' tag gets the right padding. This then gives you the flexibility to have horizontal centring or an offset to accommodate a graphic.

In the case of round cornered buttons you need a negative right margin on the 'SPAN' tag's CSS.

margin-right: -5px;

That's it. Check out the example CSS2 button.

I am thinking of making a tool soon that will produce the CSS and background image based on a specification given via an HTML form. Please let me know if you are interested in this tool by contacting me.


Read

Do you need to know how to make CSS border gradients? This swift article will show you how to make a pseudo cross browser border gradient. CSS Border gradients are easy to make once you know how, and with the right tool. The border gradients in this article work across browsers without using images to fall back on.

Making the CSS Gradient

Let's start by making the CSS gradient. Surprisingly CSS gradients can be made to work across most of, if not all of, the browser you are normally developing for. The tricky part is each browser has its own implementation. However, there are great tools online to take the labour out of making gradients. So we will make life easier for ourselves and use one.

The CSS gradient tool I've found and like is the colorzilla gradient editor. The makers of the Colorzilla gradient editor tool provided a brilliant browser-based interface that comes with all the instructions you need for making the gradient.

Making the CSS Gradient a Border Gradient

In the solution below is the CSS gradient that was generated by the Colorzilla gradient editor tool. I've put the gradient CSS inside a class that is named 'border-gradient'.

Using this CSS we will make a border or at least a pseudo border (pseudo as in not real as opposed to a CSS pseudo-class). To do this just add padding and make sure the box doesn't collapse. You can stop the box from collapsing by using an in-line block or by floating the box with its overflow property set to hidden.

Then just put a box inside of the box and set the background to a solid colour. The box that is inside the box needs to be displayed as an in-line block. That is it - I said it was easy. Easy with thanks to the hard work that the online gradient editor tools of course, without them it would be tricky.

CSS Border Gradient Demo

See the border gradient example.

CSS Border Gradient Solution

.border-gradient{
	background: #58332b; /* Old browsers */
	/* IE9 SVG, needs conditional override of \'filter\' to \'none\' */
	background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzU4MzMyYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiZWYwZTQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
	background: -moz-linear-gradient(top,  #58332b 0%, #bef0e4 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#58332b), color-stop(100%,#bef0e4)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top,  #58332b 0%,#bef0e4 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top,  #58332b 0%,#bef0e4 100%); /* Opera 11.10+ */
	background: -ms-linear-gradient(top,  #58332b 0%,#bef0e4 100%); /* IE10+ */
	background: linear-gradient(to bottom,  #58332b 0%,#bef0e4 100%); /* W3C */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#58332b\', endColorstr=\'#bef0e4\',GradientType=0 ); /* IE6-8 */
	padding: 3px;
	display: inline;
	float: left;
	overflow: hidden;
}
.border-gradient .border-gradient-content{
	background-color: #FFFFFF;
	display: inline-block;
}

Conclusion

This solution gives the effect of a gradient border. People who view it will perceive a gradient border. Importantly, this solution works across all browsers, I have tested it in IE 7 through to IE 10, Opera, Safari, Firefox, and Chrome.



Read

Internet Explorer, before version nine, did not cope with media queries, however, there is no need to duplicate your CSS stylesheets. If you need a good tip on how best to deal with Internet Explorer when it comes to CSS media queries - in the context of maintenance - then this short article will help.

CSS - the Need for Good Maintenance

Most of us know that if we get the ground work right during the development stage of a project the maintenance will be noticeably easier - not just with CSS. In fact small changes that should take five minutes can take hours on a project that either rushed or skipped the groundwork stage.

The Problem

When the project includes the use of media queries as the mechanism for enabling responsive layouts - it can be tempting to duplicate everything minus the media queries for the older versions of Internet Explorer. That is fine but this approach forks the stylesheets. Once it is time to make changes to the styles, it becomes difficult to guarantee synchronisation across the fork.

The other issue is: you are sending out a duplication set of CSS rules to Internet Explorer. That makes for an extra volume of bandwidth being used that can and should be avoided.

The Solution

First, spilt the CSS styles into two files - this may seem counter intuitive as this does create an extra hit to the server but in the context of maintenance I believe it is worth it. With proper caching, the second hit only happens once.

Once split, name the staylsheets something like: reset-generic-queries.css and large.css. You may see where I am going with this!

In the first stylesheet put your CSS resets, followed by your generic CSS rules such as the projects typography, and then your media query groups.

Finally, without any media queries put your large screen style rules in the stylesheet named 'large'.

You should have two CSS files structured something like this:

/* resets */


/* typography */


/* elements */


/* helpers */


/* small screen */
@media all and (max-width: 480px){

}

/* medium screen */
@media all and (min-width: 480px) and (max-width: 940px) {

}

For the 'reset-generic-queries.css' file; and

/* large screen */

For the 'large.css' file.

Once you have your CSS across two stylesheets, in a similar manner you can establish zero duplication in your styles without difficulty. The magic, now, of zero duplication is in how you link the stylesheets to the main document.

<link media="all" type="text/css" rel="stylesheet" href="reset-generic-queries.css" />
<link media="all and (min-width: 940px)" type="text/css" rel="stylesheet" href=" large.css " />
<!--[if lt IE 9]>
	<link media="all" rel="stylesheet" type="text/css" href=" large.css" />
<![endif]-->

As you can see, the first stylesheet labled 'reset-generic-queries' is linked as normal. The second stylesheet uses an in-line media query so that it is used only by screens large enough, in combination with an 'IF IE' for Internet Explorer support.

Internet Explorer (older IE) will not see the embedded media queries in the first stylesheet but will see your resets CSS rules and your generic CSS rules as they are not wrapped in a query. Internet Explorer will not download the stylesheet linked with an in-line media query but will download the same stylesheet using its own 'IF IE' query - therefore Internet Explorer renders all of the CSS that is meant for a large screen.

All the other browsers (and new IE) will read your resets CSS rules, your generic CSS rules, and the rules most appropriate to the screen size currently displaying your responsive layouts.

Conclusion

When using CSS media queries, you can cut out the need for duplication in your CSS. There is no need to duplicate CSS just to make Internet Explore continue to work with your otherwise responsive layouts. All you need to do is be clever in how you organise your styles and link your styles to the main document. This short article has outlined an approach to do this so that zero duplication can be achieved with media queries and this will make your CSS more maintainable in the long term.

Video Supplement



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

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