window.Browser?

We all love IE, right?!? WRONG! Well now with jquery bumping out the browser detection we have to have some way to deal with IE and gracefully degradating our features. I found a pretty neat way of dealing with browser detection that I have integrated at a very root layer for my javascript.
(function (window, navigator) {
    window.Browser = {
        IsIe: function () {
            return navigator.appVersion.indexOf("MSIE") !== -1;
        },
        IsIeMobile10: function () {
            return navigator.userAgent.match(/IEMobile\/10\.0/);
        },
        Navigator: navigator.appVersion,
        Version: function () {
            var version = 999; // we assume a sane browser
            if (navigator.appVersion.indexOf("MSIE") !== -1) {
                // bah, IE again, lets downgrade version number
                version = parseFloat(navigator.appVersion.split("MSIE")[1]);
                return version;
            }
        }
    };
}(window, navigator));
Let’s pick this guy apart, shall we? First off, we wrap the whole thing an Immediately-Invoked Function Expression, or IIFE (if-ee). This lets us get some immediate functionality as soon as the JS is hit, it also, based on the params passed into the function, have local references to object that live on the js page scope so there is much faster retrieval time.
E.G.
(function (yellowSubmarine) {
    yellowSubmarine.on('click', function(event) {
        console.log("do click things");
    });
}(jQuery));
This will set the var `yellowSubmarine` to the jQuery function. Pretty normal javascript pattern. Moving on.

We grab `window` and set a new variable on it named `Browser`. This is where we will store our helper methods to figure out if we are dealing with IE or not. `IsIe`, `IsIeMobile10`, `Navigator`, and `Version` are all helper functions that can now be called off of `window.Browser` or just `Browser` from JS. If we have a piece of functionality that we want removed that isn’t capable of being detected by any other technology that has been implemented we now have a simple and concise way to detect and turn it off!

For example; in the previous post I wrote about the custom select box and mentioned that it will not work in IE8-10. Here is how i chose to disable it using the example code above:
$(function() {
    if (window.Browser.IsIe() && window.Browser.Version() <= 10) {
        var selectBoxes = $(".custom-select-box");
        for (var i = 0; i < selectBoxes.length; i++) {
            $(selectBoxes[i]).removeClass("custom-select-box full-width").attr("style", "width:100%").find("select").removeClass("form-control").attr("style", "width:100%");
        }
    }
};
No regex, easily readable. One line, two condition if statement. Doesn’t get much better than that in terms of detecting and fixing IE. This fix was to ‘gracefully degradate’ IE10-IE8 (our supported browsers) by just disabling the custom styling. DONE!

Custom Styled HTML dropdown/select boxes

UI/UX and dev is always a delicate balance. We had a recent request come in to style our dropdowns as the rest of our form fields. We are using bootstrap so our inputs are fairly customized. Here is how I did it, I will discuss the issues and caveats after the basic code for “modern” browsers.

HTML structure
<label class="custom-select">
    <select>
        <option value="1">Value 1</option>
        <option value="2">Value 2</option>
        <option value="3">Value 3</option>
        <option value="4">Value 4</option>
    </select>
</label>

This is all in less.

Style the containing label:
.custom-select {
    position: relative;

    &:after {
        .fa; //Font awesome icon
        .input-group-addon; //bootstrap mixin
        border-bottom-left-radius: 0;
        border-top-left-radius: 0;
        padding: 10px 13px;
        width: auto;
        height: 100%;
        content: "\f107"; //down arrow
        font-family: FontAwesome;
        position: absolute;
        right: 15px;
        top: 0px;
        pointer-events: none; //Do not block the propagation of the pointer event
    }

Now to style the select box itself which is really just hiding the arrows and coloring it.
    select {
        outline: none; //hide the outline
        -webkit-appearance: none; //hide the arrows
        -moz-appearance: none; //hide the arrows
        appearance: none; //hide the arrows
        cursor: pointer; //change the cursor
        .placeholder(); //mixin for placeholder values
        color: @input-color; //theme var
        font-weight: normal;

        option {
            color: @input-color; //background for the options
        }
    }
    /* Targetting Webkit browsers only. FF will show the dropdown arrow with so much padding. */
    @media screen and (-webkit-min-device-pixel-ratio:0) {
        select {
            padding-right: 18px;
        }
    }
}

Relatively simple, but there are some key pieces that need to be in place for this to work.
  • pointer-event: none;This is very important or the overlaid addon would catch the pointer even and we wouldn’t “click through” to the underlying select box. This is NOT SUPPORTED by anything less than ie11. (IE10 is still going to cause you fits here).
  • outline: none; //hide the outline -webkit-appearance: none; //hide the arrows -moz-appearance: none; //hide the arrows appearance: none; //hide the arrows cursor: pointer; //change the cursor Also very important so we don’t see the stupid OS generated select boxes that change from one to the next.

You will probably also notice that I don’t touch any of the nasty hacks that could happen for IE8-10. This is because I used a bit of javascript to grab these boxes and just remove all custom styling. It is much easier than hacking it and we have decided it to be graceful degradation. I will discuss this in a different post.
Your output should look something like this:
Custom_Select
Unlike some examples i’ve seen out on the internet here is an actual WORKING example of how this is supposed to look and behave in modern browsers.

HTML5 Pew-Pew (Galaga remake)!!!


This project is also available on GitHub:Mutmatt/Pew-Pew

Special thanks go out to:
Weapon Upgrades: SeongJae Park
Sound Effect: Haebin Yoon
Recover The Original Motion: JongYoon Lim
Boss Stage: Lee WonJae