Styling Tabular Data with CSS3

In my career as a web developer, I’ve helped build many web applications that require the display of tabular data in a clean and simple fashion. Over time, I’ve developed a few techniques for doing so that are effective and easy to implement.

But before I go into that, let me quickly remind my fellow web developers that tables are not, in fact, the enemy. Although the days of using tables for layout are long past, tables are still a perfectly appropriate method for displaying tabular data on the web.

However, I must also acknowledge that there are some disadvantages to working with tables to be aware of, including:

  1. Tables don’t always scale down well and may display poorly when space is limited, like on mobile devices. If your primary audience is viewing your web site on mobile devices, it may be better to use lists or other markup that’s better suited for vertical display.
  2. Tables are not as adaptable as other elements, especially in older versions of Internet Explorer, and that can limit your options when developing a responsive web site.
  3. Display tends to vary slightly across different browsers. This is particularly true with column widths. I’ve encountered many situations where the text in one column wraps to two lines while there is clearly ample space to accommodate for it in another cell. There are ways to get around that of course, but the solution is generally specific to the situation.

So after much preamble, here are four simple examples that I’ve created to demonstrate different ways you can work with tables to display data cleanly:

  1. Basic Grid with Alternating Row Colors
  2. Basic Grid with Alternating Row and Column Colors
  3. Basic Grid with Rounded Corners
  4. Simplified Grid with Generated Content
Advertisements

Optimizing Site Speed

Talking about site speed today almost seems superfluous, with so many users accessing the web with powerful Internet connections and download capabilities. Most desktop users access the web via cable or fiber optic lines, brandishing download capacities of 15 megabits per second (Mbps) or greater. Although many users will often access those same Internet services via wireless signal, the rapid spread of 4G networks has brought similar download speeds to mobile devices even when they aren’t connected to WiFi.

Despite all that, there are still some desktop users that access the web using DSL or dial-up connections and many mobile users that are restricted to less powerful networks.

But, regardless of all the latest technologies, there will always be some subset of users that hit your web site with poor Internet connections. In addition, many mobile users are limited to how much they can download over their provider’s data network. Personally, I’m limited to 2 gigabytes of data usage per month, excluding any data transferred over WiFi.

That means that when we build and maintain web sites, we need to be cognizant of users’ technology capabilities, as well as their limitations, and plan accordingly.

Understanding Your Users

The first step towards building an optimized web site is simply getting to know your users. Getting a basic idea of user demographics such as age, income, and location will allow you to make some general assessments about how they are accessing your site.

I recommend utilizing Google Analytics to help verify (or nullify) any assessments that you have made about your users. There are several “Audience” reports that will help you gain some insight.

  1. Demographics > Location – Shows where your users are located geographically.
  2. Technology > Browser –  Shows what browsers your users are accessing the site with. I like to check this prior to development to help determine what browsers need to be supported for the site.
  3. Technology > Network – Shows what Internet networks are being used to access your web site. This may give you some idea about your users’ download capabilities.
  4. Mobile > Overview – Shows a basic breakdown of your total desktop, mobile, and tablet users.

Google Analytics doesn’t collect enough information to paint a detailed picture, but these reports, combined with your own experiences, should give you a pretty good idea of what to expect.

Once you understand your users, you can then determine which optimization practices are necessary for your site.

Optimization Basics

Here are some easy techniques that I recommend for all sites, regardless of user technology.

  1. Minify CSS and JavaScript files. This will remove all unnecessary spaces from your files and reduce their size. I prefer cssminifier.com.
  2. Combine CSS files to reduce HTTP requests. Previously, I would keep my screen, mobile, and print styles in separate files, but I have begun combining them into a single file to reduce the number of requests the browser has to process.
  3. Create image sprites. Likewise, you can reduce requests by creating a single image with all of your design files. High traffic web sites like Amazon.com use this technique frequently, but I find it to be a bit cumbersome and avoid it unless I feel it’s necessary.
  4. Scale down and optimize images for the web. I recently noticed a client site was loading slowly and discovered that three of the photos on the home page totaled over 12 mb. By simply scaling those images down to dimensions that fit their container, I was able to reduce the page weight to well under 1 mb.
  5. Optimize PNGs. Photoshop is notorious for creating bloated PNGs. There are many services that you can use to reduce the bloat and overall file size. I like TinyPNG.
  6. Only reference the files that you really need. If you are only using JavaScript on the home page, only call the file on the home page. There’s no need to impact the loading of other pages if they never use the file.
  7. If you are using jQuery or another popular code library, consider referencing Google’s hosted copy. Since many other sites do the same, users may already have the file cached in their browsers, which will save loading time.
  8. Many JavaScript libraries such as Modernizr allow you to customize what code is included in the file that you create. Only download the functionality that you really need.

