Category Archives: Uncategorized

IE10 Gotcha: Animating Pseudo-Elements on Hover

I came across a question on Stack Overflow today asking about animating pseudo-elements. This is something I have lamented over in the past since it’s been a supported feature in Internet Explorer 10 for a while, but only recently implemented in Chrome version 26. As it turns out, there was a small edge-case surrounding this feature that I had yet to encounter in Internet Explorer 10.

The following code does two things; first it sets the content and transition properties of the ::after pseudo-element for all paragraphs (there’s only one in this demo). Next, in the :hover state (or pseudo-class), it changes the font-size property to 2em. This change will be transitioned over 1 second, per the instruction in the first block.

p::after {
    content: ", World.";
    transition: font-size 1s;
}

p:hover::after {
    font-size: 2em;
}

Although simple and straight forward, this demo (as-is) doesn’t work in Internet Explorer 10. Although IE10 supports :hover on any element, and IE10 supports pseudo-elements, and IE10 supports animating pseudo-elements, it does not support all three, together, out of the box.

If you change your markup from using a paragraph to using an anchor element, the code begins to work. This seems to suggest some type of regression has taken place, causing Internet Explorer 10 behave similar to Internet Explorer 6 where only anchors could be “hovered” — support for :hover on any element was added in version 7.

Upon playing with this a bit, there does appear to be a few work-arounds:

  1. Change your markup
  2. Use sibling combinators in your selector
  3. Buffer a :hover selector on everything

Let’s look at these one at a time.

Change Your Markup

Rather than having a paragraph tag, you could nest a span within the paragraph, or wrap the paragraph in a div. Either way, you’ll be able to modify your selector in such a way so as to break up the :hover and ::after portions. When the user hovers over the outer element, the content of the inner-element’s pseudo-element is changed.

I don’t like this option; it’s far too invasive and demanding.

Use Sibling Combinators in Your Selector

This was an interesting discovery. I found that if you further modify your selector to include consideration for sibling elements, everything is magically repaired. For instance, the following targets our paragraph based on some other sibling paragraph:

p~p:hover::after {
    font-size: 2em;
}

This is interesting; it doesn’t break the connection between :hover and ::after, but it does modify the root of the selector, which somehow causes things to repair themselves.

What I don’t like about this approach is that it requires you to explicitly declare the sibling selector, as well as the element you’re wishing to target. Of course, we could fix this a bit by targeting a class or id, as well as going with a different sibling combinator:

*~.el:hover::after {}

This targets any element with the .el class that is a sibling of any other element. This gets us a little closer, but still, a bit messy. It requires us to modify every single selector that is part of a pseudo-element animation.

Buffering the :hover Selector

Provided with the question on Stack Overflow was one solution to the problem. As it turns out, if you provide an empty set of rules for the hover state, this fixes all subsequent attempts to animate pseudo-element properties. What this looks like follows:

p:hover {}

p::after {
    content: ", World.";
    transition: font-size 1s;
}

p:hover::after {
    font-size: 2em;
}

Oddly enough, this small addition does indeed resolve the issue. Given the nature of CSS, you can even drop the p portion, and just go with the following fixing it for all elements:

:hover{}

This too results in a functioning Internet Explorer 10 when it comes to animating pseudo-element properties.

Experiment: http://jsfiddle.net/jonathansampson/N4kf9/

Creating a (autofocus) Polyfill

In the ever-changing world of browser topography, every so often there exists an expectation in the community that some feature or API will be available in a browser, and it’s not.

We have an approach to mitigating these types of issues though, and we call it polyfilling. To quote Remy Sharp, “A polyfill, or polyfiller, is a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively. Flattening the API landscape if you will.”

A question was recently asked on Stack Overflow about automatically applying focus to an input element when the page loads. The first responses suggested using a tool like jQuery to target the element, and invoke its focus method. While this works, it adds additional overhead in environments where it’s not needed.

My initial solution to the question was to use the autofocus boolean attribute on the input element of choice. Shortly after suggesting this, I realized this attribute was only introduced in Internet Explorer at version 10, meaning users of 6, 7, 8, and 9 wouldn’t get the behavior the developer expected – perfect opportunity to author a polyfill.

Our goal in building a solid polyfill is to not make its presence known; we want the web developer to author their markup as they would normally, while we quietly teach the browser to make sense of the unknown autofocus attribute.

So we start with basic HTML:

<input name="name" placeholder="John Doe" autofocus />

In browsers like Internet Explorer 10, Chrome 26, or Firefox 20, focus will be immediately given to this element upon page load. But for Internet Explorer 6-9 and versions of Firefox prior to 4.0, we’ll have to add a bit of assistance.

We start by first performing a feature-detect for the autofocus property in a freshly-created input element. In browsers that support this property, the default value is false:

// Proceed only if new inputs don't have the autofocus property
if ( document.createElement("input").autofocus === undefined ) {

}

