The overuse of HTML5 and CSS3
As I’m getting more familiar with all the aspects of designing for the web I constantly bump into small unimportant problems. In most cases those problems can be solved with some CSS trickery or javascript. One way or the other I always find some sort of solution that works out pretty fine, up till now.
The challenge
A few weeks ago I designed some category tags with a slightly odd shape for a WordPress blog. Normally I would slice up a PSD-file in different parts and use them as background images to style those kind of tags. For this blog I figured it would be a nice touch to fully style the tags in CSS3. I came to this idea after reading an article on how CSS3 can be used to create different kind of shapes. Because the shape of the tags I designed was pretty basic, I thought it was perfectly possible to design the whole thing in CSS3.
The tags I designed in Photoshop consisted of 7 styling elements:
- Round corners
- Gradient fill
- 1 px solid border
- Uppercase text
- Lighter hue text shadow to create depth
- A triangular extension
- A tiny hole with border
The first 5 elements are very easy to do. The triangular extension and the tiny hole in the middle on the other hand are a bit of a challenge. The triangle can be made with transparent borders and the hole can be seen as a tiny square with nothing but rounded corners.
Execution
For an overview of all the techniques used for this article take a look at the demo page I made. From top to bottom you’ll find the same tags designed in Photoshop, with CSS background-image property, CSS3 and HTML5.
First try: CSS3 transparent borders
For this exercise I based my coding on an excellent tutorial written by Alan Grakaric. Alan makes use of the CSS selectors “:after” and “:before” to keep the amount of HTML elements as low as possible.
<ul id="css3"> <li><a href="#">Photoshop mockup</a></li> <li><a href="#">CSS background-image</a></li> <li><a href="#">CSS3 border-radius</a></li> <li><a href="#">CSS3 transparent borders</a></li> <li><a href="#">HTML5 Canvas</a></li> </ul>
The left triangle in the tag is going to be a challenge. As mentioned the technique Alan Grakaric used, involves transparent borders. The trick is to add thick borders to an empty element. All borders will look like a triangle because that’s how the box-model is designed. If you make all but one border transparent you end up with a triangle.
ul#css3 a:before{
content:""; /* Empty element */
float:left;
position:absolute;
top:0;
left:-8px;
border-color:transparent #c9e5f5 transparent transparent;
border-style:solid;
border-width:12px 8px 12px 0; /* 24px high, 8px wide */
}
For the rest of the styling I used a gradient fill for the background and border-radius for the rounded corners. You can take a look the source code for more details. The final version looks like this:
As you can see all of that CSS3 styling is doing a pretty good job in general but it’s lacking something. The transparent border trick worked to make a triangular extension but it is impossible to add an extra border to that triangle. So the triangle trick is quite ingenious, but it doesn’t solve the real problem. It’s still impossible to really change the shape of an HTML element with CSS.
Second try: HTML5 canvas
Now that we’re exploring new grounds we can just try HTML5 as well. One of the new elements W3C introduced together with HTML5 is the Canvas element. This element allows us to draw any kind of shape directly into an HTML file. Essentially it’s just another HTML element such as a div or a span in which something can be drawn with javascript. It goes something like this:
window.addEventListener('load', function () {
// Get the canvas element.
var can1 = document.getElementById('canvas1');
var context = can1.getContext('2d');
// Define how the shape should be filled
var lingrad = context.createLinearGradient(0,0,0,25); //create variable with linear gradient from top to bottom
lingrad.addColorStop(0, '#c9e5f5'); //set top color
lingrad.addColorStop(1, '#aed8f0'); //set bottom color
context.fillStyle = lingrad; // set fillstyle to variable "lingrad"
// Define how stroke should look like
context.strokeStyle = '#86bedf'; //stroke color
context.lineWidth = 1; //stroke width
// Create tag shape
context.beginPath(); // Let's start drawing our shape.
context.moveTo(0.5, 12); // Where to start drawing.
context.lineTo(8.5, 0.5); // Draw top diagonal side of arrow
context.lineTo(161.5, 0.5); // Draw top side of shape
context.quadraticCurveTo(164.5, 0.5, 164.5, 3.5); // Draw the top right rounded corner
context.lineTo(164.5, 20.5); // Draw right side of shape
context.quadraticCurveTo(164.5, 23.5, 161.5, 23.5); // Draw the bottom right rounded corner
context.lineTo(8.5, 23.5); // Draw the bottom side of the shape
context.lineTo(0.5, 12); // Draw the bottom diagonal side of arrow
context.closePath();// Stop drawing that tag shape
context.fill(); // Fill the shape as defined above
context.stroke(); // Add a stroke to the shape as defined above
// Add little white hole in tag
context.fillStyle = "white"; // Set filling color to white
context.beginPath(); // Start drawing circle shape
context.arc(12,12,3,0,Math.PI*2,true); // Circle with 3px radius
context.closePath();// Stop drawing that tag shape
context.fill(); // Fill the hole as defined above
context.stroke(); // Add a stroke to the hole as defined above
}, false);
I was really amazed with the sort of freedom you get when you design with this technique. You can give exact dimensions to the shape, add a gradient fill, add a border and so on. On the other hand, the freedom of drawing exact shapes is also a shortcoming since the dimensions of each drawing are fixed. If you add dynamic content to the canvas, such as a dynamically created text, it will not resize according to its content. This clearly shows in the rendering at the demo page or in the screenshot below.
I don’t want to discard this technique as something incomplete because I’m sure there’s a way to change the width of each tag with an extra piece of javascript code. But as a novice I’m not (yet) capable to craft something like that. For now I think it’s fair to say that HTML5 canvases are not designed for this sort of tasks.
Final try: good ol’ background-image
So there I was, almost a full day had past and I still had nothing functional. At that point I knew I had to fall back to the good old background-image property. It’s very easy to implement, works like a charm, works on every browser and is still pretty lightweight.
As you can see in the image above, the end result is a perfect copy of the Photoshop mockup. All of the elements are there, the width of the tags changes according to its content and all it took was a few lines of code.
Conclusion
Today I learned a lesson in efficiency. Sometimes you neglect the easiest things when you are getting too ambitious. New technologies are invented for a reason and if you don’t have a clear understanding of that reason, you end up making it yourself too complicated. Lately, the use of CSS3 and HTML5 is booming in the web design sector. For almost each task, designers find some way or another to implement CSS3 or HTML5 because it’s the latest thing. Sometimes it’s overlooked that older proven techniques are just better for the job than the new fancy stuff.
Although I see a ton of possibilities with some of the HTML5 specification for the future, I believe CSS3 is taking us in the wrong direction. Or better, I believe designers all over the world are using CSS3 for the wrong reasons. One of the biggest limitations of CSS3 is that it’s still impossible to really change the shape of an HTML element. And that is quite frustrating because that’s exactly what designers want. They want full control over the look and feel of their websites. So they end up using little hacks and tricks to mimic what they want.
I strongly believe that we’re getting there step by step. Canvas drawing allows us to create any shape we want. We can now fully control the way shapes looks, how they’re oriented, which size they have and so on. The only problem is that a good understanding of javascript is needed to complete the more difficult tasks. Until now web designers were pretty spoiled with the limited designing options they had. In the future they’ll have to start learning to code whether they like it or not. I believe this will cause a great shift in how websites will be built in the future. Chances are that a lot of the upcoming web designers will grab to WYSIWYG applications that will do all of the coding in the background. This might create a bigger gap between coders and designer then there ever was before.
What do you think? Will technologies like HTML5 bring designers closer to coders or will it drift them further away from each other?