Most of these steps are simple and can easily be implemented on any web site without impacting quality or deadlines. Doing these things will reduce page weight, decrease loading time, and ultimately improve user experience.

There are many other things that you can do to help reduce page weight and decrease load time, but you’ll need to decide what techniques are right for you and your site. In many cases, the basics may be fine, but in others, every kilobyte may be important.

To learn more about page weight optimization, I recommend reviewing the Network and Audits features within Google Chrome’s Developer Tools. I also really like the Pingdom Tools website speed test. Both of these will break down how long it takes each resource to load and provide suggestions for optimizing your site.

My Presentation Slides: Making Your Site Printable

This post originally appeared on my blog.

On Friday, May 17 I had the pleasure of speaking for the first time at Stir Trek, a one-day conference in Columbus, Ohio, that drew over 1,200 attendees (and I understand sold out in just a few minutes). Apparently the name is a reference to the MIX developer conference, for which they were unable to obtain license to use a variation on the name.

I also had the pleasure of presenting for the first time on best practices for making your web site printable, built from my own professional experience, my PrintShame site, and an article I wrote for .net Magazine, among other resources (also linked in the presentation).

With 40 great speakers across 8 different tracks, there was quite a lot to offer throughout the day. Considering the other presentations held at the same time as mine, I was thrilled to get any audience and more excited to see that those who attended saw value in the topic and asked great questions throughout.

As promised in the session, I have made my slides available online via SlideShare and embedded them here:

Well after the talk I got even more questions and feedback on the session, which I truly appreciated. Since there is no official survey for attendees to give feedback on a speaker, I am hoping any attendees will feel comfortable tweeting about it or leaving a comment here. So far I have gotten one great bit of feedback on Twitter:

(I worked in some accessibility tips during my presentation.)

All other feedback is welcome (including if I was loud enough when the lavalier microphone failed).

While in Columbus I also had the pleasure of having a nice dinner (I arrived too late to make the speaker dinner), visiting the North Market, and, as part of the conference, getting to see a double feature of Iron Man 3 and Star Trek: Into Darkness. All around a good time which I look forward to repeating next year.

Don’t Use Global Browser Stats

This post originally appeared on my blog on May 2, 2013.

When I say “global,” I don’t necessarily mean the whole world, but really any aggregate pile of numbers for browsers that aren’t culled from your own site or project.

With IE6 finally fading (which many developers will claim is a result of their IE6-blocking sites), the ire of developers has turned to Internet Explorer 7. Given that many web developers want to play with the new shiny (and not worry about supporting older browsers) or hate the extra work that sometimes comes with supporting older browsers, it’s no surprise that disdain for IE7 is high.

It is with that experience that I think casually tweeting global stats and calls-to-action can be irresponsible without context, as this one on Friday:

This tweet led to the usual self-congratulatory responses of how it’s a web developer’s responsibility to force users to upgrade, old browser support is just a false assumption from the client (and maybe that client should be fired), money is being thrown at the wrong problem, IT departments are just jerks, and so on. While Paul clarifies in a follow-up tweet that he still thinks the content should be accessible, that point is lost as a tweet response instead of a tweet all his followers will see.

Competing Stats

Some responses were more thoughtful and based on a different source of global stats:

Akamai chart.
Screen capture of Akamai chart with Safari, IE7 and IE10 highlighted.

The Akamai chart shows that IE7 is about on par with IE10 and even fares slightly better than Safari 6. The more discerning viewer might notice that Safari use goes up on weekends just a bit while IE7 use drops off for the same period, suggesting IE7 traffic might be coming from office workers.

Ignore Stats That Aren’t Yours

