Matt Brundage

Archive for the 'technology' category

Wednesday, 30 December 2015

Web developer tools

Firefox Developer ToolsThe following link dump represents the web developer tools that I use most frequently, both at my day job and for freelance projects.

Editors and regular expressions

Version control and diffing

FTP and database clients

Documentation and web apps

Browsers

Browser tools and plugins

Graphics programs

Wednesday, 11 February 2015

Mobile strategy: two opposing philosophies

I wrote this piece last summer, as part of a lively discussion I was having with colleagues regarding the future mobile strategy for FAA.gov. While some of my research and positions are pertinent only to FAA, I have found that most of it can be generalizable to the wider web development community.


We have to be careful when we talk about designing for context vs. having a device-agnostic approach. These two philosophies are opposing. Allow me to explain.

Smartphone usage trends

As of spring 2013, well over half of all American adults are cell phone internet users. Among those cell internet users, 34% use their phone as their primary or exclusive means of going online. This is an increase from 31% in 2012, and from 25% in 2011. In other words, the proportion of those who use their cell phones exclusively to access the internet is trending upward and has been a significant percentage for several years.

Cell-mostly internet users by household income.
Full report: Percentage of cell phone internet users who use their phones exclusively or mostly to go online

Three market trends indicate the rise of small-screen (“mobile”) browsing as a normal, mainstream means of accessing the internet:

  1. cell phone (smartphone) adoption percentage
  2. cell phone internet use percentage, and
  3. cell phone primary or exclusive internet use percentage.

All three of these percentages are steadily trending upward year-over-year.

What does all of this mean?

For a growing proportion of the population, there is no such thing as “device context” or “task context.” (two sides of the same coin) Many people aren’t doing different tasks on different devices because they use only one device primarily or exclusively. And regardless of how many devices users have, they expect content to be available and usable to them on the device that they are currently on.

What some call their “Mobile Strategy” should simply be called their “Strategy.” It should focus on getting all of their content accessible and usable on as many screen resolutions as possible. If a particular piece of content is relevant on a desktop or laptop, then it’s relevant on a “mobile” device. This approach — this device-agnostic philosophy — is echoed throughout the president’s Digital Government Strategy, published in 2012. (Press release) (Device-agnostic means that a service is developed to work regardless of the user’s device, e.g. a website that works whether viewed on a desktop computer, laptop, smartphone, media tablet or e-reader.)

“Americans deserve a government that works for them anytime, anywhere, and on any device.”

President Barack Obama

FAA.gov, mobile screenshotWhile developing FAA.gov, I laid the foundation of our device-agnostic approach. With responsive design (CSS rules), I endeavored to make FAA’s pages look at the very least acceptable and readable at any screen resolution. But our work is in no way finished. We can further optimize (both template-level and page-specific) to ensure that pages look and behave their best at smaller resolutions.

Recommendation

If you haven’t already guessed, my recommendation remains that we continue to employ responsive design (CSS rules) on FAA.gov — to build on the foundation that I have already laid — to optimize all of our content for whatever device a visitor will choose to use.

Our other two options involve creating and maintaining two websites. Both of these options involve making assumptions about our users, based solely on their device type or screen resolution.

Assumptions

  • The assumption that there is a clear distinction between “desktop tasks” and “mobile” tasks. This distinction was relevant in the early days of mobile internet — when responsive design had yet to mature and when smartphones were not as capable as they are now. But user expectations and usage patterns have changed and continue to change, as outlined in the section above. People expect websites to work on their device, and FAA must deliver on those expectations.
  • The assumption that we can divine what content our visitors will want to see on their mobile device vs. what content those visitors won’t want to see, or won’t need to see. Content curation is based on this faulty assumption. The whole concept of content curation ignores the reality that smartphone and tablet users are already exploring faa.gov in ever-increasing numbers — to the tune of 24% of all visits, and over 35% on weekends! (July 2014) I can assure you that these ½ to ⅓ of our site visitors are not hopelessly lost and desperately looking for our pared-down, insultingly simplified mobile site.
  • The assumption that a mobile user fits a single, outdated set of characteristics. Can FAA determine the user’s mindset, their “on-the-go” attitude, their location relative to an available desktop or laptop computer, their motivation or intent to consume content, or their information needs based solely on the device that they’re using?

