Introduction
This advanced HTML5/CSS3 technique was briefly discussed in the IoT (i.e. "Internet of Things") contest submission article 'enRoute: Real-time NY City Bus Tracking Web App' [1], which describes real-time NY City bus monitoring web app.
Compact, Scalable and Flexible solution
Due to the real-time nature of the City bus tracking app [1], it was quintessentially important to minimize the web data traffic (inbound/outbound), thus it was highly desirable to avoid any use of graphic files and limit the data communication exclusively to the text. As a good auld saying goeth - 'the picture is worth a thousand words', but it also weighs lots a kilobytes (that part was omitted from the original word of wisdom). Even in a highly-compressed form, the image file could outweigh the entire textual communication packet by order of magnitude or more.
Ideally, the real-time data communication exchange would be comprised just of text; no graphic files transmitted to the client. In order to produce some aesthetic enhancement, certain grahic images are available as Unicode characters: the use of them will solve the problem in the best possible way. In case of no appropriate Unicode character available, the other two options would be either creating a custom graphic image file (bad from size/flexibility perspective), or to apply advanced CSS3 technique, which in many cases is capable to produce a desirable compact pseudo-icon graphic enhancements. Scalability and ease of modification via CSS3 statements (rather that image editing) are additional advantages of proposed solutions over the use of graphic files, as discussed below.
Background
The original CSS technique used to produce a bus pseudo-icon for a real-time City bus tracking application [1] is shown below:
Listing 1. Bus "pseudo-icon" made of HTML5 div and CSS3 (original solution)
<!DOCTYPE html">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>BUS ICON</title>
<style type="text/css">
.b16 {
width:12px;
height:14px;
border-top: 2px solid #000099;
border-left: 2px solid #000099;
border-right: 2px solid #000099;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
background:#f0f0f0;
}
.b16 .b {
width:100%;
height:4px;
margin-top:4px;
border-top: 2px solid #000099;
border-bottom: 2px solid #000099;
background:#ffff00;
}
.b16 .b .bb {
background:#000099;
width:6px;
margin:0 auto;
height:4px;
}
</style>
</head>
<body>
<!--
<div class="b16"><div class="b">
<div class="bb"></div></div></div>
</body>
</html>
Corresponding to the Listing 1, "CSS3-synthesized" bus pseudo-icons look like the following:
Figure 1: Bus pseudo-icons made of HTML5 <div>
elements w/CSS3 styling technique
Desirable bus pseudo-icon can be added to HTML5 document with this simple line:
<div class="b16"><div class="b">
<div class="bb"></div></div></div>
In addition to small digital footprint, this compact solution provides tremendous flexibility over the graphic-file counterpart: color theme and overall appearance can be easily changed by modifying just couple lines within HTML5/CSS3, instead of going to image editing for every change needed. This technique is further extended with advanced use of CSS3:before
and :after
pseudo-elements.
Using the Code
The refined CSS3 styling technique that allows creation of the bus 'pseudo-icons
' by using :before
and :after
pseudo-elements is shown in the following Listing:
Listing 2. Bus pseudo-icon: HTML5 div w/CSS3 pseudo-elements (better solution)
/* BUS ICON, HEIGHT 12PX */
.b12
{
width : 8px;
height : 10px;
border-top : 2px solid #000099;
border-left : 2px solid #000099;
border-right : 2px solid #000099;
border-top-left-radius : 3px;
border-top-right-radius : 3px;
background : none;
display : inline-block;
vertical-align : middle;
}
.b12:before
{
content :'';
display : block;
height : 2px;
margin-top : 3px;
border-top : 2px solid #000099;
border-bottom : 2px solid #000099;
background : #ffff00;
}
.b12:after
{
content :'';
display : block;
background : #000099;
width : 4px;
height : 4px;
margin : -5px auto;
}
/*circle to use w/b12*/
.b12C
{
width : 18px;
height : 18px;
line-height : 16px;
vertical-align : middle;
text-align : center;
border-radius : 12px;
border : 2px solid #000099;
background : #fafafa;
}
Corresponding to the Listing 2, the bus pseudo-icons can be added to the Bing Map or any HTML5 document with a simple line:
<div class='b12'></div>
or, included in the circle:
<div class='b12C'><div class='b12'></div></div>
Suggested technique provides flexible and rather compact CSS3 alternative to graphic files. The following demo screenshot is linked to the real-time fully-operational web app utilizing the described technique.
Demo
The following sample screenshot of the real-time City buses tracking web application shows bus pseudo-icons
produced by the advanced CSS3 technique described above in Listing 2 . Click on the image link to view the live demo of real-time NY City bus tracking app:
Figure 2: Real-time NY MTA bus tracking app utilizes CSS3-generated bus pseudo-icons (shown in circles)
Flexibility and Scalability
Pseudo-icon solution is scalable and allows ease of customization: for example, the color theme can be changed just by couple lines in CSS stylesheet as shown in the following Listing 3 (HTML5+CSS3 encapsulated in a single file):
Listing 3. Bus pseudo-icon, flexible HTML5/CSS3 solution
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ADVANCED HTML5/CSS3: BUS PSEUDO-ICONS MADE OF DIV</title>
<style type="text/css">
.b1
{
display : inline-block;
vertical-align : middle;
width : 0.8em;
height : 0.8em;
border : 0.2em solid;
border-bottom : none;
border-radius : 0.3em 0.3em 0em 0em;
}
.b1:before
{
content :'';
display : block;
height : 0.2em;
padding : 0;
margin-top : 0.25em;
border-top : 0.15em solid;
border-bottom : 0.15em solid;
}
.b1:after
{
content :'';
display : block;
width : 0.4em;
height : 0.4em;
margin :-0.4em auto;
}
.b1, .b1:before { border-color: #000099; }
.b1:after {background : #000099; }
.b2
{
display : inline-block;
vertical-align : middle;
width : 1.7em;
height : 1.7em;
border : 0.3em solid;
border-bottom : none;
border-radius : 0.4em 0.4em 0em 0em;
}
.b2:before
{
content :'';
display : block;
height : 0.4em;
margin-top : 0.6em;
border-top : 0.3em solid;
border-bottom : 0.2em solid;
}
.b2:after
{
content :'';
display : block;
width : 0.9em;
height : 0.8em;
margin :-0.8em auto;
}
.b2, .b2:before { border-color: darkgreen; }
.b2:after {background : darkgreen; }
.b2:before { background : Yellow;}
</style>
</head>
<body>
<table>
<tr>
<td>Bus pseudo-icon, 1em, blue w/white headlights</td>
<td><div class="b1"></div></td>
</tr>
<tr>
<td>Bus pseudo-icon, 2em, green w/yellow headlights</td>
<td><div class="b2"></div></td>
</tr>
</table>
</body>
</html>
The solution is using CSS3 'em
' units for better scalability. Bus pseudo-icon color can be easily changed by the following two lines:
.b2, .b2:before { border-color: darkgreen; }
.b2:after {background : darkgreen; }
Optionally, headlights color can be specified via CSS3 property as following:
.b2:before { background : Yellow;}
The corresponding sample screenshot follows:
Figure 3: Bus pseudo-icons sample screenshots
Points of Interest
I was very excited about exploring a seemingly limitless opportunity of the advanced CSS3 styling technique, particular important in a real-time web apps where data traffic/packet size is rather critical. More on this topic in my previous articles/tips [2,3].
Practical consideration
For didactic purpose the entire solution (see the code snipet in Listing 3) is encapsulated in a single HTML file with CSS stylesheet structured for a better readability with tab/spaces and additional comments. There are couple important practical consideration pertinent to a production-level implementation of this solution. First, all comments and extra tab/spaces can be removed in order to further reduce the overall size. Also, it's quite important to split the file into two: HTML file providing the content and a CSS file included into the main one w/ link rel
statement as shown in the following Listing 4a,b:
Listing 4a: HTML file
<!DOCTYPE html>
<html>
<head>
<title>ADVANCED HTML5/CSS3: BUS PSEUDO-ICONS MADE OF DIV</title>
<link rel="stylesheet" type="text/css" href="BusIcon.css" />
</head>
<body>
<table>
<tr>
<td>Bus pseudo-icon, 1em</td>
<td><div class="b"></div></td>
</tr>
<tr>
<td>Bus pseudo-icon, 2em</td>
<td><div class="b" style="font-size:2em;"></div></td>
</tr>
</table>
</body>
</html>
Listing 4b: CSS style sheet in a separate file
.b
{
display : inline-block;
vertical-align : middle;
width : 0.8em;
height : 0.8em;
border : 0.2em solid;
border-bottom : none;
border-radius : 0.3em 0.3em 0em 0em;
}
.b:before
{
content :'';
display : block;
height : 0.2em;
padding : 0;
margin-top : 0.25em;
border-top : 0.15em solid;
border-bottom : 0.15em solid;
}
.b:after
{
content :'';
display : block;
width : 0.4em;
height : 0.4em;
margin :-0.4em auto;
}
.b, .b:before { border-color: #000099; }
.b:after {background : #000099; }
Separation of programming concerns, i.e. content (HTML) from presentation layer (CSS) is a well-known programming paradigm, particular important in this use-case. Major web browsers implement efficient caching technique, so the external CSS3 file (Listing 4b) typically will be cached upon first request, thus reducing the web traffic and giving performance boost to the consequent data requests.
Another advantage of the proposed solution, as discussed above, lies in its flexibility/scalability: it's sufficient to specify just a single pseudo-icon CSS3 style, easily modifiable through the code, as shown in this example. In order to increase the size of bus pseudo-icon (to make it, for e.g. 2x of the base one) just apply a single CSS statement: font-size:2em
; to the container div
element: it could be done in the main HTML file (as shown here for the didactic purpose), or in the external CSS file, which is more appropriate for a production release.
Possible alternatives
As stated in a previous subchapter, the best possible scenario would be using ASCII or Unicode character if any appropriate one exists. Otherwise, this advanced CSS3 technique is an option providing rather compact, flexible and scalable solution. Other alternative exists, in particular, the ones discussed in comments thread. The first suggestion of using highly compressed graphic image/files lacks flexibility/scalability and adds significant labor overhead dealing with image editing. Using canvas drawing is another suggested alternative, which also lacks of any tangible merits: it requires additional javascripting and raises web browser compatibility issues. Beyond those suggestions, it seems like SVG could be a valid alternative to this CSS3-based pseudo-graphic solution (SVG topic will be covered in a separate tip).
History
- Mar 2015: First draft solution released as described in [1] (contest article)
- Apr 2015: Advanced CSS3 technique applied to the original code in order to produce more flexible/compact solution
- Apr 2015: Another sample code added providing increased flexibility (using 'em' units and simplified CSS3 color theming)
- May 2015: Added code and guideliness pertinent to a production-grade solution.
References
- A.Bell, "enRoute: Real-time NY City Bus Tracking Web App" (Codeproject IoT contest submission)
- Advanced CSS3 Styling of HTML5 SELECT Element
- Toggle Button built on ASP.NET CheckBox and HTML5/CSS