A few people try to make the point that those numbers don’t apply to their sites, some even try to make the point that this isn’t about browser support at all:

As an example, I have a site I was working on last night that gets 7.3% of its traffic (over the last month) from IE7. That’s about one in 14 users. I know I have to support users on IE7 because I look at the stats for the site, not because I look to Akamai, StatCounter, or anywhere else.

Here’s the takeaway I want everyone to recognize: The only browser statistics that matter are those for the site you’re supporting.

I feel so strongly about that point that I am going to quote myself just one sentence later:

The only browser statistics that matter are those for the site you’re supporting.

This Applies to Other Stats

I’ve seen plenty of people discuss window sizes over the years and make generalizations about what sizes to support — even more common in the era of responsive web design. But global screen sizes are irrelevant. Instead, look at the numbers for the site you’re supporting. Even better, look at the viewport size:

There has been a resurgence in discussion of late on print styles, but nobody seems to have any stats for how often users print pages. In the absence of raw data, developers talk about how they use sites and how their circle of contacts use sites. Instead, track it for your own sites and know when pages are being printed:

There are many other cases where developers look to global stats in lieu of tracking their own, but I haven’t written tutorials for them. Now might be a great time to consider writing some of your own for the data points you want to capture.

Related

My Previous Rants

Going the Wrong Way

While supporting your users, and by extension their browsers, is the best approach, it is possible to get so focused on browsers themselves that instead of cutting edge you end up doing the opposite (even if it takes time to become apparent). Take this example from the UK Department for Work & Pensions:

The service does not work properly with Macs or other Unix-based systems even though you may be able to input information.

You are likely to have problems if you use Internet Explorer 7, 8, 9 and 10, Windows Vista or a smartphone. […]

There is also a high risk that if you use browsers not listed below, including Chrome, Safari or Firefox, the service will not display all the questions you need to answer.

The supported list of browsers and operating systems are combinations of Microsoft Windows 98, Windows ME, Windows 2000, and Windows XP with the browsers Internet Explorer versions 5.0.1, 5.5 and 6.0, Netscape 7.2, Firefox 1.0.3, and Mozilla 1.7.7.

Tracking When Users Print Pages

Originally posted on my blog on March 26, 2013.

A few months ago I had the pleasure of writing a piece for .net Magazine about print styles (Make your website printable with CSS). It was posted to .net’s web site last month and received an overwhelming one comment. That comment, however, summed up something I hear all the time:

Would be interesting to see some statistics on how many people actually print websites.

For years I have argued that the best user statistics are those for the site you are building. In the absence of global numbers for how many users print web pages, in this post I’m going to show you how you can measure how many (and which) pages get printed from your site by using Google Analytics. I am also hoping those who know everything about Analytics can answer some of my questions.

The Concept

While looking around for existing solutions to track printed pages, I found this article: Use Google Analytics to Track When People Print your Web Pages (written exactly one year before I got my own code working). While there doesn’t appear to be anything wrong with this approach (I did not try it), how it both produces the tracking code (JavaScript) and presents the data in Analytics (different than how I report on custom events), doesn’t match my preferred approach.

I want to be able to call the Google Analytics tracking image (__utm.gif) only when the page is going to be printed, skipping unnecessary HTTP calls and the resulting image download (brief though it is). I rely on the CSS @media print declaration to call the image. I also don’t want to write that image call to the page with yet more client-side script when I can assemble it all right on the server.

Since my post Calling QR in Print CSS Only When Needed already outlines the general flow (presuming I only want to support Internet Explorer 8 and greater), I can lean on the CSS syntax there.

To reiterate this technique will not work in versions of Internet Explorer 7 and earlier.

Constructing the Query String

I had a heck of a time finding information on how the Analytics query string needs to be constructed, and when I did find information it didn’t always explain the values in much detail.

Google’s developer site has information on all the query string parameters for the GIF request, but no information on what is required or what all the possible values might be. I did find a list of what may be the required parameters while searching among a thread on tracking emails with Analytics. Through a good deal of experimentation I came up with the following minimum list for my purpose:

Variable Description
utmac Account String. Appears on all requests. This is your UA-#######-# ID.
utmwv Tracking code version. While my standard GA requests use 5.4.0, I opted to use 4.3 for reasons I no longer recall.
utmn Unique ID generated for each GIF request to prevent caching of the GIF image. I just concatenate the current year, month, day, hour, minute and second.
utmhn Host Name of your site, which is a URL-encoded string.
utmr Referral, complete URL. In this case I just insert a dash so it is not blank.
utmp Page request of the current page.
utmt Indicates the type of request, which is one of: event, transaction, item, or a custom variable. If you leave it blank, it defaults to page. Because I am tracking events, I use event.
utme Extensible parameter. This is where you write your event. I use 5(Print*{page address}). See below for why.
utmcc Cookie values. This request parameter sends all the cookies requested from the page. It can get pretty long. It must be URL encoded. It must include __utma and __utmz values.

Because the whole point of this is exercise is to track the event in Google Analytics, it was important to understand how to construct the event for the query string. I struggled a bit.

I still haven’t figured out what the number 5 maps to, but it works. I also found that I need an asterisk as a separator, though I found no documentation explaining it. In the end, the only way a print event tracked as I wanted was when I constructed it as: 5(Print*/Accessibility). In this example, /Accessibility is the address of the page I am tracking.

The other tricky bit is pulling the cookie value and stuffing it into the string. Conveniently I can get to this within our content management system (QuantumCMS, which you should use) on the server side. Many others (if not most or all) have a similar ability. At the very least you have to include the __utma and __utmz values, passed as encoded parameters for utmcc. Without these, my tracking would not fire.

The Completed Query String

For ease of reading, I will break the string to a new line at each &. This represents what is generated when I visit the careers page on the Algonquin Studios site using Opera.

http://www.google-analytics.com/__utm.gif
?utmac=UA-1464893-3
&utmwv=4.3
&utmn=2013326124551
&utmhn=algonquinstudios.com
&utmr=-
&utmp=/Engage/Careers
&utmt=event
&utme=5%28Print*/Engage/Careers%29
&utmcc=__utma%3D267504222.1477743002.1364314722.1364314722.1364314722.1%3B%2B__utmb%3D267504222.17.7.1364314901604%3B%2B__utmz%3D267504222.1364314722.1.1.utmcsr%3D%28direct%29|utmccn%3D%28direct%29|utmcmd%3D%28none%29

Constructing the CSS

Now that you have the query string and the Google Analytics tracking image, you just need to call the image when the page is printed. All you need to do is embed a style block at the top of your page with the print media query, and call the image within it:

