Related
I am currently adding support of QWebEngineWidgets to my older applications but I don't want to loose QWebKitWidgets. because in some embeded platforms the qt version is still 5.3. I wonder if the following solution I made by myself is correct and better solutions is also welcome.
equals(QT_MAJOR_VERSION, 5) {
lessThan(QT_MINOR_VERSION, 5) {
QT += webkitwidgets
}
greaterThan(QT_MINOR_VERSION, 4) {
QT += webenginewidgets
}
}
You can also use "else" for the alternative branch, e.g.
lessThan(QT_MINOR_VERSION, 5) {
} else {
}
or even check for a module's availability specifically
qtHaveModule(webengine) {
}
IE10+ no longer supports browser detection tags to identify a browser.
For detecting IE10 I am using JavaScript and a capability-testing technique to detect certain ms prefixed styles are defined such as msTouchAction and msWrapFlow.
I want to do the same for IE11, but I am assuming that all the IE10 styles will be supported in IE11 as well. Can anyone help me identify IE11 only styles or capabilities that I could use to tell the two apart?
Extra Info
I don't want to use User Agent type detection because it's so spotty, and can be changed, as well as I think I've read that IE11 is intentionally trying to hide the fact it's Internet Explorer.
For an example of how the IE10 capability testing works, I used this JsFiddle (not mine) as a basis for my testing.
Also I am expecting a lot of answers of "This is a bad idea...". One of my needs for this is that IE10 claims it supports something, but it is very badly implemented, and I want to be able to differentiate between IE10 and IE11+ so I can move on with a capability-based detection method in the future.
This test is coupled with a Modernizr test that will simply make some functionality "fallback" to less glamorous behavior. We are not talking about critical functionality.
I am already using Modernizr, but it doesn't help here.
In the light of the evolving thread, I have updated the below:
IE 6
* html .ie6 {property:value;}
or
.ie6 { _property:value;}
IE 7
*+html .ie7 {property:value;}
or
*:first-child+html .ie7 {property:value;}
IE 6 and 7
#media screen\9 {
.ie67 {property:value;}
}
or
.ie67 { *property:value;}
or
.ie67 { #property:value;}
IE 6, 7 and 8
#media \0screen\,screen\9 {
.ie678 {property:value;}
}
IE 8
html>/**/body .ie8 {property:value;}
or
#media \0screen {
.ie8 {property:value;}
}
IE 8 Standards Mode Only
.ie8 { property /*\**/: value\9 }
IE 8,9 and 10
#media screen\0 {
.ie8910 {property:value;}
}
IE 9 only
#media screen and (min-width:0\0) and (min-resolution: .001dpcm) {
// IE9 CSS
.ie9{property:value;}
}
IE 9 and above
#media screen and (min-width:0\0) and (min-resolution: +72dpi) {
// IE9+ CSS
.ie9up{property:value;}
}
IE 9 and 10
#media screen and (min-width:0) {
.ie910{property:value;}
}
IE 10 only
_:-ms-lang(x), .ie10 { property:value\9; }
IE 10 and above
_:-ms-lang(x), .ie10up { property:value; }
or
#media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
.ie10up{property:value;}
}
The use of -ms-high-contrast means that MS Edge will not be targeted, as Edge does not support -ms-high-contrast.
IE 11
_:-ms-fullscreen, :root .ie11up { property:value; }
Javascript alternatives
Modernizr
Modernizr runs quickly on page load to detect features; it then
creates a JavaScript object with the results, and adds classes to the
html element
User agent selection
Javascript:
var b = document.documentElement;
b.setAttribute('data-useragent', navigator.userAgent);
b.setAttribute('data-platform', navigator.platform );
b.className += ((!!('ontouchstart' in window) || !!('onmsgesturechange' in window))?' touch':'');
Adds (e.g) the below to html element:
data-useragent='Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)'
data-platform='Win32'
Allowing very targetted CSS selectors, e.g.:
html[data-useragent*='Chrome/13.0'] .nav{
background:url(img/radial_grad.png) center bottom no-repeat;
}
Footnote
If possible, identify and fix any issue(s) without hacks. Support progressive enhancement and graceful degradation. However, this is an 'ideal world' scenario not always obtainable, as such- the above should help provide some good options.
Attribution / Essential Reading
Jeff Clayton | Browserhacks.com
Keith Clarke
Paul Irish
Web Devout
The Spanner
To target IE10 and IE11 only (and not Edge):
#media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
/* add your IE10-IE11 css here */
}
So I found my own solution to this problem in the end.
After searching through Microsoft documentation I managed to find a new IE11 only style msTextCombineHorizontal
In my test, I check for IE10 styles and if they are a positive match, then I check for the IE11 only style. If I find it, then it's IE11+, if I don't, then it's IE10.
Code Example: Detect IE10 and IE11 by CSS Capability Testing (JSFiddle)
/**
Target IE 10 with JavaScript and CSS property detection.
# 2013 by Tim Pietrusky
# timpietrusky.com
**/
// IE 10 only CSS properties
var ie10Styles = [
'msTouchAction',
'msWrapFlow',
'msWrapMargin',
'msWrapThrough',
'msOverflowStyle',
'msScrollChaining',
'msScrollLimit',
'msScrollLimitXMin',
'msScrollLimitYMin',
'msScrollLimitXMax',
'msScrollLimitYMax',
'msScrollRails',
'msScrollSnapPointsX',
'msScrollSnapPointsY',
'msScrollSnapType',
'msScrollSnapX',
'msScrollSnapY',
'msScrollTranslation',
'msFlexbox',
'msFlex',
'msFlexOrder'];
var ie11Styles = [
'msTextCombineHorizontal'];
/*
* Test all IE only CSS properties
*/
var d = document;
var b = d.body;
var s = b.style;
var ieVersion = null;
var property;
// Test IE10 properties
for (var i = 0; i < ie10Styles.length; i++) {
property = ie10Styles[i];
if (s[property] != undefined) {
ieVersion = "ie10";
createEl("IE10 style found: " + property);
}
}
// Test IE11 properties
for (var i = 0; i < ie11Styles.length; i++) {
property = ie11Styles[i];
if (s[property] != undefined) {
ieVersion = "ie11";
createEl("IE11 style found: " + property);
}
}
if (ieVersion) {
b.className = ieVersion;
$('#versionId').html('Version: ' + ieVersion);
} else {
createEl('Not IE10 or 11.');
}
/*
* Just a little helper to create a DOM element
*/
function createEl(content) {
el = d.createElement('div');
el.innerHTML = content;
b.appendChild(el);
}
/*
* List of IE CSS stuff:
* http://msdn.microsoft.com/en-us/library/ie/hh869403(v=vs.85).aspx
*/
body {
font: 1.25em sans-serif;
}
div {
background: red;
color:#fff;
padding: 1em;
}
.ie10 div {
background: green;
margin-bottom:.5em;
}
.ie11 div {
background: purple;
margin-bottom:.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1>Detect IE10 and IE11 by CSS Capability Testing</h1>
<h2 id="versionId"></h2>
I will update the code example with more styles when I discover them.
NOTE: This will almost certainly identify IE12 and IE13 as "IE11", as those styles will probably carry forward. I will add further tests as new versions roll out, and hopefully be able to rely again on Modernizr.
I'm using this test for fallback behavior. The fallback behavior is just less glamorous styling, it doesn't have reduced functionality.
This seems to work:
#media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
/* IE10+ specific styles go here */
}
https://www.limecanvas.com/css-hacks-for-targeting-ie-10-and-above/
Here's an answer for 2017 on, where you probably only care about distinguishing <=IE11 from >IE11 ("Edge"):
#supports not (old: ie) { /* code for not old IE here */ }
More demonstrative example:
body:before { content: 'old ie'; }
/**/#supports not (old: ie) {
body:before { content: 'not old ie'; }
/**/}
This works because IE11 doesn't actually even support #supports, and all other relevant browser/version combinations do.
You can write your IE11 code as normal and then use #supports and check for a property that isn't supported in IE11, for example grid-area: auto.
You can then write your modern browser styles within this. IE doesn't support the #supports rule and will use the original styles, whereas these will be overridden in modern browsers that support #supports.
.my-class {
// IE the background will be red
background: red;
// Modern browsers the background will be blue
#supports (grid-area: auto) {
background: blue;
}
}
This worked for me
if(navigator.userAgent.match(/Trident.*rv:11\./)) {
$('body').addClass('ie11');
}
And then in the css file things prefixed with
body.ie11 #some-other-div
When is this browser ready to die?
Try this:
/*------Specific style for IE11---------*/
_:-ms-fullscreen, :root
.legend
{
line-height: 1.5em;
position: relative;
top: -1.1em;
}
Take a look at this article: CSS: User Agent Selectors
Basically, when you use this script:
var b = document.documentElement;
b.setAttribute('data-useragent', navigator.userAgent);
b.setAttribute('data-platform', navigator.platform );
b.className += ((!!('ontouchstart' in window) || !!('onmsgesturechange' in window))?' touch':'');
You can now use CSS to target any browser / version.
So for IE11 we could do this:
FIDDLE
html[data-useragent*='rv:11.0']
{
color: green;
}
Use the following properties:
!!window.MSInputMethodContext
!!document.msFullscreenEnabled
You should use Modernizr, it will add a class to the body tag.
also:
function getIeVersion()
{
var rv = -1;
if (navigator.appName == 'Microsoft Internet Explorer')
{
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
else if (navigator.appName == 'Netscape')
{
var ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
return rv;
}
Note that IE11 is still is in preview, and the user agent may change before release.
The User-agent string for IE 11 is currently this one :
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko
Which means your can simply test, for versions 11.xx,
var isIE11 = !!navigator.userAgent.match(/Trident.*rv 11\./)
Perhaps Layout Engine v0.7.0 is a good solution for your situation. It uses browser feature detection and can detect not only IE11 and IE10, but also IE9, IE8, and IE7. It also detects other popular browsers, including some mobile browsers. It adds a class to the html tag, is easy to use, and it's performed well under some fairly deep testing.
http://mattstow.com/layout-engine.html
If you're using Modernizr - then you can easily differntiate between IE10 and IE11.
IE10 doesn't support the pointer-events property. IE11 does. (caniuse)
Now, based on the class which Modernizr inserts you could have the following CSS:
.class
{
/* for IE11 */
}
.no-pointerevents .class
{
/* for IE10 */
}
You can use js and add a class in html to maintain the standard of conditional comments:
var ua = navigator.userAgent,
doc = document.documentElement;
if ((ua.match(/MSIE 10.0/i))) {
doc.className = doc.className + " ie10";
} else if((ua.match(/rv:11.0/i))){
doc.className = doc.className + " ie11";
}
Or use a lib like bowser:
https://github.com/ded/bowser
Or modernizr for feature detection:
http://modernizr.com/
Detecting IE and its versions actually is extremely easy, at least extremely intuitive:
var uA = navigator.userAgent;
var browser = null;
var ieVersion = null;
if (uA.indexOf('MSIE 6') >= 0) {
browser = 'IE';
ieVersion = 6;
}
if (uA.indexOf('MSIE 7') >= 0) {
browser = 'IE';
ieVersion = 7;
}
if (document.documentMode) { // as of IE8
browser = 'IE';
ieVersion = document.documentMode;
}
.
This way, ou're also catching high IE versions in Compatibility Mode/View. Next, its a matter of assigning conditional classes:
var htmlTag = document.documentElement;
if (browser == 'IE' && ieVersion <= 11)
htmlTag.className += ' ie11-';
You can try this:
if(document.documentMode) {
document.documentElement.className+=' ie'+document.documentMode;
}
I ran into the same problem with a Gravity Form (WordPress) in IE11. The form's column style "display: inline-grid" broke the layout; applying the answers above resolved the discrepancy!
#media all and (-ms-high-contrast:none){
*::-ms-backdrop, .gfmc-column { display: inline-block;} /* IE11 */
}
Step back: why are you even trying to detect "internet explorer" rather than "my website needs to do X, does this browser support that feature? If so, good browser. If not, then I should warn the user".
You should hit up http://modernizr.com/ instead of continuing what you're doing.
I'm currently working on a cross-browser Dropdown-Menu.
But currently I have some issues specifically on iOS 5.1 while "hovering" (means: Touching) the Main-Level Navigation links.
On iOS >= 6.0 the link action is prevented using return false and the submenu changes visibility to show and opacity to 1.
But on iOS 5.1 nothing happens. Neither the link-action nor the dropdownmenu shows.
EDIT: Code-Sample
$(function() {
if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
$("#mainNavigation ul li.dropactive > a").click(function() {
return false;
});
}
});
Any special workarounds for this iOS Safari?
Cheers,
~MxAgent
In addition to "hover", add a "focus" selector.
http://www.w3schools.com/cssref/sel_focus.asp
Is there a way to apply the following CSS to a specific div only in Google Chrome?
position:relative;
top:-2px;
CSS Solution
from https://jeffclayton.wordpress.com/2015/08/10/1279/
/* Chrome, Safari, AND NOW ALSO the Edge Browser and Firefox */
#media screen and (-webkit-min-device-pixel-ratio:0) {
div{top:10;}
}
/* Chrome 29+ */
#media screen and (-webkit-min-device-pixel-ratio:0)
and (min-resolution:.001dpcm) {
div{top:0;}
}
/* Chrome 22-28 */
#media screen and(-webkit-min-device-pixel-ratio:0) {
.selector {-chrome-:only(;
property:value;
);}
}
JavaScript Solution
if (navigator.appVersion.indexOf("Chrome/") != -1) {
// modify button
}
As we know,Chrome is a Webkit browser,Safari is a Webkit browser too,and Also Opera,so it's very hard to target the Google Chrome,using media queries or CSS hacks,but Javascript is really more effective.
Here is the piece of Javascript code that will target Google Chrome 14 and later,
var isChrome = !!window.chrome && !!window.chrome.webstore;
and below is a list of Available Browser hacks,for the Google chrome including the influenced browser,by that hack
WebKit hack:
.selector:not(*:root) {}
Google Chrome:All the versions
Safari:All the versions
Opera :14 and Later
Android:All the versions
Supports Hacks:
#supports (-webkit-appearance:none) {}
Google Chrome 28,and Google Chrome > 28, Opera 14 and Opera > 14
Google Chrome:28 and Later
Opera :14 and Later
Firefox: 64 and Later (i.e. this no longer works)
Property/Value Hacks:
.selector { (;property: value;); }
.selector { [;property: value;]; }
Google Chrome 28,and Google Chrome < 28, Opera 14 and Opera > 14,and Safari 7 and Less than 7.
Google Chrome:28 and Before
Safari:7 and Before
Opera :14 and Later
JavaScript Hacks:1
var isChromium = !!window.chrome;
Google Chrome:All the versions
Opera :14 and Later
Android:4.0.4
JavaScript Hacks:2 {Webkit}
var isWebkit = 'WebkitAppearance' in document.documentElement.style;
Google Chrome:All the versions
Safari:3 and Later
Opera :14 and Later
JavaScript Hacks:3
var isChrome = !!window.chrome && !!window.chrome.webstore;
Google Chrome:14 and Later
Media Query Hacks:1
#media \\0 screen {}
Google Chrome:22 to 28
Safari:7 and Later
Media Query Hacks:2
#media all and (-webkit-min-device-pixel-ratio:0) and (min-resolution: .001dpcm) { .selector {} }
Google Chrome:29 and Later
Opera:16 and Later
For more information please visit this website
An update for chrome > 29 and Safari > 8 :
Safari now supports the #supports feature too. That means those hacks would also be valid for Safari.
I would recommend
# http://codepen.io/sebilasse/pen/BjMoye
/* Chrome only: */
#media all and (-webkit-min-device-pixel-ratio:0) and (min-resolution: .001dpcm) {
p {
color: red;
}
}
This css browser selector may help you. Take a look.
CSS Browser Selector is a very small javascript with just one line
which empower CSS selectors. It gives you the ability to write
specific CSS code for each operating system and each browser.
http://www.templatemonster.com/help/how-to-create-browser-specific-css-rules-styles.html
Apply specific CSS rules to Chrome only by using .selector:not(*:root) with your selectors:
div {
color: forestgreen;
}
.selector:not(*:root), .div1 {
color: #dd14d5;
}
<div class='div1'>DIV1</div>
<div class='div2'>DIV2</div>
The accepted answer matches Firefox 80+ also.
To target all Webkit browsers (Edge 79+, Chrome, Safari), find a -webkit specific CSS extension that is not supported by Firefox (use https://caniuse.com). This is a moving target; one of the Webkit browsers may remove it, and a non-Webkit browser may add support for it.
Here are two examples:
#supports(-webkit-text-security: circle) {
/* Matches Edge 79 - latest (92) */
/* Matches Chrome 4 - latest (95) */
/* Matches Safari 3.1 - latest (15/TP) */
/* Matches Opera 15 - latest (78) */
/* does not match Firefox */
}
#supports(-webkit-tap-highlight-color: black) {
/* Matches Edge 12 - latest (92) */
/* Matches Chrome 16 - latest (95) */
/* Matches Opera 15 - latest (78) */
/* does not match Safari */
/* does not match Firefox */
}
If you actually need Chrome-only, JS is probably the only way to go.
The .selector:not(*:root) {} hack in https://stackoverflow.com/a/25496712/1218408 still excludes Firefox through version 92 but matches Safari.
Have never run across an instance where I had to do a Chrome-only css hack until now. However, I found this to move content below a slideshow where clear:both; affected nothing in Chrome (but worked fine everywhere else - even IE!).
#media screen and (-webkit-min-device-pixel-ratio:0) {
/* Safari and Chrome, if Chrome rule needed */
.container {
margin-top:100px;
}
/* Safari 5+ ONLY */
::i-block-chrome, .container {
margin-top:0px;
}
So simple. Just add a second class or id to you element at load time that specifies which browser it is.
So basically at the front end, detect browser then set id/class and your css will be befined using those browser specific nametags
if you want we can add class to specific brwoser see [fiddle link][1]
[1]:
var BrowserDetect = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "Other";
this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "Unknown";
},
searchString: function (data) {
for (var i = 0; i < data.length; i++) {
var dataString = data[i].string;
this.versionSearchString = data[i].subString;
if (dataString.indexOf(data[i].subString) !== -1) {
return data[i].identity;
}
}
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index === -1) {
return;
}
var rv = dataString.indexOf("rv:");
if (this.versionSearchString === "Trident" && rv !== -1) {
return parseFloat(dataString.substring(rv + 3));
} else {
return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
}
},
dataBrowser: [
{string: navigator.userAgent, subString: "Edge", identity: "MS Edge"},
{string: navigator.userAgent, subString: "MSIE", identity: "Explorer"},
{string: navigator.userAgent, subString: "Trident", identity: "Explorer"},
{string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
{string: navigator.userAgent, subString: "Opera", identity: "Opera"},
{string: navigator.userAgent, subString: "OPR", identity: "Opera"},
{string: navigator.userAgent, subString: "Chrome", identity: "Chrome"},
{string: navigator.userAgent, subString: "Safari", identity: "Safari"}
]
};
BrowserDetect.init();
var bv= BrowserDetect.browser;
if( bv == "Chrome"){
$("body").addClass("chrome");
}
else if(bv == "MS Edge"){
$("body").addClass("edge");
}
else if(bv == "Explorer"){
$("body").addClass("ie");
}
else if(bv == "Firefox"){
$("body").addClass("Firefox");
}
$(".relative").click(function(){
$(".oc").toggle('slide', { direction: 'left', mode: 'show' }, 500);
$(".oc1").css({
'width' : '100%',
'margin-left' : '0px',
});
});
.relative {
background-color: red;
height: 30px;
position: relative;
width: 30px;
}
.relative .child {
left: 10px;
position: absolute;
top: 4px;
}
.oc {
background: #ddd none repeat scroll 0 0;
height: 300px;
position: relative;
width: 500px;
float:left;
}
.oc1 {
background: #ddd none repeat scroll 0 0;
height: 300px;
position: relative;
width: 300px;
float:left;
margin-left: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<div class="relative">
<span class="child">
○
</span>
</div>
<div class="oc">
<div class="data"> </div>
</div>
<div class="oc1" style="display: block;">
<div class="data"> </div>
</div>
Chrome provides no own conditionals to set CSS definitions just for it! There shouldn't be a need to do this, cause Chrome interprets websites like defined in w3c standards.
So, you have two meaningful possibilities:
Get current browser by javascript (look here)
Get current browser by php/serverside (look here)
I am using a sass mixin for chrome styles, this is for Chrome 29+ borrowing the solution from Martin Kristiansson above.
#mixin chrome-styles {
#media screen and (-webkit-min-device-pixel-ratio:0)
and (min-resolution:.001dpcm) {
#content;
}
}
Use it like this:
#include chrome-styles {
.header { display: none; }
}
How to Apply CSS to Only Chrome
You might try the code below if you want to apply CSS to only Chrome browsers (Webkit/Blink). Keep in mind there are other browsers that use Chrome's Webkit engine...
#supports (not (-moz-appearance:button)) and (contain:paint) and (-webkit-appearance:none) {
body {
background: blue;
}
}
In 2022, this code works pretty well and should work in most Chrome browsers going back to ~ 2013. It should filter out all Internet Explorer, early Trident Edge, Firefox, Safari, and many other browsers. But please test!
Keep in mind Microsoft Edge version 83 and later switched from the old Trident engine to Chrome's Blink browser engine in May of 2020. So, this should work in the newer Edge browsers, as well. Expect that to function that way as the engines under the covers are close to the same!
NOTES ON THIS CSS
As mentioned, the code above works in all browsers that share some modern version of the Chrome Webkit or Blink engines. The two main deciding factors in the code above as far as earliest possible browser support in Chrome-based engines would be support of the CSS feature at-rule #supports and the newer Chrome prefixed property -webkit-appearance:none. Combined, full support for both in Chrome did not begin till May, of 2013 (I believe). So you can count on Chrome browsers version 28 through today would or should support this CSS hack above. But again, please test!
So let's go through how the hack works.....
Use of the new #supports at-rule or 'feature check' allows your browser to check if a specific CSS property or feature, and its value, is supported in the user's browser. The problem is very few older and even newer browsers support the #supports CSS trick. It really did not get support in Chrome till around the May 2013 browser release. So that would be the earliest Chrome browsers supported. Keep in mind Chrome was not released till 2008, so was a late browser.
But browser non-support of #supports is the main way this CSS is hidden from nearly all other browsers since adoption is still so poor. All browsers prior to 2010 and most prior to 2013 will ignore the rule above. But Chrome version 27 till today would have baseline support of the rule. Microsoft Internet Explorer 1-11 completely ignore it, and only Microsoft Edge version 83 to present (2020-present) would understand the #supports rule. Firefox did not adopt it till 2019 and most Safari user agents starting in 2021. So it is a major filtering tool!
The generic "appearance" CSS property (non-prefixed version) was supported in Mozilla/Firefox as early as 2006 and in Chrome around 2010 in prefixed experimental version with partial support for various features. The Firefox prefix version -moz-appearance and the Chrome browser prefixed version -webkit-appearance seem to have early adoption so would find support across a wide range of browsers. The value "button" (pre-2006) has earlier adoption in Mozilla/Firefox browsers than "none" for "apperance", so increases the chance you filter out those browsers. "none" for "appearance" in Chrome was a very early supported property value (2010), so was used to widen the range of Chrome browsers possible. So the two prefix rules both remove the most mozilla/Firefox browsers and widen the most Chrome browsers possible in the code above.
So you can probably assume Chrome browsers starting in 2013-present would be able to use the rules below, and seen by all browsers using Webkit engines since then.
The logic (not (-moz-appearance:none)) hides the CSS block from all Mozilla/Firefox browsers. When combined with limited support for "#support" however, it makes sure even earlier ones are all excluded.
The CSS property contain:paint was mainly supported after 2016 in Chrome and Firefox. So this excludes Safari browsers from the CSS block. Some Safari iOS switched to the Webkit Chrome engine, however. So contain:paint makes sure those older Safari browsers are excluded from the Chrome Webkit filter.
Lastly, the Chrome prefixed rule, -webkit-appearance, applies only to Chrome Webkit browsers. It makes sure the rule below is only seen by Chrome. Keep in mind some later Firefox browsers started to support Chrome prefix properties. But with the extra filters above, they are now hidden from the CSS block above. As mentioned above, -webkit-appearance:none has wide enough adoption that it should at least go back to the earliest adoption date of #support at-rules in the web browser. As far as I know that is sometime around May of 2013.
So in summary, the CSS above filters allows only Chrome browsers going back to version 27 in 2013 and Microsoft Edge 83 in 2020 to see the code.
WHY DO WE EVEN NEED TO APPLY CSS FOR CHROME?
HTML5 and CSS standards have changed since 2010. There are no more W3C Recommendations where carefully agreed on standards are applied by all browsers. This means browser vendors are randomly changing their browsers continually (called Evergreen) as far as CSS support. It also means CSS will change on-the-fly, code forks will rarely be aligned, CSS in all the other browsers will rarely match each other, and "hacks" above could change as well.
This failed Web Standards movement forms the basis for why new CSS has partial support between browsers and versions, browsers will increasingly not look the same, and these prefixed CSS hacks will be needed in the future. Not good :(
/* saf3+, chrome1+ */
#media screen and (-webkit-min-device-pixel-ratio:0) {
/*your rules for chrome*/
#divid{
position:relative;
top:-2px;
}
}
check this.it work for me.
Hi I've cross browser fixed a site on all thinkable PC browsers, including Safari.
Now my smart ass designer sent me a screen shot of the whole layout collapsing on mac.
I have an idea how to solve it (reduce the margin on an element by a few pix), but i don't know how to target Safari only, preferably Safari mac only.
What's the best way to do this?
Here's a script you can include on your page (or in a separate js file) that will add a class to the html element so that you can add safari-mac specific css to your css file.
(function($){
// console.log(navigator.userAgent);
/* Adjustments for Safari on Mac */
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Mac') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
// console.log('Safari on Mac detected, applying class...');
$('html').addClass('safari-mac'); // provide a class for the safari-mac specific css to filter with
}
})(jQuery);
Example css fixes, which can be in page or in your external css file etc:
/* Safari Mac specific alterations
* (relies on class added by js browser detection above),
* to take into account different font metrics */
.safari-mac #page4 .section p.fussyDesigner { margin-right: -15px; }
.safari-mac #page8 .section-footer { width: 694px; }
Thanks to other answers for ideas, I've tried to wrap everything up into a complete solution in this answer.
The user agent string contains operating system information, and you are probably already checking the user agent string for the browser type.
A mac browser will have the string "Mac OS X 10." in the user agent string.
I think the selected right answer is outdated and does not work now.
Here is the output of navigator.vendor
Safari on iPad
Mozilla/5.0 (iPad; CPU OS 8_3 like Mac OS X) AppleWebKit/600.1.4
(KHTML, like Gecko) Version/8.0 Mobile/12F69 Safari/600.1.4
Safari on Mac
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5
(KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 Safari/600.1.4
As you can see Mac appears in navigator.vendor of both scenarios.
Here is my version
var isSafariMac = /Safari/.test(navigator.userAgent) &&
!/Mobile/.test(navigator.userAgent) &&
/Apple Computer/.test(navigator.vendor);
So you can use this to target Safari on Mac:)
Building off of #Tim Abell's solution, you can use a similar approach to get classes for all of the major platforms and browsers for broader detection and flexibility.
This snippet will add a class for the browser name and another for the platform name to the <html> element. So, for example, Safari on Mac would end up being <html class="safari mac">.
Javascript/jQuery
//Search for keywords within the user agent string. When a match is found, add a corresponding class to the html element and return. (Inspired by http://stackoverflow.com/a/10137912/114558)
function addUserAgentClass(keywords) {
for(var i = 0; i < keywords.length; i++) {
if(navigator.userAgent.indexOf(keywords[i]) != -1) {
$("html").addClass(keywords[i].toLowerCase());
return; //Once we find and process a matching keyword, return to prevent less "specific" classes from being added
}
}
}
addUserAgentClass(["Chrome", "Firefox", "MSIE", "Safari", "Opera", "Mozilla"]); //Browsers listed generally from most-specific to least-specific
addUserAgentClass(["Android", "iPhone", "iPad", "Linux", "Mac", "Windows"]); //Platforms, also in order of specificity
With this approach, you can do things like:
CSS
.safari { /* Safari only */ }
.mac { /* Mac only */ }
.safari.mac { /* Safari Mac */ }
html:not(.safari) { /* All browsers except for Safari */ }
html:not(.safari.mac) { /* All browsers except for Safari Mac */ }
Glad I found this page, I feel your pain anytime you use padding with font based navigation or tabs you run into these Mac/PC issues because they render fonts differently.
if (navigator.userAgent.indexOf('Mac') >= 0) {
$(element).addClass('mac_os')
}
// targets macs only`
You probably need to run a regex query against the User-Agent and selectively load a CSS file just for Safari for Mac.
Also: Are you sure that Safari for mac and safari for windows render the same page drastically different?
#media screen and (-webkit-min-device-pixel-ratio:0) {
/* Add your Safari-specific styles here. */
}
An example of providing dynamic styles for various browsers:
<?php
$str = $_SERVER['HTTP_USER_AGENT'];
$pos1 = strpos($str, "Safari");
$pos2 = strpos($str, "Chrome");
$pos3 = strpos($str, "MSIE");
$pos4 = strpos($str, "Firefox");
if($pos1 != '' && $pos2 == '') // Safari
$style = "width:200px; height:100px;";
else if($pos2 != '') // Chrome
$style = "width:180px; height:90px;";
else if($pos3 != '') // IE
$style = "width:180px; height:90px;";
else if($pos4 != '') // Firefox
$style = "width:180px; height:90px;";
?>
<div style="<?php echo $style; ?>">Hello world</div>
for this question i have solution with the help of CSS, please find the below code fixes..
/* Safari 10.1+ */
#media not all and (min-resolution:.001dpcm) {
#supports (-webkit-appearance:none) {
.classname{
padding: 1px 0px; // css styles
}
}
}
Please try this in .scss file.
Use this in css. it will be rendered only in Safari
/*\*/
.some-class {
/* Here comes some options */
}
/**/