Other problems with a two-site approach

  • Forcing the user to redirect to a separate mobile site flies in the face of the user experience credo that “the user is always in control.” Period. Redirecting the user when that corresponding page does not exist on the mobile site is the worst possible course of action to take, as the content would be inaccessible on that device.
  • The definition of “mobile” is changing, and there is less of a distinction. For instance, is a Dell Venue 11 Pro considered a mobile device, since it is sold as a tablet? Or is it really a laptop, since it comes with an optional keyboard and has the same screen size as an 11″ Apple MacBook Pro? Or is the 11″ MacBook Pro now considered a mobile device? For that matter, is any laptop considered a mobile device when it is used on a plane, train, or automobile?
  • A two-site approach will increase maintenance — perhaps not by a factor of two, but by a significant amount. Maintaining two “separate but equal” websites will introduce programming inconsistencies — when one feature is correct on one site, but incorrect or different on the other. And certain features may be intentionally different across the two sites, but that fact may not be entirely obvious. Over time, it will become exceedingly difficult to determine the “correctness” or current relevance of a given block of code.

In summary

I recommend that we continue to maintain a device-agnostic approach to web development, and to further optimize our content for smaller screens (“mobile”, if you will). Refining and simplifying our content can have a dramatic, positive effect on the user experience — but not just on mobile devices but on the desktop as well.

Works cited and consulted

Friday, 28 February 2014

FAAcelift

screenshot of www.faa.gov

I unveiled a new site earlier this week for the Federal Aviation Administration. That is, it feels like an entirely new site because the changes are so sweeping and comprehensive. I’ve been referring to the project as a FAAcelift (get it?), but the scope of the project is much more than just a fresh coat of CSS.

A huge thanks to my coworkers and the FAA Office of Communications for their support and encouragement, and for entrusting me with this opportunity. Improving FAA’s public-facing website was pure bliss, and I’m fortunate that I was given the time — and autonomy — to commit the following changes to the template. When I wake up in the morning, I am always excited about getting to work. In a way, I feel privileged. The constant feeling of fulfillment never goes away.

Notable changes/improvements

Design/layout

  • Responsive layout is informed by design breakpoints — not necessarily by device breakpoints. In other words, the responsive layout aspires to be device-agnostic.
  • The appearance of pre-content page messages has been standardized. A “debugging” page message appears when the development tier is in debug mode. The News CMS mini-toolbar is styled in the same manner. Pre-content page messages are dismissible.
  • FAA and DOT seals are approximately 25% larger than before. The words on the seals are closer to being legible.
  • Text is, on average, 15% larger than before and is closer to browser default font sizes.
  • The page tools box appears to reside in the right sidebar (to the right of the page title), but it remains visible even if the right sidebar is hidden.
  • Text in ordered and unordered list items start at the same horizontal place on a given line. Intra-page anchor links (e.g. class="anchorDown") are similarly aligned.
  • Vertical navigation supports additional levels of indentation. Example of prolific nesting
  • Blank space between paragraphs and lists has increased to be equal to the default line height of its corresponding text. This affords consistent vertical flows of text.
  • Message boxes look 43% less ugly. Also, they’re dismissible. Message box icons are from a single set: Chalkwork. Icon size has increased proportionally to the text size increase.
  • Footer: Readers and Viewers icons better match current software branding used by Adobe and Microsoft. Icon size has increased proportionally to the text size increase.
  • ForeSee modal dialog styles are closer to template styles. ForeSee’s FAA seal image, in particular, is more accurate.
  • CSS filter effects progressive enhancement: desaturation of the page content when it loses “visual focus” to certain page elements with higher z-indexes:
    • Colorbox modal dialog
    • ForeSee modal dialog
    • jQuery UI modal dialog
  • A larger percentage of CSS rules use relative (em) unit values instead of absolute (px) unit values. With relative unit values, page element properties such as margin, padding, and width will scale relative to the user’s default font size (set in the browser) or font scale factor (set in the operating system).
  • Font sizes (as calculated by the browser in pixels) are whole numbers when possible in an attempt to overcome differences (subtle and not-so-subtle) in font rendering and rounding among various browsers. See:

screenshot of Air Traffic page

JavaScript

  • A class of “noJS” or “js” is applied to the <html> tag. The correct class is determined (via JavaScript) before any CSS is loaded, avoiding potential rendering engine repaints/reflows, and thus, an appearance of latency.
  • Upgraded to the latest stable releases of jQuery, jQuery Migrate, and jQuery UI.
  • Upgraded template-level plugins Colorbox, bxSlider, and a forked version of beautyTips which I then had to fork again.
  • When feasible, the site loads non-minified versions of JavaScript libraries and plugins on the development tier and minified versions of the same on the production tier. This makes it easier to debug JavaScript errors/warnings on the development tier.

Markup

  • DTD changed to HTML5.
  • Template markup is valid according to the HTML5 DTD.
  • Removed <meta> “keywords” from template output.

Browser support

  • IE6 support has been dropped, as its marketshare has fallen below one-tenth of 1%. No testing occurs in this browser. For what it’s worth, IE6 loads the lone CSS “fixes” file, intended mostly for IE8.
  • IE7 support has been dropped, as its marketshare has fallen below 2/3 of 1%. Cursory testing may still occur in this browser, although there is no guarantee that the template structure will hold up reasonably well. For what it’s worth, IE7 loads the lone CSS “fixes” file, intended mostly for IE8.
  • JS-/canvas-based rounded corners has been dropped. It was previously implemented in IE7 and IE8.

User experience/accessibility

See section below for how I aspire to meet Web Content Accessibility Guidelines: WCAG 2.0

  • “Skip to page content” link becomes visible on keyboard-activated focus.
  • Keyboard-accessible (focusable) dropdown menus (horizontal navigation and “FAA for You”)
  • Contrast between backgrounds and text complies with WCAG 2.0, Level AAA. (see section, below)
  • Page Last Modified date above the footer is in the long-date format to resolve ambiguities surrounding the two-digit representations of the day, month and year, and the ordering of said numerals. If a short-date format is recommended for aesthetics, it should conform to ISO 8601.
  • Page Last Modified time has been converted from the 24-hour clock (military time) to the 12-hour clock (AM/PM) for the sake of plain language and understandability. Additionally, the time zone indicator reports standard or daylight saving time as appropriate.
  • All heading levels (<h2>, <h3>, etc.) are properly differentiated by font size, line height, and margins. They are closer to browser defaults.
  • WAI-ARIA Landmark attributes adorn key sections.
  • jQuery UI Tabs follow WAI-ARIA best practices.
  • On hashchange events (such as “Skip to page content” or other intra-page anchor links), browser focus state now reliably mirrors visual focus across all browsers.
  • Breadcrumb delimiter is no longer a right-pointing double-angle quotation mark, but a solid arrow. The arrow glyph is wrapped with aria-hidden=”true” to prevent screen readers from reading this design element.
  • The legacy mode message (displayed in the pre-content area on the development tier) now reports all conditions that put the page into legacy mode. The messages are less cryptic and more developer-friendly.
  • If the jQuery UI autocomplete widget in the site search field is left open and no item is selected, hovering over neighboring drop-down menus (“FAA For You…” or the horizontal nav) closes the autocomplete widget. This is done for the sake of minimizing z-index collisions.
  • Sticky horizontal navigation.

screenshot of News page

Web Content Accessibility Guidelines: WCAG 2.0

