Instead of using prefixes I want to ask site visit

2019-01-02 18:10发布

I'm re-building a site using CSS flexbox.

In checking browser compatibility, I see that flexbox is supported by all modern browsers, except that Safari 8 and IE 10 require vendor prefixes.

In checking Google Analytics, I see that 96% of site visitors in the last 6 months use browsers that fully support flexbox. The remaining 4% use browsers that require prefixes or provide no support.

Since we're talking about 4% of users, and the number will keep getting smaller, (and I like to keep my code as clean and simple as possible), I'm considering not using prefixes, and instead asking users to upgrade their browsers.

How can I target older browsers in order to display a message to users asking them to update their browser?

Here's what I have so far:

<!--[if IE]>
    <div class="browserupgrade">
        <p>You are using an outdated browser. Please <a href="http://browsehappy.com/">
           upgrade your browser</a> to improve your experience.</p>
    </div>
<![endif]-->

This IE conditional comment covers me for IE versions 6, 7, 8 and 9.

These visitors will get an alert with a link to download a current browser. However, Microsoft discontinued support for conditional comments starting with IE10.

Now I need something similar for:

  • IE 10
  • Safari 7-8
  • Opera Mini < 8
  • UC Browser for Android
  • Android Browser < 4.4

Is there a simple JS/jQuery script to handle this job? Or another lightweight method?


Solution

Thanks for all the answers. Clearly there are many ways to tackle this problem (Modernizr, PHP, jQuery functions, plain Javascript, CSS, browser-update.org, etc.) Many of these methods will do the job completely and effectively.

I went with the simplest one: CSS (credit @LGSon).

This CSS covers essentially all targeted browsers, except for IE <= 7.

.browserupgrade { display: block; }
_:-ms-fullscreen, :root .browserupgrade { display: none; }
:-o-prefocus, .browserupgrade { display: none; }
@supports (display: flex) { .browserupgrade { display: none; }}

See the answer for details.

And for those relatively few visitors using IE <= 7, a conditional comment in the HTML:

<!--[if lte IE 7]>
    <div style=" ... inline styles here ...">
        browser upgrade message here
    </div>
<![endif]-->

15条回答
看风景的人
2楼-- · 2019-01-02 18:36

On the front end you could use modernizr library and detect if browser support the modern features you are using.

Another thing to do is to do redirect directly from the back end to a special page. If you are using PHP for the back end you can use get_browser function to detect user agent and then load a normal page or if the browser is one of unsupported browser open a page suggesting users to upgrade.

http://php.net/manual/en/function.get-browser.php

查看更多
还给你的自由
3楼-- · 2019-01-02 18:37

This one line will check for ie10 and return true if ie10 or false otherwise .

var ie10 = /MSIE 10/i.test(navigator.userAgent) && /MSIE 10/i.test(navigator.vendor);

Did my studies here : https://blogs.msdn.microsoft.com/ie/2011/04/15/the-ie10-user-agent-string/

use case

Option 1

 if(ie10){

    //Do something

    }

UPDATE :

Microsoft browsers use @cc_on which will allow you to initiate conditional comments through script .

Option 2 :

<script>
/*@cc_on

 @if (@_jscript_version == 10){

 document.write("You are using IE10");
}
@*/
</script>

FYI . Only EI 10 and below do not support flexbox css . Proof here : http://caniuse.com/#feat=flexbox

Hope this helps

查看更多
人间绝色
4楼-- · 2019-01-02 18:38