This condition will only evaluate to true in browsers that don’t natively understand the autofocus attribute, and as such, this will be our sandbox to play in while constructing our polyfill. We’ll need to go through a few steps for this polyfill, so let’s have a look at what they are:

  1. Cycle over all forms
  2. Cycle over all elements in each form
  3. Check attributes of each element for autofocus
  4. If found, trigger focus, and break out of all loops (only one instance of autofocus should exist on in a document, otherwise you’ll get inconsistent cross-browser results)

Our first step in the above list is to cycle over all the forms. We can use the document.forms collection to find all of the forms on the document. We’ll also create a variable to track our index in the collection of forms. Lastly, we’ll add a label to this loop so that we can break from it later:

// Get a reference to all forms, and an index variable
var forms = document.forms, fIndex = -1;

// Begin cycling over all forms in the document
formloop: while ( ++fIndex < forms.length ) {

}

Next, within our formloop, we need to get a collection of the current form’s elements. Additionally, we will be creating another index variable to help us navigate this new collection:

// Get a reference to all elements in form, and an index variable
var elements = forms[ fIndex ].elements, eIndex = -1;

// Begin cycling over all elements in collection
while ( ++eIndex < elements.length ) {

}

The third step in our process is to check for the autofocus attribute in each element. There are various ways you can do this, and I explored several of them. For instance, you could use the hasAttribute method, but this is only supported in Internet Explorer from version 8 (meaning you’d have to polyfill it in earlier versions).

In the end I wound up checking for the attribute as a key in the element.attributes collection. If not present, the result will be falsey, and the loop will skip to the next element in the nodeList:

// Check for the autofocus attribute
if ( elements[ eIndex ].attributes["autofocus"] ) {

}

Finally, we arrive at our last step. We have found an element that has the attribute we’re looking for, and it’s time to focus on it, break out of the loops, and call it quits.

// If found, trigger focus
elements[ eIndex ].focus();

// And break out of outer loop
break formloop;

This is where the formloop label comes in handy; a simple break would have broken the element loop, but not the forms loop, meaning subsequent form elements (and their children) would be evaluated. Since only one instance of autofocus should appear in a document, this is not the behavior we want.

The final result is wrapped in an IIFE (Immediately Invoking Function Expression) which runs our code immediately, as well as prevents our variables from appearing in the global namespace, potentially causing harm to the rest of the document or application.

(function () {

    // Proceed only if new inputs don't have the autofocus property
    if ( document.createElement("input").autofocus === undefined ) {

        // Get a reference to all forms, and an index variable
        var forms = document.forms, fIndex = -1;

        // Begin cycling over all forms in the document
        formloop: while ( ++fIndex < forms.length ) {

            // Reference all elements in form, and an index variable
            var elements = forms[ fIndex ].elements, eIndex = -1;

            // Begin cycling over all elements in collection
            while ( ++eIndex < elements.length ) {

                // Check for the autofocus attribute
                if ( elements[ eIndex ].attributes["autofocus"] ) {

                    // If found, trigger focus
                    elements[ eIndex ].focus();

                    // And break out of outer loop
                    break formloop;

                }

            }

        }

    }

}());

There you have it, a polyfill that gives autofocus behavior to browsers that don’t natively support it. By dropping this in to your website, you can now carry on your merry way using great features of HTML like this, without worrying what negative effect it might have on your Internet Explorer 6, 7, 8, or even 9 visitors.

Taking the Internet Explorer Challenge

I’m going to use Internet Explorer 10 as my primary browser for one week. That’s one week without browsing, tweeting, or listening to turntable in Chrome (current “Browser of Choice”). That’s one week deep inside the bowels of the browser that burned me, and so many of my peers, so badly over the last decade. One week in the heart of the beast.

Why? Isn’t Internet Explorer supposed to be a thing of the past? A bad phase in the history of the web that we’re slowly recovering from? The faint image of the broken internet from yesterday, replaced by far more standards-compliant browsers like Firefox and Chrome? Well, yes, and no.

If I’m honest with myself, and everybody else, it’s not the browser that burned me. Internet Explorer dominated the market back in the day when I got excited to see 3kb/sec downloads. It was installed along side Netscape Navigator, but won me over pretty quickly.

The browser won a lot of people over, including corporations who went on to develop internal applications that depended on its implementation of HTML, CSS, and J(ava)Script. And then the world changed around them; around all of us.

Dial-up was becoming a thing of the past, and new browsers were creeping into the scene. Firefox rose like a phoenix from the ashes of Netscape, and then Google got into the game with Chrome. These later browsers took advantage of faster and more consistent connections and offered streamlined updates that happened silently in the background.

Internet Explorer was still dominating in the global market, but these antiquated versions from yesteryear were still in circulation, and still being actively used. While they were once the apple of our eye, we quickly jumped from them to the new breed of browsers. It wasn’t that Internet Explorer 3-8 were bad – they weren’t. It was the fact that the world around them changed, and changed quickly.