FAAcelift aspires to meet WCAG 2.0 (Level AAA), particularly in the visual presentation of text.

  • 1.4.1: Use of color: The template is now fully compliant. In the previous version of the template, the visited link color was the same as the hovered link color. Hovering over visited links resulted in no visual change. This has been remedied in the latest template revision. Additionally, developers are encouraged to not use color as the only visual means of conveying information.
  • 1.4.2: Audio control: Not applicable to the template. No known site sections or pages play audio on page load.
  • 1.4.3: Contrast ratios (minimum): The template meets and exceeds this requirement. See full explanation in section 1.4.6 (below).
  • 1.4.4: Resize text: Compliant in all page layout scenarios. See also 1.4.8.
  • 1.4.5: Images of text: The template is compliant. See also section 1.4.9 (below).
  • 1.4.6: Contrast ratios (enhanced): (Level AAA) “The visual presentation of text and images of text has a contrast ratio of at least 7:1” with limited exceptions.

    Already compliant

    • Page title
    • Body copy
    • Horizontal navigation
    • Vertical navigation
    • New design of footer (first row with blue background)

    Made compliant

    • Page subtitle: increased from 3.9:1 to 9.7:1
    • Breadcrumb links: increased from 2.6:1 to 7.1:1 (not hovered) and 10.6:1 (hovered)
    • Links (visited and unvisited): increased from 6.2:1 to 7.1:1
    • Hovered links (visited and unvisited): increased from 3.2:1 to 10.6:1
    • Input and textarea placeholder text: increased from 4.6:1 to 7.1. The color was deferring to the browser’s default placeholder color. In Firefox 25, for example, the default placeholder color passes WCAG AA but fails WCAG AAA.

    Improved, but not compliant

    • “FAA for You…” dropdown in the header: increased from 3.1:1 to 4.5:1. This complies with Level AA, but not Level AAA.
  • 1.4.7: Low or No Background Audio: (Level AAA) Not applicable to the template.
  • 1.4.8: Visual Presentation: (Level AAA)
    • First requirement: Not compliant. We do not provide a mechanism for the user to change the background or foreground colors.
    • Second requirement: Made compliant. In the default page layout (with both sidebars present), the average number of characters per line has been reduced from about 95 in template v. 3 to about 80 in template v. 4. The upper limit recommended by WCAG 2.0 is 80 characters.
    • Third requirement: Partially compliant. Pro: we do not provide a CSS rule in the template to justify paragraph text. Con: we do not provide a mechanism in the template to un-justify text affected by custom CSS.
    • Fourth requirement: Partially compliant. Text line height has increased slightly from 145% of text size to 150% to meet this requirement. Spacing between paragraphs has increased from 85% of line height to 100% of line height, but this spacing is not large enough to meet this requirement.
    • Fifth requirement: Compliant in most scenarios when the template is in the default page layout (with both sidebars present). Newer browsers that support media queries are fully compliant, as the responsive layout ensures that the user will never have to scroll horizontally to read overflowing text.

    Key advisory techniques for 1.4.8:

    • Providing large fonts by default. “Large” is a relative term, but the base font size of the page (while still less than the browser default) is about 15% larger than before.
    • Avoiding chunks of italic text. The default style for <blockquote< displays text in the normal font style instead of in italics (or oblique).
    • Making links visually distinct. Breadcrumb links conform to the same link color scheme as the other links in the main content area.
  • 1.4.9: Images of text (No exception): The template is fully compliant, but individual pages may not be fully compliant. Our “Visit FAA Mobile” ad in the footer violated this rule, but the image has been reworked as text styled with CSS. Right sidebar ads and homepage ads frequently violate this requirement. Merely providing alt text on images ensures Section 508 compliance but does not necessarily ensure compliance with this requirement.

screenshot of Michael Huerta biography page

Sunday, 29 April 2012

Accelerate

My dearly beloved website clients: over time, your sites are loading faster and faster1 — and there’s nothing you can do about it. Just another fringe benefit of having me as your web developer.

Homepage speeds (all data points), Oct 2010 to Apr 2012

Google page speeds

Homepage speeds (averaged), Oct 2010 to Apr 2012

Google page speeds

Coincidentally, our happy little graph here appears to evoke a logarithmic trend.


1: As measured with Google’s Page Speed extension for Firefox, which rates a page’s loading speed based on these criteria.

Sunday, 12 February 2012

Coding on the shoulders of giants

Isaac Newton I write and edit code for a living. Because I enjoy what I do, I have this insatiable thirst for knowledge and self-improvement: “How can I write this function in fewer lines?” “How can I make this CSS bullet-proof?” “How can I make this page load faster?” Not for a second do I purport that I come up with solutions solely on my own. I have this small army of disparate web developers at my disposal — a collection of developers that, for all intents and purposes, functions as an extension of my own brain.

Kroc Camen

