salcode / bootstrap-genesis

WordPress Genesis Child Theme setup to use Bootstrap, Sass, and Grunt
MIT License
184 stars 63 forks source link

Visitor's forced into compatibility mode #128

Closed salcode closed 8 years ago

salcode commented 8 years ago

Sub-issue created from #127

@bryanwillis wrote:

I'm still getting complaints from users being forced into compatibility mode and the site layouts breaking

and

To quickly bring people up to date on the issue, basically company's running IE9 automatically throw this theme into compatibility mode

salcode commented 8 years ago

@bryanwillis thanks for all the hard work and research you put into #127

We definitely want to apply some kind of fix to users getting kicked into compatibility mode. I'm having a tough time with this issue because I haven't been able to recreate the problem (and get IE9 to throw me into compatibility mode).

Do you have any notes on how to recreate the problem?

I'd really like to recreate it so I can try out the solutions you mentioned and we can get something merged in to correct it.

bryanwillis commented 8 years ago

Take a look at why HTML5 boilerplate removed the CC's in the commit or see updated docs here.

By including comments like <!--[if IE 9 ]> around the html tag before the xua meta tag we are telling IE to determine what version it is. Once it is able to determine what version it is, it is too late for our meta tag because the the document mode has already been set.

IE9 forces the browse mode to run in compatibility when it encounters any intranet websites or sites in enterprise mode (corps, universities, government, etc) unless specified otherwise in the document mode.

Basically forced compatibility can occur if...

From Microsoft:

Placing the Meta Tag Too Late: If the meta tag appears after we have had to determine the rendering engine, then you are too late. You have to include that metadata before running scripts or rendering HTML. The mode can be switched only before you’ve done any work which uses a rendering and scripting engine, otherwise we decide based on the header or the group policy.

... Bootstrap and HTML5 Boilerplate both re-emphasis this.


Some things to consider:


The most accepted solution is to remove the meta tag altogether and instead include in in http headers. This can be done a few ways, but the "wordpress way" is by using send_headers(). This way we don't have to worry about any seo plugins or Genesis for that matter adding additional markup before the tag and HTTP header it is slightly better for performance because it avoids a potential browser parser issues.

is_admin() || add_action( 'send_headers', 'add_header_xua' );
function add_header_xua() {
    header( 'X-UA-Compatible: IE=edge,chrome=1' );
}, 1);

This should fix the issue and allow us to optionally keep the conditional comments if necessary. However, a better approach would be to add them to the body class. I think it's very important to consider though why we need them in the first place especially since Bootstrap, HTML5BP, and Genesis don't use them. If this is a "Bootstrap Genesis" theme shouldn't we be following the way they do things? Plus out of the box they do nothing on their own making them useless the developer adds their own css.


Bootstrap3 has support for IE8 and IE9 by adding html5shiv and respond. While Genesis adds html5shiv, it's safer adding it ourselves to ensure it's loaded just before the closing head tag.

/**
 * Load HTML5shiv and Respond Correctly
 */
if ( genesis_html5() ) {
    remove_action( 'wp_head', 'genesis_html5_ie_fix' );
    add_action( 'wp_enqueue_scripts', 'bsg_html5_shiv_respond_js_add_last' );
}
function bsg_html5_shiv_respond_js_add_last() { 
    wp_enqueue_script( 'html5shiv',
        'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js',
        array('bootstrap'),
        false,
        false
    );
    wp_enqueue_script( 'respond',
        'https://oss.maxcdn.com/respond/1.4.2/respond.min.js',
        array('bootstrap'),
        false,
        false
    );
    wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );
    wp_script_add_data( 'respond', 'conditional', 'lt IE 9' );
}
salcode commented 8 years ago

Ok, I was able to recreate the problem. My understanding is there is more than one way to trigger this behavior but I went with the Intranet trigger.

Steps to Recreate

Tell Tale Signs

You'll notice your in compatibility mode because

salcode commented 8 years ago

I recognize I'm probably overly attached to the .ie6 through .ie9 classes provided by conditional comments. This technique was revolutionary for me as a developer and I find them comforting to still have available if I need to tweak something on one of these older browsers.

Therefore my preference is to add the header 'X-UA-Compatible: IE=edge,chrome=1 as @bryanwillis outlined above.

I've added Bryan's code on branch ie-compat-mode-128 and as long as there are no objections, I'll merge it in.

Thanks for all your hard work (and patience) on this Bryan.