Fast forward to Internet Explorer 10; it is new, and has great support for standards. Most importantly though, it hints at having the capacity to auto-upgrade like its competition. So I was curious, do I have any reason to dislike Internet Explorer any longer? Is it just as good as Google Chrome, Mozilla Firefox, or Opera? What better way to find out than to use it as my primary Browser of Choice for one week.

Sunday, Bloody Sunday

It’s really tough retraining my mind to click my Internet Explorer icon instead of my Chrome icon. The icon that was once relegated to testing and debugging my code in yesterday’s browser is now my go-to destination for all casual browsing, tweeting, and more.

So far I’ve been using Internet Explorer for Bootstrap work, blogging from WordPress, Tweeting with TweetDeck, Facebook, and casual browsing online. While I didn’t spend much time in the browser today, I did do some tweeting from @tweetdeck’s web-application, and noticed that the scrollbars are pretty horrible looking – so I fixed them. Left and right for before and after.

ie-tweetdeck-css

Unfortunately it appears Twitter has neglected Internet Explorer when they developed their dark-theme. While they fixed up the styles for the scrollbar in WebKit, they failed to do anything remotely similar in Internet Explorer. I’ve notified them (and might have gotten their attention), so let’s hope they get word and make these changes. You can make similar changes in your applications using scrollbar-face-color and related properties (See the “see also” section on the previous link).

I must admit, it would be awesome if we could control the properties of the scrollbar by setting properties on a pseudo-element instead of on any element that scrolls. It’s worth noting that in this territory, there currently is no w3c-accepted standard.

IE uses a proprietary extension in the form of prefixed-properties, and WebKit uses a proprietary extension in the form of prefixed-pseudo-elements. One can only hope there will be a consensus and convergence in implementation.

No Case of the Mundays

Today was my first actual day of work in Internet Explorer. I mean, I’ve opened it up here and there during work in the past, but today I spent all of my time in Internet Explorer – and it went well. Nothing broke (that I noticed), nothing was complicated, all was well.

I did work on a CSS example for somebody today only to have them say “the antialiasing sucks,” but as it turned out they were viewing in Chrome, and I was viewing in Internet Explorer. Sure enough, if you create a hard-edge on an angled CSS gradient, it looks better in Internet Explorer than it does in Chrome. Here’s a quick comparison between Chrome 25 and Internet Explorer 10.

linear-gradient-aa

This particular gradient is 25deg – oddly enough, Chrome draws a beautifully-smooth line when the gradient is changed to 45deg rather than 25deg. Don’t ask me why – I haven’t the slightest clue.

OMG, Tuesday!

Wow, so today was a big day. When I started this blog post I was a little bummed that the only people able to take the IE Challenge would be those who have purchased Windows 8, or a machine that came loaded with Windows 8. This morning at 6am PST, the IEBlog announced Internet Explorer 10 for Windows 7!

On to my day though – today was spent largely in Google Docs. I noticed there were some small layout differences between Chrome and IE. For instance, the number of characters you can fit on one line before a wrap occurs differs in Chrome than it does in IE. This was particularly bothersome since one of my templates features right-aligned text left-padded with enough spaces to complete a full line of characters. All of these characters are then set with a dark background color.

I wound up taking an alternative route, replacing this approach with a single-cell single-row table, and setting the background color of the cell instead of the background color of the text. This was far better and gave far more consistent results between IE and Chrome. No clue who is to blame, or what was the means by which both browsers diverged from one another, but Chrome appeared to hold itself together better overall when it came to Google Docs.

Wednesday, Thursday, and Friday

So at this point it’s just difficult to find things to blog about. I instinctively click on the Internet Explorer 10 and go straight to my browsing. I don’t experience any issues with my favorite sites. I tweet using TweetDeck, check in with Mom on facebook, drop images into imgur, broadcast using Google Hangouts, manage a channel on YouTube, help out where possible on StackOverflow, and blog about all of it here in WordPress – no issues. Everything just works.

I don’t mean to give the impression that there isn’t any work to be done – there is, a lot. Sadly, while the Internet Explorer developers have been doing an amazing job with their product, we (the community) need to step up our game as well. We’ve got to start writing better code, and paying attention to language specifications and APIs, as well as the ways in which they’re implemented in various browsers.

I came across another “my site doesn’t work in IE” thread today. The website popped up in Quirks mode. Changing it to Standards didn’t magically fix it (as it does from time to time). Instead, pushing it to Standards mode resulted in an even more damaged experience.

The problem here was written all over the Source: apathy, carelessness, and so much more. We aren’t teaching passion for our craft today as well as we should. We teach people how to hammer out some markup, and then encourage them to feed off of the visual presentation, rather than the compliance to the specification (too). New developers code, and refresh, code, and refresh. Rarely, if ever, making a trip to w3.org.