Where do I begin? Kroc was one of the first to fully embrace the still-emerging HTML5 specification, his Video for Everybody! just works, and his approach to writing CSS and .htaccess is refreshing and enlightening.

Dean Edwards

After Microsoft released IE6 in 2001, the company essentially stopped all browser development for five years. However, during that time, a man in the UK was busy writing a script that, when run in IE6, corrected many of the rendering bugs inherent in that browser and even added support for certain CSS rules that IE7 would eventually support. If you’re curious or pedantic enough to parse through Dean’s code, you will soon realize that he is insane.

Joe Hewitt and other Firebug contributors

When I write code, I usually have the Firebug pane open constantly. I wouldn’t be as efficient or effective at what I do without Firebug. Proper respects to Joe Hewitt and other contributors to Firebug: some anonymous, some not well known.

Paul Irish

I just know it: news will soon surface that the man known as Paul Irish is actually several Google employees working collaboratively under the same alias. The man seems to have his paws in everything. Deep breath: HTML5 Boilerplate. Move the Web Forward. Modernizr. CSS3 Please. HTML5 Please. W3Fools. HTML5 Readiness. Front-end Code Standards & Best Practices.

And it doesn’t hurt that he’s deeply knowledgeable, funny, and — might I add — handsome.

Steven Levithan

In the short 15 months that I worked alongside Steve, I learned more about web development best practices, regular expressions, and JavaScript than I had in all years prior. Many of my Oh My God, it’s full of stars! moments are because of Steve.

Jens Meiert

Jens is the expert and I enjoy reading his posts about code maintenance. He’s also a bit of a Renaissance man. I get deeply jealous if I think about it too much.

Eric Meyer

Eric, for a while, was the go-to guy for all things CSS. He wrote CSS: the Definitive Guide, for Pete’s sake! Eric is a dog who has had his day, but he can still churn out thought-provoking posts.

Ben Nadel

It seems that whenever I have a ColdFusion problem that I need to solve, my search ends when a Ben Nadel blogpost succinctly tells me exactly what I need to know. That’s not at all an oversimplification.

Chris Pederick

Chris, British-born but now residing in California, is the author of the invaluable Firefox extension Web Developer. Every time the extension has a major update, I send Chris a thank you gift from his Amazon wishlist. Along with Firebug, Web Developer is indispensable to developers — I couldn’t imagine the browser without it.

John Resig

The creator of jQuery, Resig made JavaScript interesting again and is arguably the man most responsible for its resurgence.

Steven Souders

Steve, an former employee of Yahoo (now with Google), is the one who got me interested in web page speed optimization. However, in a strange twist of fate, I never installed his YSlow browser plugin, but instead opted for a similar plugin, Google PageSpeed. But still, Souders wrote the book on front-end page performance.

Friday, 12 August 2011

Stale cache mitigation with query string automation!

So you’ve been a good little developer and define expires headers for page assets such as CSS, JS, and images. Let’s say you specify that the caching of CSS files expires one week after initial access. But if you modify a CSS file, your visitors could potentially load stale cache for up to one week.

One solution is to rename the file. For example, main.css would become main.2011-08-12.css This will effectively create a unique cached version of the CSS file. But this solution could get cumbersome with frequent updates, or with disparate references to the asset. A second solution is to add a query string to any references to the asset, for instance, main.css?2011-08-12. Proxy servers will treat this reference as a dynamic file and will likely not cache it. Browsers will treat this as if it were a unique file and re-cache it.

A refinement to our second solution is to automatically add a query string to references to the asset, but only when it’s necessary to do so. The following function, assetQueryString(), does just that. It takes two arguments:

  1. The reference to the page asset
  2. (optional) Maximum file age (in days) in which the query string will be appended

The function determines the file modification date and determines whether or not to append a query string, and for how long. The value of the query string, conveniently, is the last modification date of the file. Or, more accurately, it’s the number of days between the Unix Epoch and the last modification date.

PHP

function assetQueryString ($filePath, $maxAge = 7) {
	$today = intval(strtotime(date("Y-m-d")) / 86400);
	$fileDate = intval(strtotime(date("Y-m-d", filemtime($_SERVER['DOCUMENT_ROOT'].$filePath))) / 86400);
	$days = $today - $fileDate;

	if ($days <= $maxAge) {
		$filePath .= "?".$fileDate;
	}
	echo $filePath;
}