Okay, also I suggest to use modernizr (download from https://modernizr.com/), but a little bit differently. I take it as a fact that your actual concern is only to detect if the browser supports flexbox or not, and not if it's a particular browser or browser version.

After you install it and load your page, modernizr will put classes into the <body> tag. Concerning flexbox it will put either the class .flexbox OR the class .no-flexbox into the body tag, like <body class="no-flexbox bgsizecover csscalc"> (and in fact many more classes, unless you download a modernizr custom build only for flexbox). So you can use a simple combined selector for a CSS rule that selects a DIV block into which you write your warning concerning an outdated browser. Example:

Into the HTML, write something like:

<div class="browserwarning">Your browser is outdated and cannot display this page properly! Please install an up-to-date browser, which you can get from <a href="http://www.example.com">here</a>.</div>

In the CSS stylesheet, add this:

.browserwarning {
  display: none;
}
.no-flexbox .browserwarning {
  display: block;
  font-size: 24px;
  color: red;
  background-color: yellow;
}

This will hide this message first (by the first rule), and then (second rule) only display it in browsers which cannot handle flexbox and therefore have the .no-flexbox class put into the body tag by modernizr when the page is loaded: The combined selector .no-flexbox .browserwarning works regardless of where in the body that browser warning is placed - it doesn't have to be a direct child of body, but can be anywhere in there.

This works for sure - I've used this in pages I did successfully...

查看更多
冷夜・残月
5楼-- · 2019-01-02 18:42

Revised answer after question edit

Here is a CSS only way to achieve that.

As the CSS @supports won't work on your targeted (unwanted) browsers: Safari 7-8, IE <= 10, Android Browser < 4.4, UC Browser for Android and Opera Mini < 8, your "browserupgrade" message will be visible on those using this rule.

@supports (display: flex) { .browserupgrade { display: none; }}

There is a few browsers that still does support the non-prefixed flex but doesn't support @supports, IE 11(1) and Opera Mini 8, but luckily we can address them with a couple of CSS specific rules.

/* IE 11 */
_:-ms-fullscreen, :root .browserupgrade { display: none; }

/* Opera Mini 8 */
:-o-prefocus, .browserupgrade { display: none; }

Here is the complete code to show an upgrade message for your targeted browsers.

CSS

.browserupgrade { display: block; }

/* IE 11 */
_:-ms-fullscreen, :root .browserupgrade { display: none; }

/* Opera Mini 8 */
:-o-prefocus, .browserupgrade { display: none; }

/* all modern browsers */
@supports (display: flex) { .browserupgrade { display: none; }}

HTML

<div class="browserupgrade">
    <p>You are using an outdated browser. Please <a href="http://browsehappy.com/">
       upgrade your browser</a> to improve your experience.</p>
</div>

(1): The IE 11 CSS rule should work on IE Mobile 11 too, though haven't one to test it on.


The CSS @supports is also available as an API, CSS.supports(). Here is a very well written article by David Walsh.


Additionally, if one would like to automatically redirect those browser, here is a small script that does that, after a delay of 10 sec.

var el = document.querySelector('.browserupgrade');
if (window.getComputedStyle(el,null).getPropertyValue("display") != 'none') {
  setTimeout(function(){
    window.location = 'http://browsehappy.com/';        
  }, 10000);
}
查看更多
妖精总统
6楼-- · 2019-01-02 18:43

You can use the following functions to get the browser name and version :

function get_browser() {
        var ua = navigator.userAgent, tem, M = ua
                .match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)
                || [];
        if (/trident/i.test(M[1])) {
            tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
            return 'IE ' + (tem[1] || '');
        }
        if (M[1] === 'Chrome') {
            tem = ua.match(/\bOPR\/(\d+)/)
            if (tem != null) {
                return 'Opera ' + tem[1];
            }
        }
        M = M[2] ? [ M[1], M[2] ] : [ navigator.appName, navigator.appVersion,
                '-?' ];
        if ((tem = ua.match(/version\/(\d+)/i)) != null) {
            M.splice(1, 1, tem[1]);
        }
        return M[0];
    }

    function get_browser_version() {
        var ua = navigator.userAgent, tem, M = ua
                .match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)
                || [];
        if (/trident/i.test(M[1])) {
            tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
            return 'IE ' + (tem[1] || '');
        }
        if (M[1] === 'Chrome') {
            tem = ua.match(/\bOPR\/(\d+)/)
            if (tem != null) {
                return 'Opera ' + tem[1];
            }
        }
        M = M[2] ? [ M[1], M[2] ] : [ navigator.appName, navigator.appVersion,
                '-?' ];
        if ((tem = ua.match(/version\/(\d+)/i)) != null) {
            M.splice(1, 1, tem[1]);
        }
        return M[1];
    }

and you can use the following code to alert the user to update the browser.

    jQuery(document).ready(function() {
        var browser = get_browser();
        var browser_version = get_browser_version();
        if (browser == "Chrome" && browser_version <= 30) {
            alert("Your browser is below the minimum required version. Please update your browser for this site to function properly");
        }
        if (browser == "Firefox" && browser_version <= 25) {
            alert("Your browser is below the minimum required version. Please update your browser for this site to function properly");
        }
        if (browser == "MSIE" && browser_version <= 8) {
            alert("Your browser is below the minimum required version. Please update your browser for this site to function properly");
        }
    });
查看更多
余生请多指教
7楼-- · 2019-01-02 18:45

Or another lightweight method?

If you're serving your page through nginx, there is very useful directive ancient_browser.

You need to set a list of browsers you wish to not support:

ancient_browser msie 9.0;

and then redirect those to special browser-upgrade page:

if ($ancient_browser) {
    rewrite ^ /install-chrome.html;
}

This way you're not polluting your already existing pages and do not need to load extra css for users who do not need it.

查看更多
登录 后发表回答