In early 2012 I came across a rather iconic website that was rendering well in Chrome and Firefox, but the side-bar navigation (made up of lists within lists) was severely broken in Internet Explorer 9. The problem wound up being an unclosed list item; I modified the response in Fiddler, issued a new request in IE9, and the page magically worked. This designer tested their markup in a browser that deviated from what the code explicitly requested (nasty nesting), and instead did what it thought the designer intended. While this resulted in the proper formatting, it breaks the web.

This was something I grew to appreciate in Internet Explorer 9 – it was brutally honest. You got what you asked for (generally speaking), and when your document was looking ugly, it was because your code was telling it to. Other browsers would implement a dose of speculation into its rendering process, which adds far too much variability to the web.

Not Perfect, But Better

A week of using Internet Explorer as your primary browser convinces me of at least two things: 1) Microsoft has come a long way with their product, and it deserves a second look. And 2) There’s still work to be done. While surfing the web on Internet Explorer 10 doesn’t feel like sucking on broken glass, it still leaves some areas for improvement.

I try to be a little less critical about massive software, given the enormous complexity to create, develop, and maintain it, but there are areas where Internet Explorer 10 can be improved. I come across these items from time to time, and try to create simplified reproducible examples when possible to share with others (and with whomever I have access to within Microsoft). One such issue is the :hover bug related to table-rows. You can see this online at http://jsfiddle.net/jonathansampson/FCzyf/show/ (Tested in Internet Explorer 10 on Windows 8 only).

Even with its flaws, Internet Explorer is still leading the way in other areas. It’s currently one of the only browsers to support pseudo-element animation, the Pointer model (though you can get ‘Pointium‘), and some CSS level 4 text properties.

My biggest concern lately is not with the browser itself, Microsoft has convinced me that their product is reliable. What concerns me lately is with the release cycles. Can they keep this new browser breathing, or are they going to continue resuscitating it on a bi-annual cycle? If so, we’ll quickly find the web moving out ahead of it again, and history will repeat itself. I find a glimmer of hope in the newest “About Internet Explorer” dialog.

Install New Versions Automatically