// usage:
<link rel="stylesheet" href="<?php assetQueryString("/templates/style/main.css"); ?>">

ColdFusion

<cffunction name="assetQueryString" returntype="string" output="FALSE">
	<cfargument name="filePath" type="string" required="TRUE" />
	<cfargument name="maxAge" type="numeric" default="7" required="FALSE" />

	<cfparam name="Variables.unixFileDate" default="0" />
	<cfset Variables.expandedFilePath = expandPath(filePath) />
	<cfset Variables.unixEpoch = CreateDate(1970,1,1) />

	<cfif fileExists(Variables.expandedFilePath)>
		<!--- determine last modified date --->
		<cfset Variables.unixFileDate = DateDiff("d", Variables.unixEpoch, getFileInfo(Variables.expandedFilePath).lastmodified) />

		<!--- determine today's date --->
		<cfset Variables.unixTodaysDate = DateDiff("d", Variables.unixEpoch, Now()) />

		<!--- append unique query string to file path if the file was recently modified --->
		<cfif Variables.unixTodaysDate - Variables.unixFileDate LTE maxAge>
			<cfset filepath &= "?" & Variables.unixFileDate />
		</cfif>
	</cfif>

	<cfreturn filepath />
</cffunction>

<!--- usage: --->
<link rel="stylesheet" href="<cfoutput>#assetQueryString("/templates/style/main.css")#</cfoutput>">
Wednesday, 29 June 2011

Chesapeake ADHD Center of Maryland

Chesapeake ADHD Center of MarylandChesapeake ADHD Center of Maryland is my most recent client: an ADHD psychotherapy practice in Silver Spring, MD. As was the case with Ann Dolin’s site, the original codebase was inherited. Apparently, the website was originally created in an old version of Dreamweaver — and all of its WYSIWYG glory. Sigh. With over 150 pages (and file names such as cooltext449991252_001.png) the codebase had become an unmaintainable morass of untemplated spaghetti, with nary a single redeemable line of code. The site was razed to the ground and reborn in the ashes.

Chesapeake ADHD has undergone more of a reorganization than a redesign; in fact, I view my design as more of an improvement upon the original — the essential design elements can still be seen.

When I inherited the project, the site’s Page Speed score was a somewhat respectable 78. Now? Try 96. The law of diminishing returns should kick in soon.

Wednesday, 11 May 2011

Ann Dolin

Ann Dolin You may remember a site refresh I did for Ann Dolin last summer: her own tutoring business, Educational Connections. This spring finds her personal site, anndolin.com, getting a subtle makeover and a substantial speed boost.

Before the refresh, the site’s Page Speed score hovered in the high eighties. Not bad, by any measure. The original codebase was inherited, and I had done all I could to increase page load times (save for completely redoing the site, which was using a WordPress template of questionable character). The stars realigned with this recent redesign, and her Page Speed score is positively screaming with a score of 97.

Thursday, 3 March 2011

CSS resetting with the negation pseudo-class

My derivation of Eric Meyer’s latest Reset CSS, but for current browsers:

:not(button):not(input):not(optgroup):not(option):not(select):not(textarea) {margin:0; padding:0; border:0; font-size:100%; font:inherit; vertical-align:baseline;}

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block;}

body {line-height:1;}

ol, ul {list-style:none;}

blockquote, q {quotes:none;}
blockquote:before, blockquote:after, q:before, q:after {content:''; content:none;}

table {border-collapse:collapse; border-spacing:0;}

Meyer’s first rule — in which we reset margins, padding, borders, and fonts — quickly becomes unwieldy as we explicitly list out all elements, save for a few typically used in forms. Instead, the negation pseudo-class provides a succinct way of selecting these elements. Internet Explorer 8 and below will still need to be fed the more verbose rule, however.

Update

Ah. It turns out I spoke too soon. The negation pseudo class carries a higher specificity than a simple element selector. So in practice, my method would be at least cumbersome. It was a nice mind exercise while it lasted…