@media print {
 header::after
  { content: url(http://www.google-analytics.com/__utm.gif?utmac=UA-1464893-3&utmwv=4.3&utmn=2013326124551&utmhn=algonquinstudios.com&utmr=-&utmp=/Engage/Careers&utmt=event&utme=5%28Print*/Engage/Careers%29&utmcc=__utma%3D267504222.1477743002.1364314722.1364314722.1364314722.1%3B%2B__utmb%3D267504222.17.7.1364314901604%3B%2B__utmz%3D267504222.1364314722.1.1.utmcsr%3D%28direct%29|utmccn%3D%28direct%29|utmcmd%3D%28none%29); }

If you read my post on embedding QR codes, then this code will be familiar — I use header::before in that example. As such, I use header::after here so you can use them both keyed off the same element (header) without conflict.

If you look closely, you may have noticed that my event parameter looks like 5%28Print*/Engage/Careers%29 instead of 5(Print*/Accessibility). I URL encoded the parentheses on the entire string to make certain that they do not conflict with the parentheses in the CSS. If you don’t do that, the browser will get confused and fail to load the image.

Once you have the CSS in place, I recommend going into HTTP Fox or the Chrome Developer Tools to make sure the image is called when you fire a print preview (save paper!), and then to make sure it has the parameters you expect — particularly the utme value:

Screen shot of Chrome Dev Tools.
Screen shot of Chrome Dev Tools showing the query string parameters for the tracking GIF.

Checking Your Google Analytics Report

Assuming you’ve verified all is working well, you just need to run a report for events in Google Analytics. Bear in mind that Analytics isn’t up-to-the-minute, so you may need to give it some time to capture all the data.

Log into your Analytics account and make sure you set the report date to the time period where you rolled out these changes. Choose “Content” from the “Standard Reports” on the left side. From there, expand “Events” and then select “Top Events.” You should see “Print” as one of the items in the “Event Category” column (you may need to show more rows).

Screen capture from Google Analytics
After you click “Top Events,” you will see all of the events you are tracking (if any other).

Click on the word “Print” in that grid and you will see all the pages that were tracked (ostensibly because you or a user printed the page).

Screen capture from Google Analytics
The report is handy if you know the page addresses, but Analytics doesn’t think of them as such. As a result, clicking the addresses will not take you to the page.

From here you can run a secondary dimension to cross-reference this with more information. In my example, I tested different pages in different browsers so I could quickly verify the cross-browser support. You can run screen resolution, landing page, or any other dimension that you think might be handy to compare.

Screen capture from Google Analytics
An example comparing the printed pages with the browser as a secondary dimension of the report.

Conclusion

I am just adding this to my own site, so I don’t have any numbers to offer as part of this post. However, if you implement this please feel free to let me (and everyone) know how many users you have who print and for what site. I don’t expect the numbers to be high, but I do expect to see it happen here and there.

If you have any additions, corrections or suggestions, please let me know. I am still unclear how all the Google Analytics query string parameters come together and exactly what they all mean, so there may be some optimizations I can work into it.

Related

Related articles on print styles:

Stuff I’ve Written

Chrome: Blink and You Missed the News

This post originally appeared on my blog on April 4, 2013.

The new Blink logo.
It’s old news by this Thursday morning, but in case you had not heard, Google is forking WebKit to make its own rendering engine, Blink. Opera will be using the Blink fork of WebKit as its rendering engine.

A combination of people who are far smarter, far more well connected, and in timezones that allow them to write about this sooner, along with all the Twitter chatter, has already hashed out the major details. As such, I will link to them below. I would be a terrible blogger if I didn’t offer my opinion, however.

I will format this the way I did when I provided my in-depth analysis of Opera’s move to WebKit (away from Presto) less than two months ago.

So what does this really mean?

For Developers

Any developer who is complaining that this means there is another browser/engine against which they will need to test has been doing it wrong.

Web developers should always test against different browsers, regardless of their engine. In particular, WebKit has so many nuanced implementations that not independently testing against each browser that uses WebKit belies either a lack of understanding of how WebKit is implemented or laziness.

If you aren’t sure what is different between each WebKit implementation (Chrome, Safari, Android browser, Opera, etc.), I encourage you to read my post “WebKit Will and Won’t Be the New IE,” where I provide a high-level overview of these variances.

For Users

At this point it doesn’t mean a whole lot.

Google will argue this is better for users. Apple will argue that Google took its ball and left. Opera won’t be arguing. None of that impacts users because we have mostly done a good job of promoting standards-based development. I again refer you to “WebKit Will and Won’t Be the New IE” for how poor testing can impact users, but that’s not a function of the engines.

Because Apple only allows WebKit on iOS devices, and even then it restricts those browsers to a different JavaScript engine and thus a lesser experience, Chrome and Opera for iOS may still stay on WebKit. Over time as its harder to incorporate features from Blink back into the WebKit core, there may be feature divergence which may affect users.

That’s just speculation on my part.

For Standards

For a specification to become a W3C recommendation, there must be two 100% complete and fully interoperable implementations, which basically means two browsers need to support it. When Opera announced the shuttering of Presto, that left Trident (Internet Explorer), Gecko (Mozilla), and WebKit (Safari and Chrome) as the remaining engines (of measurable size). Essentially, two out of the three of them had to agree to implement a feature.

With Blink, provided the W3C recognizes it as a stand-alone engine, there is now one more engine back in the mix, essentially returning the count to where it was in February before Presto’s wind-down (to be fair to Presto, it’s expected to exist in the wild until 2020, but with no new feature development).

I am hoping that this is a good thing for standards.

Blink won’t be using vendor prefixes (even though it will have inherited some), so I consider that a step in the right direction. While I think this matters to developers, I think it matters even more to standards.

Technical Aside

From Peter-Paul Koch:

Chrome 28 will be the first stable release to use Blink; earlier versions will use WebKit. Opera and Yandex will start using Blink whenever they start using Chromium 28.

Related

First some bits from The Twitters:

And now to the related links:

There’s this one from 2010 by Haavard Moen that I thought worth highlighting: “Dear Google: Please fork WebKit.”

Update, 5:35pm

A video Q&A from Google Developers about Blink (time markers available on the Chromium blog).

Calling QR in Print CSS Only When Needed

This post originally appeared on my blog on March 8, 2013.


For those of us who put together print styles for our sites, we’ve probably tossed around the idea of embedding QR codes so that users can quickly get back to a page they have printed. In the hardcopy version of my article for .net Magazine, “Make your website printable with CSS,” I show how you can embed QR codes in your page (it’s not included in the online version).

In my example I use the Google Charts API to generate the QR code on the fly. The problem in my example is that the QR code image gets called whether or not you print the page. Not only is this an additional HTTP request, it’s also an additional download that immediately gets hidden. This puts a bandwidth burden on users who aren’t printing, but it’s also the only way to support your users on Internet Explorer 8 and below (who may be the ones trapped at the office who want to bring the document home).

If you truly have no IE8 or below users, then the less bandwidth-hoggy approach is rather simple, if a bit inelegant.

Since each call to the Google Charts API to get the QR code must include the full address of the page, I cannot leave this to my linked CSS file (which is static, not run through any server-side processing), nor would I want to push every URL for every page of my site into that file. Initially I wanted to use a data- attribute to hold the URL and then, using the generated content feature of CSS, have it take that value and feed it into the content: CSS declaration to have it generate the image from there. Except that’s not how CSS works. You cannot use CSS to generate an image from a CSS variable.

The easiest solution is to a put a style block at the top of your page (something I hate doing) and feed the current page’s URL into the Google Chart API query string to dynamically draw the image. The rest of the styles that affect placement, spacing, etc. should all be in your print stylesheet already. The example:

@media print {
  header::before
    { content: url(http://chart.apis.google.com/chart?chs=120x120&cht=qr&chl=http%3A%2F%2Falgonquinstudios.com/Engage/Careers); }
}

That’s it. Now when (and only when) you call the print styles, the image will load. As proof, here is a screen shot using HTTPFox showing the page before the print styles were called and after, where you can clearly see the QR code is called only when the print styles are fired.

Screen shots of the list of HTTP requests before and after the print styles were fired. You can click / tap to see the full-size image.
Screen shot of the print preview with the generated QR code in place.

Note: This technique will not work in any version of Internet Explorer that doesn’t support CSS generated content, which includes IE 8 and below. Internet Explorer 9 and above happily include the QR code generated with this method.

App Store Meta Tags

Screen shot of Dominos home page on Nexus 7.
Why yes, Dominos, I’d love to tap again to get your real home page to order a pizza when I could have done it right here, below your over-sized app pitch that could be done in a tiny ribbon.

This is an adapted and updated version of a blog post on my site from last week. This post includes a real-world example of the feature.

This may be old news to some of you, but I haven’t found a place that collects this in one spot.

One of the most offensive experiences I have when surfing a site on my mobile devices is being forced to click through an advertisement for the site’s app in the iTunes store (even moreso when I am surfing on a non-iOS device). There is a fair number of sites I have tapped away from because of this (I also don’t expect to be served the page I came to see, but instead shunted to the mobile home page).

If yours is one of those sites, whether promoting your entire user experience or just a product, there is a less offensive way to present your pitch to users on iOS and Windows Phone.

Platforms

iOS 6

Safari on iOS 6 and later devices can promote your app with a standardized banner. Essentially you stuff a custom meta tag into your page that references your App Store ID. If the user already has the app installed, then the ad becomes a launcher instead.

The code is pretty simple:

<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">

  • app-id is required and references your app’s identifier.
  • affiliate-data is optional and uses your iTunes affiliate string.
  • app-argument is also optional and can allow users who have your app installed to jump to a specific place in your app.

More details at Apple’s developer site: Promoting Apps with Smart App Banners

Windows 8

Microsoft offers a similar feature for users of Windows 8 in non-desktop mode who are also using Internet Explorer. I have not tried it, so I cannot explain how this works as the user changes modes nor how it works with the “charms” feature of Windows 8.

This code is relatively simple as well, though it requires two meta tags and supports up to five:

<meta name="msApplication-ID" content="microsoft.build.App"/>
<meta name="msApplication-PackageFamilyName" content="microsoft.build_8wekyb3d8bbwe"/>

  • msApplication-ID is required and references your app’s identifier.
  • msApplication-PackageFamilyName is required and contains the package family name created by Visual Studio.
  • msApplication-Arguments is optional and lets you pass arguments to your app.
  • msApplication-MinVersion is optional and can direct users with an old version to the Windows Store.
  • msApplication-OptOut

More details at Microsoft Developer Network: Connect your website to your Windows Store app (Windows)

Google Play, BlackBerry App World, Etc.

In addition to Google Play, BlackBerry App World, I looked for similar features for the Firefox OS and Ubuntu Mobile stores. I know there are other mobile platforms out there for which I did not look.

If you know of other app stores that offer similar features, please let me know so I can update this post.

Real-World Example

One of our spin-off companies, SWRemote, has an app available for iPads. There is value in promoting the app to visitors of the site but not in blocking their access to the site content with a splash page or an extra click, especially if they are not on iPads. The SWRemote web site is powered by QuantumCMS (yes, I am promoting our web content management system), which makes it about 30 seconds of effort to add the necessary meta tag to the site.

Screen shot of the QuantumCMS custom meta tag screen.
Screen shot of the QuantumCMS custom meta tag screen.

If you are already a client of ours on QuantumCMS, all you have to do is choose Site Configuration from the Settings menu and pop into the Marketing tab. This is the screen that allows you to add custom meta tags. Press the Advanced button and you are off to the races. In the Name field, for this example, I just entered “apple-itunes-app” and in the Content field I provided the custom ID for the app appended to “app-id=.” As soon as I hit Save the web site was showing the app bar to visitors:

Site on the iPad3 without the app installed. Site on the iPad3 with the app installed.
Screen shots of the SWRemote site on an iPad3 both with the app installed and without it installed, showing how the bar changes its message.

Oddly, even though the app runs on the iPad Mini, which is running iOS6, the app bar never appeared on the site when viewed on the iPad Mini. On an iPhone 5, the app bar started to appear and then disappeared — probably as the device recognized that there is no iPhone version of the app.

If/when there is an app available for Windows Phone, the process to add this feature will be the same, allowing the site to promote both apps dependent on the audience. QuantumCMS helps make the process easier, with no need to code any changes to your site templates.

Related

There are other places where custom meta tags are used to display targeted content. One example is used for Twitter Cards and another example is used with Google News. While you can build support for them, neither Twitter nor Google is going to use them unless you have been vetted in advance.

Letting Mobile Users See Desktop View of RWD Site

Originally posted on my blog on January 11, 2013.

Bruce Lawson tweeted out a seemingly random musing today that I have pondered myself — what if, while on a mobile device and surfing a RWD web site, I want the desktop version of a site?

There are many reasons as a user that this might be the case, ranging from poor development practices that hide chunks of content you need to see to just wanting to know what it looks like.

Clearly it’s enough of a use case that mobile browsers such as Opera Mobile, Chrome, Firefox, and so on, have a feature to request the “desktop” version of a site from a menu built into the browser.

Except that feature doesn’t work with a RWD-powered site because media queries, typically based on viewport width, are used to deliver styles for traditional desktop window sizes. The browser feature only sends a different user agent string (bypassing terrible user agent sniffing) but doesn’t do much else. Your 320-pixel-wide device is still 320 pixels wide, and the media queries know it.

Until the mobile browser makers report a false viewport (or, rather, assume one when choosing CSS from a set of media queries), we’re kind of stuck. While I have many ideas on how that might work, that won’t address the issue today.

While I had bandied about an idea to address this on the redesign of my site a couple years ago, it took a client request last year to get my team the time to finally code a solution.

There are some core steps the hammer out in the logic of any solution:

  1. Put a link on the page to view the desktop layout. I prefer to have it in the raw HTML over writing it in with script.
  2. In the more mobile-friendly CSS files allow this link to display. In the more desktop-friendly CSS files hide the link.
  3. Either using a round-trip to the server or client-side script, remove the media query logic and serve up the “desktop” CSS.
  4. Warning for Europeans: cookies. Set a cookie with that preference for the user. Whether it is for the current session, forever, or somewhere in between is worth an internal discussion.
  5. Now display a link to view the “mobile” version of the site. Again, this can be done with or without script.
  6. If the user clicks the link to see the mobile version, re-instate all your media queries, clear the cookie and pretend nothing happened.

This process is a bit oversimplified, but it covers the broad strokes.

There are some hurdles, of course. Your users might not understand what you mean by “desktop” or even “mobile.” You could make the link to get out of one of the views too hard to find. You could bump up against expectations set by the mobile browser feature to request the desktop site. If you serve mobile styles to IE6 users, you could confound them if you don’t clear the link from the page for them. And so on.

You can play around with what we implemented for our client at CHSBuffalo.org. View the source to see the styles and script. There is obviously logic on the server side, but you can make up your own for your own server platform.

These screen shots should give you an idea of what to expect when you visit the site:

The CHSBuffalo.org site as seen on an iPhone and on a Nexus 7, all styling determined by media queries.
CHSBuffalo_iPhone_desktop CHSBuffalo_Nexus7_desktop
The CHSBuffalo.org site as seen on an iPhone and on a Nexus 7 after clicking “View desktop layout” (with the zoom as the user would initially see it). The link to return to the mobile layout is at the top, though not as obvious as it could be.
CHSBuffalo_iPhone_desktop_oops
This is what the user on an iPhone sees as soon as the desktop view loads—note the link to return to the mobile view is nowhere to be found. We did a poor job there and will have to fix it. Don’t make the same mistake if you try this.

Related

SEO Isn’t Just Google

This post originally appeared on my blog.

Back in October I had the pleasure of speaking at Buffalo’s first WordCamp for WordPress users. Before my presentation I made it a point to sit in on the other sessions that were in the same track as mine.

When discussing SEO, all the sessions I saw mentioned only Google. The Google logo appeared throughout, Google’s PageRank was discussed, Google search result screen captures were used, and so on.

The presenters for an SEO-specific session even went so far as to embed a video of Matt Cutts (from Google) in their presentation and declare that Matt Cutts stated that WordPress is the best platform for SEO.

For context, Matt Cutts appeared at a WordCamp in May, 2009 to discuss his search engine (Google) for an audience using a particular platform (WordPress). Matt even said, WordPress automatically solves a ton of SEO issues. Instead of doing it yourself, you selected WordPress (at about 3:15 in the video). He’s pitching his product to a particular audience to validate their technical decision (he’s just saying they don’t need to manually code these tweaks).

If while watching that video you heard Matt Cutts declare that WordPress is the best platform for SEO, then you are engaging in selection bias.

This same selection bias is also happening when developers work so hard to target Google and not any other search engines. If you convince yourself that Google is the only search engine because you don’t see other search engines in your logs, then perhaps you are the reason you don’t see those other search engines.

To provide context, this table shows the ratio of searches performed by different search engines in August 2012 in the United States. These are from comScore’s August 2012 U.S. Search Engine Rankings report.

Google Sites 66.4%
Microsoft Sites 15.9%
Yahoo! Sites 12.8%
Ask Network 3.2%
AOL, Inc. 1.7%

It’s easy to dismiss 16% when you don’t know how many searches that translates to.

More than 17 billion searches were performed in August 2012. Google ranked at the top (as expected) with 11.3 billion, followed by Microsoft sites (Bing) at 2.7 billion. The breakdown of individual searches per engine follows:

Google Sites 11,317,000,000
Microsoft Sites 2,710,000,000
Yahoo! Sites 2,177,000,000
Ask Network 550,000,000
AOL, Inc. 292,000,000

To put this another way, for every four (ok, just over) searches using Google, there is another search done in Bing. For every five searches using Google, there is another one done using Yahoo.

If your logs don’t reflect those ratios in search engines feeding your site, then you need to consider if you are focusing too hard on Google to the detriment of other search engines.

Now let’s take this out of the United States.

Considering Bing’s partnership with the Chinese search engine Baidu, contrasted with Google’s battles with the Chinese government, it might be a matter of time before Bing tops Google for Asian searches. Given the size of the Asian market (over half a billion users), if you do any business there it might warrant paying attention to both Baidu and Bing.

Related