In my sincere opinion, Internet Explorer (in just a few years) went from being the bane of my existence (#somuchdrama), to being a bright luminary, back competing in the pack of modern browsers. Will it stay among the pack? Time will tell. Until then, welcome back Internet Explorer.

Download Internet Explorer 10, give it a week, and post your results below.

Flexible Browsers

I overheard a comment a few days ago that a friend made regarding the default layout of Internet Explorer; namely its placing of the address bar inline with tabs. This results in reduced space for tabs, thus reduced title lengths, thus reduced efficiency managing multiple tasks in parallel.

Chrome, on the other hand, places the tabs above the address bar, giving the impression the address bar is part of the tab currently-opened tab. Firefox, and Opera both also place the tabs above the address bar. Every browser appears to write in stone their tab-placement – though Internet Explorer appears to show the most flexibility.

Upon exploring Internet Explorer following my friends comments, I soon found that I could resize the address bar, re-arrange the stop/refresh buttons, drop tabs down onto their own line (or leave them inline), reduce certain toolbars down into command buttons to minimize space-used. Needless to say, I was pretty impressed with just how much flexibility I found in Internet Explorer.

Here are a few arrangements I went through:

Exploring Varation in Internet Explorer's Layout

Exploring various customizations of the address bar, tabs, and more in Internet Explorer.

As previously mentioned, the above shows the resizing of the address bar, shifting of the stop/refresh buttons from the right over to the left (easier to avoid accidentally clicking the Compatibility View button), dropping tabs onto their own line (you can leave them inline, if that floats your boat), collapsing toolbars like the LastPass one into the command region, and making it inline with the favorites.

Of the four browsers I checked, Chrome appears to be the most rigid. As for customization, you can change the theme, but this is really not much more than swapping out a background image on browser itself. You can’t change the address bar width (well, you can resize the add-on bar, which results in a longer/shorter address bar), the placement of the tabs, the locality of the buttons or anything. You can, however, toggle the “Home” button on and off.

chrome-appearance

Both Firefox and Opera have really impressive options for customizing your toolbars, but that might be a degree of control that few people enjoy. I personally explored it, but didn’t find it too appealing. Also in Firefox you can disable tabs until you explicitly request to open a link in a second tab. This too reduces used-space around the “chrome” of the browser.

Opera sports an even more advanced set of options for Tab Bar Placement. While tabs at are traditionally at the top of the content (following their real-world exemplar of manila folders), you can place them on any side of the viewport in Opera. The changes of the layout are pretty drastic, so I apologize for the disorienting effect of the following gif:

Tab Bar Placement in Opera.

Tab Bar Placement in Opera.

My take-away is that Chrome is nice on the eyes, but far too rigid with the layout options. Opera and Firefox go to the other extreme, and drop enough tools in your lap that you’d need an engineer’s manual to truly understand the power you’ve been given. Internet Explorer hits closest to the sweet spot in my sincere opinion. While I wish Internet Explorer had a few features we’ve come to love in its competition, I am happy with the degree (and limits) of flexibility Microsoft has chosen to provide.

Use Vendor Prefixes Carefully

Vendor-prefixed properties and values in CSS are a beautiful thing; they allow you to do some really awesome stuff that would otherwise require a copy of Photoshop on your machine. In mere seconds you can whip up gradients, reflections, and even animations.

All of this is so appealing that people forget the fact that these are prefixed for a reason – they’re experiments, and should be viewed as such. That doesn’t mean you can’t use them, it just means you need to do so cautiously.

Don’t use these features in such a way that your page is severely broken without them – that’s not cool. Don’t use them in an unbalanced way either, providing prefixes for one browser but not for the others. And don’t use them in an anachronistic way, giving higher priority to prefixed experimental implementations over un-prefixed standardized implementations.

Often times I come across CSS that looks like this:

.gradientBox {
  background-image: linear-gradient(0deg, red, green);
  background-image: -moz-linear-gradient(0deg, red, green);
  background-image: -webkit-linear-gradient(0deg, red, green);
}

There are a few problems with this. For starters, only Firefox and Chrome/Safari are accounted for in the prefixes. It may very well be that Internet Explorer and Opera have provided an implementation under their own prefixes, -ms- and -o- respectively. You should provide for those as well.

Additionally, the unprefixed (which would be the standardized implementation) property is at the top, meaning it will be evaluated first, followed by the others. This means if you visit the page in a browser that supports both a -moz- prefix, and it’s unprefixed alternative, the un-prefixed implementation will be tossed out in favor of the experimental prefixed version – this isn’t cool.

So how should it look?

.gradientBox {
  background-image: -webkit-linear-gradient(0deg, red, green);
  background-image: -moz-linear-gradient(0deg, red, green);
  background-image: -ms-linear-gradient(0deg, red, green);
  background-image: -o-linear-gradient(0deg, red, green);
  background-image: linear-gradient(0deg, red, green);
}

The browser evaluates the rules from top to bottom. Internet Explorer will ignore any -webkit- properties, as well as any -moz- or -o- properties. If it supports the -ms- prefix, it will implement this rule. When it comes to the un-prefixed version, it will determine whether that value is supported or not. If it is not, it will be ignored, and the -ms- implementation will remain. Otherwise, the un-prefixed version will take precedence over the prefixed version. The same flow exists for the other major browsers.

But that’s a lot of writing, right? Fortunately we have a lot of great tools today that can reduce the effort on your page. From pre-processors like SASS and Compass to entire editors like Microsoft’s Visual Web Developer 2012, many options exist that will fill-out these values for you. We even have a great JavaScript option in -prefix-free which lets you write only the un-prefixed version – it will determine the appropriate prefix (if necessary) and insert it when the page is loaded.

Bottom line is this, we can enjoy these experimental features without breaking the web for people. If you’re going to use prefixed properties and values in CSS, do so wisely.

Of Dice, Dabblet, and CSS

I discovered dabblet.com some time back and never really spent much time there. Don’t get me wrong, it made a great first impression, however I am not super-talented in the CSS department, and it seems to be a tool for those who are.

I decided to return this evening and try my hand at creating some dice with nothing but CSS. I recently became a Potentate of the Rose, so this was a relevant and timely interest. After a couple hours of distracted back-and-forth, I finally had something pretty attractive.

While I don’t consider myself much of a CSS power-house, dabblet.com made the tedious process of building these die super-fun and very palatable. If you find yourself giving dabblet a run (and I suggest you do it), be sure to thank @leaverou for all of her hard work on such an awesome tool.

The final result can be seen here, or in the framed demo below.

Creating Your Own Custom jQuery Filters

Chances are you have probably used custom filters in jQuery from time to time to save on verbose selectors. For instance, if we wanted all of the buttons, selects, inputs, and textareas within a form we could do the following:

$("button, textarea, input, select", "#myForm");

You can see how that quickly piles up and gets a bit heavy. jQuery natively provides us with the :input filter which grabs all form elements:

$("#myForm :input");

While these both do the same thing, it’s far easier to call :input than it is to construct a large selector containing all of the particular form elements we can remember at the time. There is a bit of  a performance issue with things like :input though, since they have to cycle over all potential elements. That’s why it’s wise to limit our load by providing some context, in this case we’re looking only within #myForm.

While we can do a lot with what jQuery brings out-of-the-box, we’re capable of doing so much more using some of the tools it provides us with.

You’ve likely used .filter to sift through your elements before applying some effects:

$("div").filter(":visible").hide();

The filter method can take a string expression like :visible and determine which of the div elements meet its demands, and which don’t. Those that don’t will be dropped, and all remaining will have .hide called against them. This method can take a function as well:

$("div").filter(function(){
    return $(this).text() === "Foobar";
}).hide();

Here we are manually sifting through the elements based upon some examination of their properties. We return true or false, depending on whether the current element being evaluated has the text “Foobar” or not. This solution isn’t very flexible though, what if I wanted to check different things for different strings?

Fortunately jQuery exposes itself in such a way that we can extend its base filters and add our own.

Our focus from here will be on $.expr[":"]. Within the jQuery function ($) is an object called expr. This object has objects within, one of which is called “:”. This object is where we will place our new method, and provide the necessary functionality to determine which elements pass, and which fail.

$.extend($.expr[":"], {
    exactly: function(){
        return true;
    }
});

With nothing more than the above, we can already use our filter:

$("div:exactly");

Granted, it doesn’t do anything, but it doesn’t blow up in our face either! As is the case with most callback methods, the element currently being handled is referred to as this. With that, we could already perform some logic:

$.extend($.expr[":"], {
    exactly: function(){
        return $(this).text() === "Foobar";
    }
});

Of all the div elements we’re cycling over, only those whose text content loosely equals “Foobar” will be kept, while all others are discarded. But again, who wants to hard-code “Foobar” into the definition of the filter? Wouldn’t it be better if our filter worked like :contains in that it took some parameters?

It is at this point we need to look at the arguments passed to our function. We can do so by logging the arguments object from within:

$.extend($.expr[":"], {
    exactly: function(){
        console.log( arguments );
    }
});

$("div:exactly");

In our console we find the following:

[<div>​Hello World</div>​,   0, Array[4], NodeList[3]]
[<div>​Hello, World</div>​,  1, Array[4], NodeList[3]]
[<div>​Hello, World.</div>​, 2, Array[4], NodeList[3]]

My selector evaluated three div elements. The first argument passed to my function is the element itself. The second is the index of the element. Third is an array of details about the selector itself (more about that in a minute), and the last item is a NodeList of all elements being evaluated.

In this particular instance, our selector array looks like this:

[":exactly", "exactly", undefined, undefined]

We see it has a reference to the filter, the term used in the filter, and then two undefined values. If we were to modify our filter a bit to accept a parameter, we would see the following:

$("div:exactly(Foobar)");
[":exactly(Foobar)", "exactly", "", "Foobar"]

The first value is our entire selector. The second is our filter name, third in this case is empty (though if we wrapped our term in single quotes, this entry would be a single quote as the outer-most single-quotes would be removed from the last item in this array), and last is the actual parameter passed in. Armed with this knowledge, we can then finish our custom filter:

$.extend($.expr[":"], {
    exactly: function( element, index, details, collection ){
        return $(element).text() === details[3];
    }
});

At this point, we can now select any element based on its text value:

$("div:exactly(foo), p:exactly(bar)");

We now have a reusable solution to a common task.

First Impression of Windows 8 (Developer Preview)

I downloaded the developer preview of Windows 8 a few weeks ago so that I could begin playing with Internet Explorer 10. After setting up a new partition and loading the OS into a dual-boot environment, I was quickly up and running in Windows 8. I’ve been using the operating system almost exclusively now for a while, and I wanted to share some of the things I like, and some of the things I don’t like so much. In complete honesty, the likes greatly outweigh the dislikes – in fact, the dislikes are probably too few to require more than half a hand to list (but of course that may grow with more exposure and experience).

I write this today as somebody who knows nothing about what specific goals Microsoft has in developing this operating system. All I know is that it’s something of a one-size-fits-all, in that it’s intended to be used on both the desktop, as well as the mobile tablet interface. I’ll be honest, that fact alone had me a little suspicious. My desktop and my tablet are two radically different experiences. But could Microsoft really pull it off, and create something for both?

Fast, So Fast!

Setting up windows was quick and required very little effort. One thing I thought was especially interesting was the prompt I received to give the Setup Wizard my Live account email address. My user account is directly tied to my Live account, which I thought was pretty cool.

As cool as the Live account integration was, that wasn’t what floored me during setup: the actual boot time was! From the boot screen to my login screen, the process of getting into the OS often takes less than a few seconds. Honestly, when I select the Windows 8 Developer Preview from my boot screen, I find it difficult to actually count more than 2 seconds or so – what a joy it is to not sit and wait.

Here’s another demo online from Microsoft themselves, though I think my PC loads up just a bit faster – but hey, it’s no contest, right? :)

