Recently I was digging around in the Safari Developer Library when I came across one more reason (as if there weren’t enough) to write Unobtrusive JavaScript. In this case, Safari on iOS (all devices) disables preload="" and autoplay="", in case the user may be in a position where they are on a horrid network and are being charged per data unit. So no data is actually loaded until initated by the user; this also implies that the play() and the load()methods are inactive until user initiated playback, unless the play() or load()method is triggered via user action. So in laymens terms, user-initiated Play buttons work, however the onload="play()"eventdoes not. Safari Developer Library provided the solution below:
This works as-is, however the event handler is still mixed in with the markup thus violating the Seven Rules of Unobtrusive JavaScript, specifically number five:
5. Understand Events (Event handling to initiate change)
Event handling is the next step to truly Unobtrusive JavaScript…understand that Event Handling is true separation.
So I rewrote the Safari solution using Web Standards and separated behavior (JavaScript) from structure (html) using Unobtrusive JavaScript. I don’t have any video files available for the demo so I swapped audio in its place, as well as added some updated (read: “proper”) markup, but the principle(s) are not lost. The demo is a media control that will play a media file after user-initiated contact with the play button. You can view the demo here or view the code and markup below:
// javascript
window.onload = function() {
// Get the play button and append the audio play method to on click
var audio = document.getElementById("audiosrc");
var play = document.getElementById('play');
play.addEventListener('click', function(){
audio.play(); }, false);
}
<!-- html -->
<button type="button" id="play">
<audio id="audiosrc">
<source src="http://dev.bowdenweb.com/a/m/a/clipping_link-finds-a-secret-13908.ogg" />
<source src="http://dev.bowdenweb.com/a/m/a/clipping_link-finds-a-secret-13908.mp3" />
<source src="http://dev.bowdenweb.com/a/m/a/clipping_link-finds-a-secret-13908.wav" />
</audio>
</button>
Quick follow up to my last post regarding semantic glossaries: dictionary.com uses audio examples to express correct pronunciation. While I don’t think this practice is necessary for most glossaries, I can’t see how it would hurt any of them. If anything, you’d simply be adding accessibility coverage, which should always be a goal for a site, even if it’s in the long-run. Plus, in a very miniscule way, you’re adding more content, so it seemingly should help with seo. So, simple enough, right? Just add audio into the rubyelement and we’re good, right? Not so fast, I quickly found out that cross-browser styling of audio isn’t very well documented, even though I’m positive it’s doable.
For starters, I grabbed the speaker icon via the Noun Project to show users that there is audio content to hear. It is an svg and I had planned on adding cross-browser compatibility for it, however considering the audio roadblock I hit, I decided to just publish this now and I’ll work on that once I get it to play in all browsers. Then I grabbed an audio file, I don’t have a microphone, so I couldn’t create the actual word pronunciation which is lame, but I figured this is just for demonstration purposes only. I used media.io to generate .ogg and .wav files for (what I thought was) cross-browser compatibility. And I thought I was good to go, but clearly this was not the case.
Fallback via button
Once I ran into the audio styling roadblock, I lamely wrapped it up into a buttonelement. I thought for sure this would be the silver bullet. Negative, Ghost Rider. I hooked the button into the audioelement‘s onclickevent handler and provided 3 separate audio formats (.mp3 for Webkit, .ogg for Gecko and .wav for Presto) via sourceelement. Here’s the markup and JavaScript:
window.onload = function() {
var audio = document.getElementById("audiosrc");
var play = document.getElementById("play");
play.addEventListener('click', function(){
audio.play();
}, false);
}
Note: this doesn’t work in Opera 11.5, which is baffling to me. From what I can understand, Opera supports .ogg, but once I saw it not working, I actually created the .wav file specifically for Opera, and still no bueno. After struggling with this for a few hours, I’ve given up at the moment, so I’m quite positive that this won’t work in ie without testing. I’ll be sure to follow up on this as soon as I find more out and/or find a more elegant cross-browser solution. You can check out the Accessible Semantic Glossary demo here.
Picking up from Font Linking Separate Styles for b and i, I wanted to add examples of using Small Caps fonts with @font-face correctly. I did get it working cross-browser in Firefox 5, Opera 11.5, Chrome 14.0.8, Safari 5.0.5, and ie9, but not without jumping through some hoops first.
To start, I needed to acquire some fonts that have a Small Caps type; I found three at exljbris Font Foundry, which I used for this demo, Delicious, Fontin, and Fontin Sans. Then I simply put each into a demonstration page, declaring the Small Caps font in the @font-face rule and adding the font-variant style, like so:
Initially, I had the fonts declared starting with the Regular version, continuing through any other versions (Bold, Italic, etc.) and ending with the Small Caps font. This failed in Firefox 5 however, all of the fonts would render as Small Caps. After doing a little research, I came across this @font-face Implementation Test, which proved quite useful. The tests recommend placing the font-variant:small-caps rule first because Firefox 3.6 and Opera 10.5 both will overwrite regular text if not. The implementation test is a bit out dated here, Opera 11.5 handles declaring font-variant declarations correctly, and also doesn't cover ie, but that's not to take away from it, I did find my solution here.
So for the second test run, I declared font-variant:small-caps first, then declared all the rest of the fonts per family, and lastly declared the Regular font. This proved fruitful cross-browser until I got to ie9, which rendered all the text in Small Caps, just as Firefox had until I flipped the font ordering. So I quickly reversed the changes I had just made and sure enough, they rendered correctly in ie.
Knowing that we can use one method to work in every browser except for ie, and being used similar situations (as all web developers are), my first inclination was conditional comments. I did use them for the final solution, however I did a tad bit more. If you take a gander at the declarations below:
The first two lines target ie, while the last 3 cover the rest of the browsers; I didn't want to serve up ie styles to non-ie browsers nor did I want to serve up any more extra (than already needed) for ie. So here's what I did: I took out the ie specific declarations and put them into their own stylesheet, with the font-variant:small-caps declared last, then placed that stylesheet in conditional comments. Here's the new version of the declarations for real browsers:
Note: While this does work, I cannot say 100% if this is the best way to go about serving up Small Caps correctly via @font-face. Actually I'm positive that it isn't, but it is a solution. Until I find more information to shed some light on this situation and browsers provide better support, I am stuck at this point. You can view the demonstrations here: Delicious Font Demo, Fontin Font Demo, and Fontin Sans Font Demo.
The css3 specification says that font-family names must be quoted if they contain the keyword values of inherit, default, serif, sans-serif, monospace, fantasy and/or cursive. By simply applying quotes to every font family name besides the defaults, you’re being proactive and ensuring that the proper font-family is applied.
Sounds simple enough, but why should you care? If you’re in a large organization, setting this simple standard can go along way, especially when there are lots of hands touching code. Moreover, the disconnect between type designers and the css specification is quite evident when using font linking. I noticed this trend while searching for font families with multiple weights; many fonts that should be in the same font-family under css rules are actually in their own family as defined by the artist. Below are screenshots of a few popular fonts that have the keyword value serif in their name and could cause problems if not quoted.
DejaVu Serif, Droid Serif and Afta Serif, Popular fonts that have css Keyword Values in their Names.
Note: I’m not attacking type designers here, I’m merely pointing out the obvious. Regardless of who is to blame, if you just start quoting your font-family values, you’ll never have to worry about it.
text-rendering is actually an svg property that provides text optimization information to the rendering engine while rendering text. Gecko and WebKit browsers have adopted text-rendering and allow it to be applied to html/xml content on Windows and Linux. Firefox in Windows automatically applies text-rendering:optimizeLegibility for text greater than 20px, Firefox for Mac has it always applied by default and Safari has it off by default for performance reasons. When set to text-rendering:optimizeLegibility enables ligatures in text that is 20px or smaller and also turns on kerning.
Style Declaration
Style Definition
text-rendering:auto
Browsers will make educated guesses about when to optimize for speed, legibility and geometric precision when drawing the text.
text-rendering:optimizeSpeed
Browser emphasizes rendering speed over legibility and geometric precision when drawing text; disables kerning and ligatures. Has no effect on Gecko 2.0 (Firefox 4)
text-rendering:optimizeLegibility
Browser emphasizes legibility over rendering speed and geometric precision, enabling kerning and optional ligatures
text-rendering:geometricPrecision
Browser emphasizes geometric precision over rendering speed and legibility; makes text that use non-linear scaling font aspects look good. Kerning is one font aspect that doesn’t scale linearly. Scaling text in svg can result in stair-step scaling, however when fully supported, text-rendering:geometricPrecision lets text scale fluidly. WebKit supports text-rendering:geometricPrecision but Gecko treats it the same as text-rendering:optimizeLegibility
Note: using text-rendering:optimizeLegibility is not a silver bullet and it does come with certain cross-browser drawbacks:
text-rendering:optimizeLegibility, when used in unison with font-variant:small-caps causes small-capsnot to render in Chromium
text-rendering:optimizeLegibility causes text to disappear completely in webOS
text-rendering:optimizeLegibility negatively impacts page load; Use Caution, especially on mobile devices.
text-rendering:optimizeLegibility, when used in conjunction with margin, padding, border-width, or outline-widthproperties which are set using ex measurement type in Safari 5 causes the browser to crash.
Optimization is usually an afterthought or an after process in development; it usually only begins once a product is built, and only then if the site or application shows visible signs of needed optimization. I am vehemently against optimizing at the last minute, it should be part of your workflow(s), integrated into your development, on varying levels. One area of optimization that is critical for performance and seo is compacting and minimizing file sizes. Focusing on image file sizes in particular, when left unchecked, they can seriously impede a site’s download time, which affects that sites rankings in serps, amongst other things. There are a slew of methods to achieve this today (I use pngcrush), but as far as I know they are all focused on the images once they are production ready. While this standard practice is not going anywhere, check out these methods to be proactive with your image optimization before they get to production. These are only for Photoshop, however it is my image editor of choice when not developing in-browser.
Gamma Values
Gamma Value of a computer monitor affects how light or dark an image is in a browser. Windows use gamma of 2.2, Mac os use 1.8, so images look darker on Windows typically. In Photoshop, we can preview how images will look on different os with different gamma values, and make adjustments to compensate. Gamma Values can be altered to increase cross-platform compatibility, to aid in the ux, and also for simple design aesthetics.
After selecting Save for Web & Devices, choose one of the options in the dialog box Preview pop-up menu:
Monitor Color: makes no adjustments (default)
Macintosh: displays adjustments based on default Macintosh gamma.
Windows: displays adjustments based on default Windows gamma.
Use Document Profile: Adjusts gamma to match any attached document color profile in a color-managed document.
Photoshop Image Processor
The Photoshop Image Processor saves copies of a folder of images into jpeg format. The Photoshop Image Processor can be utilized for resizing and converting images’ color profile(s) to Web Standard srgb.
Save for Web & Devices Option
You can select the Save for Web & Devices Option under the File Menu, the same place where all of the Save options are located in Photoshop. Selecting this option shows further options for Image Optimization and previewing said images. Atop this dialog box are four tabs, original, optimized: displays image with current optimization settings applied, 2-Up: displays two versions of the image, and 4-up which displays four versions of the image.
Select preset optimization setting from the Preset Menu, or set individual options; available options change depending on the selected file format. In 4up Mode, if you choose Repopulate Views from the Optimize Menu, it automatically generates lower-quality versions of your image after changing the optimization settings.
You can change the optimization settings to your desired balance of image quality and file size; if using multiple slices, make sure you optimize all of them too. To insure that an optimized images colors are cross-browser compatible, make sure you convert any images with an embedded color profile other than srgb before you save for web. Convert to srgb option is default.
Optimize xmp Metadata
You can choose what xmp Metadata saves with your optimized file from the Metadata Menu. Metadata is only partially supported by gif/png formats and fully supported by jpeg. options:
Photoshop Image Optimization Metadata Optimization Menu Screenshot
None: no Metadata saved, smallest file size.
Coypright: Saves copyright notice, rights usage terms, copyright status, and copyright information url.
Copyright and Contact Info: Saves all copyright information, plus creator, creator job title, email(s), address, city, state/province, postal code, country, phone(s) and website(s).
All Except Camera Info: Saves all xmp Metadata except exif data, which holds camera settings and scene information.
All: saves all xmp Metadata.
Save your optimization settings as a named set and apply them to other images; they’ll appear in the Preset Menu.
Note: If you have an image with any embedded color profile other than srgb, convert the image’s colors to srgb before saving for the web.
You can preview optimized images in any browser that you have installed, simply click the browser icon at the bottom of the Save For Web & Devices dialog box. I had no browsers in the pop-up Menu, so I added some, for clarity’s sake. I selected Firefox and sure enough, an instance of Firefox fired up and displaying the image preview, as well as a caption listing the image’s file type, dimensions (px), size, compression specifications and any other settings it is using.
Photoshop Image Preview and Caption Screenshot in FirefoxPhotoshop Image Preview Browsers Menu Screenshot from the Save For Web Dialog
Compress an Image to a Specific Size
When saving for Web & Devices, select the tab with the desired display option, at the top of the dialog box. Then select Optimize To File Size from the Optimize Menu (right of the Preset Menu), enter the desired file size and select a Start With option. The Auto Select gif/jpeg Start With option automatically selects the optimal format, depending on the image’s content.
Saving Images for Email
Photoshop also allows us to save files for email, simply click the Optimized Tab in the Save For Web & Devices dialog box and select jpeg Low from the Preset Menu. Select the chainlink icon to the right of the dimension size boxes to retain image proportions and then enter 400 pixels into the width. Adobe recommends this size, however I don’t and neither do i recommend optimizing for email, at least for my purposes. I’m sure there are good reasons to it, I’m just not aware of any.
All of this information was found using this resources.
Of all the approaches to front-end development, the omission of IE has to draw my ire more than most. Entirely omitting a browser and all of its users from your development support cycle is a red flag that you do not know what you are doing. Furthermore, it leads me to believe that you do not care about Web Standards or webcomm as a whole.
I’ve heard many explanations (read excuses), such as:
IE6 is 10 years old
I develop for modern browsers
I’m on OSX/Linux
Our users shouldn’t use IE
I hate IE
I am not saying that everything has to look the same and/or be functional in IE6(+). However, casually dismissing developing for an archaic browser(s) is simply piss poor development practice.
Neglecting IE hurts your bottom line in a plethora of ways, some of which include:
Accessibility: by omitting IE and any other browser by default, you are automatically cutting out a certain percentage of users from ever using your site. You can say that no one uses IE6 and that may be mostly the case for home use, but there are countless organizations who still have IE6 tied to their enterprise applications (if you can call them that) and/or have IE6 mandated as the only browser available for use. Sounds ludicrous? Sure, but it’s still a reality. Do you know how much time people use the web at work to get stuff done? Of course you do, you do it daily, as do I. Now if you were tied to IE6, your awesome work/play productive days are over, because there are some things that you simply cannot access.
SEO: simply put, the more users you have, generally the more SEO you are going to achieve, be it organic, social, word-of-mouth, etc., the more traffic that you are generating the better off you are.
Usability: similar to Accessibility here; in short, if your site is not usable than you are neglecting integral aspects of UX and UI. Ignoring these will inevitably catch up to you, and having to redo anything violates the principle of DRY, to which I have found no good argument against.
Self-Improvement: the more versatile your skillset, the more marketable you are. Self-explanatory.
Supporting IE6 Gives Back
First off, I am no fan of IE nor do I like supporting it, but as a Standardista that holds webcomm above all else, I’ll enlighten you all to the glories that I have reaped from supporting IE:
Separation of Behaviors - placing precedence and importance in separating Structure, Presentation and Behavior, from which the most versatile and robust sites benefit from.
CSS and HTML - I am talking versions, properties, values, units of measure, implementations, elements, attributes, etc.. A nerdy bonus is that along the way you will find juicy nuggets of CSS and HTML history to explain why things are the way they are.
JavaScript - DOM versions, browser implementations, Graceful Degradation, DOM Scripting, Progressive Enhancement and Unobtrusive JavaScript.
Cross-Browser resources and solutions - These resources and solutions will enlighten you to the very brightest and bleeding-edge frontiers that are literally sculpting the web as we know it.
All of this intimate knowledge works together to shed light on even larger topics in web development including Separation of Behaviors, the Cascade, Optimization, Reflows, Repaints, Redraws, developing Mobile First and Responsive Development.
I would add that not everything must be functional, or look the same in every browser. I personally am anal retentive about those ideas, but I realize that in many cases this is simply not logical, applicable, or feasible. Besides who wants to spend time fixing bugs in IE when you can be playing with -webkit? On the same hand, once you become familiar with some of IE‘s quirks, fixing them becomes a breeze. I cannot tell you how many times I resolved IE bugs simply by recognizing the doubled-float margin bug or the peekaboo bug. A simple _display:inline for the doubled-float margin bug. _position:relative for the peekaboo bug.
Added bonus: tackling IE6 will solve many problems that also carry over to IE7. Also a new trend that has hit web development circles of late is a claim that IE9 is the new IE6. The reasoning behind this claim does have some validity. IE has a slew of quirks and bugs and by simply ignoring the older versions you are setting yourself up for future development problems.