Of course the boot screen itself is pretty handsome now too – no more white text on a black background, Windows 8 is purdy!

Multiple Displays

I am running Windows 8 on a dual-monitor setup. This meant that when I log into the machine, my left (Primary) monitor loads up the new start screen, and my right monitor (secondary display) loads up a more traditional looking desktop.

This was the first major impression made – the interface for interacting with the computer had changed completely. While a little lost, and scared, I was excited. Scrolling up and down would slide all of these neat little panels left and right, revealing games, applications and other goodies. The first thing I did was jump into the Zero Gravity game and get lost in weightless-adventure for about an hour (I didn’t have my sound working at this point, so I’m surprised I managed to play that long without audio).

Gorgeous New Task Manager

After poking around on this screen for a bit, I clicked the “desktop” panel which slid the start screen out of the way to reveal a classic desktop experience on both monitors – ah, now I feel at home.

I was curious how much memory this OS uses, so I decided to visit the performance tab from the task-manager: CTRL+ALT+DEL brought up another nice screen, and sure enough, Task Manager was there on the list of items to select.

Immediately I noticed a much nicer looking task manager – good for him, he’s been pretty ugly for as long as I can remember.

I love how much details is shared in this newer task manager, and how nicely presented it is as well. The varying yellow background colors change as frequently as the values in the cells do themselves. It’s pretty neat – just a small panel of flashing cells and fluctuating numbers. Really puts you in that “I’m Neo, and I’ll bend your reality” state of mind. But this wasn’t what I wanted to see, I wanted to see the Performance tab.

Goodness, even more beauty! I love the colors, the layout, the entire experience is just awesome. I realize I probably sound like a Microsoft fan-boy at this point, but I don’t have an agenda here, my excitement is entirely organic. From one panel I can see my CPU usage, Memory usage, current Disk usage, Data sent and received over ethernet, as well as my current transfers in Kbps, and so much more. And to top it off, it’s actually aesthetically pleasing.

Okay, Time for a Complaint (Kinda)

I would hardly convince you that I’m being fair here if I didn’t list a few things that bother me about my initial experience with Windows 8 Developer Preview. Your Start button (or ‘Pearl’) is no more, it’s dead, it’s gone – write up its eulogy. Unfortunately,  I don’t think that we have been given anything better in its place. In fact, we’re given a very confusing alternative.

Both of my displays have their own taskbar, and both also have their own start button. This wouldn’t be so bad if each of the start buttons didn’t behave differently. On my main display, hovering over the start button reveals a small fly-out menu, as well as a large over-sized date (which I actually like):

Careful, don’t click that button. Clicking it will throw you back into the start screen with the fancy panels. This is what I mean by the start button that we all know and love is dead. I instinctively click this thing about once a day it seems, especially when I’m trying to find something I just installed.

Meanwhile, over on display two, there’s an odd looking icon in the place of the start button:

This button, when clicked, actually swaps the two buttons. If you click this, the start button from the primary display will replace this, and this will occupy the old location of the primary start button. Confusing, eh?

Essentially this button moves your fancy-panel screen over to this display. Clicking this button on my secondary display causes the neat new home screen of panels to be revealed on this monitor as opposed to my primary monitor.

The complaint here is that the traditional start button that we have known for nearly all of Windows’ history is dead and gone. Admittedly, it doesn’t take long to get used to this new behavior, but it’s entirely unexpected. Additionally, you can’t just hover over any portion of the main start button to reveal the fly-up mini-menu. From what I can tell, you have to hover over the lower-left corner of the button. At times I’ve found myself hovering over the button while thinking to myself “What the eph, computer – respond!”

Finally, Smart Taskbars!

The taskbar has always been a frustrating thing for me. I’ve found myself wanting them to be a bit smarter for several iterations of the Windows operating system, and with Windows 8, Microsoft has delivered! One feature in particular really excited me.

So, a lot of this stuff is pretty standard, but the “Windows appear” portion is what caught my attention. To be honest, I didn’t really understand what it meant, “Unique to each taskbar,” so I selected it and applied. I immediately found out that any programs opened on my primary display would show up in my primary taskbar, and any programs opened on my secondary display would show up in my secondary taskbar.

Further, dragging a window from display 2 over to display 1 results in taskbar 2 giving up the application to taskbar 1. Awesome! No longer does my taskbar just tell me that I have a program opened, somewhere, but it is now smart enough to tell me which display contains which application.

This post is quickly becoming a bit too large, so I’ll cut it off here. The more I use the Developer Preview the more I’ll have to say about it. But so far, I’m very pleased with what I’ve been seeing. Nice work, Microsoft.

Sometimes jQuery is (not) the Answer

It’s difficult to say, as much as I love jQuery I must admit that it is at times the wrong route to take when addressing a problem.

While looking over a few questions on StackOverflow today I came across a poster who was seeking to modify the width of all nested elements within a container – he naturally thought jQuery would be a good, simple solution – and it is. But while it may be simple, it’s wrong in this case.

Rather than coming right out and answering with something like:

$("#container").find("*").width("100%");

I instead took just a moment to whip up a test case on http://jsperf.com (great site for testing the performance advantages of one method over others.) Just as I had suspected, jQuery would be slower than raw JavaScript – much, much slower.

var i,
    container = document.getElementById("container"),
    tags = container.getElementsByTagName("*"),
    total = tags.length;

for ( i = 0; i < total; i++ ) {
  tags[i].style.width = '100%';
}

This simple block does the same thing as the aforementioned jQuery code, but it’s much faster. In fact, in the time it takes the jQuery code to perform 20k operations, the raw JavaScript code performs nearly 300k!

You can see this particular performance test online at http://jsperf.com/resizing-children.

wordpress-unexpected

Unexpected Results While Styling WordPress Menus

Today I sat down to convert a static theme consisting of nothing more than HTML and CSS into a WordPress theme, complete with calls to functions like wp_nav_menu() for the construction of the menu’s. For this particular theme I began with a copy of the TwentyTen theme. When I came across the task of establishing a navigational menu I found some rather unexpected results from WordPress – something I think they should consider changing in future releases. (Note: The following assumes version 3.1.3 is being used)

When you open up header.php in the TwentyTen theme you’ll find the following on or around line 85:

<?php wp_nav_menu( array( 
  'container_class' => 'menu-header', 
  'theme_location' => 'primary' 
) ); ?>

This is really pretty straight forward. It defines itself as the location for any menu assigned to the “primary” spot. Additionally, it sets a container class to “menu-header”. Given this information, we should expect this to result in is an unordered list wrapped in a div (the default container is a div) that has the class “menu-header”. So what markup is generated by WordPress when somebody sets up a fresh copy of it and checks out their TwentyTen theme?

<div class="menu">
  <ul>
    <!-- ... -->
  </ul>
</div>

At first there may not appear to be any problems, but look more closely at the container class declared in the call to wp_nav_menu() and what is actually applied in the generated markup. While we declared a class of “menu-header”, what we actually get is a class of “menu”. This really frustrated me this evening.

Some users of WordPress have been unable to reproduce this effect, and the reason is fairly simple why they couldn’t – they likely have a menu already assigned to the “primary” location. Anybody who does not initially have a menu created and applied to this location will be left scratching their head.

So what is WordPress doing exactly? Initially WordPress will look for a menu assigned to this location, if it doesn’t find one it will move on to do something else. Along down the line, just before throwing its hands up completely it will call a fallback method to generate something for the user. The default fallback method is provided for us in the source (line 141):

$defaults = array( 
  /* ... */
  'fallback_cb' => 'wp_page_menu'
  /* ... */
);

So if no menu is present when wp_nav_menu() is called, it will fallback into calling the wp_page_menu() method. Up to this point this shouldn’t seem like much of a threat. Sure, if I don’t have a menu WordPress can go ahead and generate a list of pages that I might have published. Unfortunately, this is where some communication-breakdown occurs and things get a bit messy.

Recall the generated HTML list previously shown, this is what wp_page_menu() generated for us in the absence of a user-defined menu. Like wp_nav_menu(), wp_page_menu() has its own set of internally-declared default arguments that will determine much of how the results will look and feel. We can see these defaults declared below:

$defaults = array(
  'sort_column' => 'menu_order, post_title', 
  'menu_class' => 'menu', 
  'echo' => true, 
  'link_before' => '', 
  'link_after' => ''
);

The only thing we’re interested in right now is the ‘menu_class’ which, by default, is set to “menu”. This is where the “menu” class comes from in the place of our “menu-header” class passed to wp_nav_menu(). This isn’t the light at the end of the tunnel, things get even messier from here.

While it’s nice of WordPress to generate a list for us in the absence of a menu, the integrity of our data breaks down in the process. When we call wp_nav_menu() and tell it to set the “container_class” to “menu-header”, the resulting call to wp_page_menu() completely ignores this request. Again, this isn’t the end of the mess, the wp_nav_menu() function also allows us to provide a ‘menu_class’, or a class which should be applied to the generated menu within the container. Suppose we did this:

<?php wp_nav_menu( array( 
  'container_class' => 'menu-header', 
  'menu_class' => 'foo', 
  'theme_location' => 'primary' 
) ); ?>

What we should expect to see from this is a menu that looks like the following:

<div class="menu-header">
  <ul class="foo">
    <!-- ... -->
  </ul>
</div>

This should be the result regardless if pages or custom menu items populate the UL. If no menu is present, and WordPress falls back on the wp_page_menu() function, what it generates is anything but expected:

<div class="foo">
  <ul>
    <!-- ... -->
  </ul>
</div>

Note how the “menu_class” is actually applied to the container, and the “container_class” of “menu-header” is entirely abandoned. This isn’t what we asked for.

If we turn around and create a menu called “Sample Menu”, and set it to be displayed in the “primary” location, what we are presented with is the following:

<div class="menu-header">
  <ul id="menu-sample-menu" class="foo">
    <!-- ... -->
  </ul>
</div>

Notice how it gets the container class correct, and the menu class correct when we actually have a menu for it to display.

I’m hoping this problem will be resolved in future versions of WordPress for the sanity of those creating themes. Not for them alone, but for the reputation of WordPress as a whole too. If its own internal communication isn’t consistent, it makes for a very bad testimony when those of us out in the real world are attempting to act as evangelists for the wonderful platform.