Is there a way to detect if ie has animation disabled - css

I have an animated gif that works perfectly in all browsers except ie (surprise, surprise). After much searching I have found the gif is not animated in ie due to a setting in the options:
Settings -> Advanced settings -> Multimedia -> Play animations in webpages
Is there any way to detect if this is enabled as I would like to display something else instead of a static loading gif, or is there a way to force ie to play the animation?
In case there is a workaround, here is the code I use to show my loader and the type of gif I am using:
#loading {
background:url(http://preloaders.net/preloaders/712/Floating%20rays.gif) center center no-repeat;
position:fixed;
left:0;
right:0;
bottom:0;
top:0;
}
<div id="loading"></div>

You can use root class from body which shows only IE browser then write like as below in your css:
.rootclassname #loading {
background : //use static image here
}

Hmmm, seems a bit dirty but what the hell, punish the stupid ie users...
As a workaround, I did a mixture of Prajwal and lonut's answers - adding an ie class to my loader I then saved out each part of the animated gif and then used the following js to give me an animated loader for ie:
var ieLoadingCount = 1,
ieLoadingInt;
function addLoading() {
var loading = $('#paving-designer-loading');
if (loading.hasClass('ie')) { // only do this for ie
clearInterval(ieLoadingInt); // need to clear interval as this is a multi-step form and addLoading may be called multiple times
ieLoadingInt = setInterval(function () { animateIELoading(loading, true); }, 175); // preload images
}
}
function animateIELoading(loading, firstRun) {
loading.css('background-image', 'url(' + baseUrl + 'images/presentation/toolbox/pavingdesigner/loading/' + ieLoadingCount + '.png)');
if (ieLoadingCount == 12) { // loading gif had 12 parts in it
ieLoadingCount = 1;
if (firstRun) {
clearInterval(ieLoadingInt); // finish preload
ieLoadingInt = null;
}
} else {
ieLoadingCount++;
}
}
function showLoading(loading) {
if (loading.hasClass('ie')) {
clearInterval(ieLoadingInt);
ieLoadingInt = setInterval(function () { animateIELoading(loading, false); }, 175);
}
loading.show();
}
function hideLoading(loading) {
loading.hide();
if (loading.hasClass('ie')) {
clearInterval(ieLoadingInt);
}
}
I'll leave this open in case anyone can find a way to check if the animation is allowed in the first place as currently I apply this for all ie users regardless of if the animation is allowed or not. Would be good to only apply it to the browsers that have their animations turned off.

Related

Can autoprefixer solve the issue of CSS variables for Internet Explorer?

I am using css variables in my angular7 application. Everything works fine on other browsers. But IE is not supporting css variables. Is there a way to make it work on IE. Can Autoprefixer do this?
color: var(--primary, #7F583F);
According to caniuse.com, of current browsers only IE, Edge (older versions) and Opera Mini do not support CSS variables. This polyfil appears to work on all three really well.
This is an attempt at a very basic CSS variables (custom properties) polyfil. In reality this is more of a partial polyfill as it will not cover variables inside of variables, DOM scoping or anything else "fancy". Just taking variables declared anywhere in the CSS and then re-parsing the CSS for var() statements and replacing them in browsers that don't natively support CSS variables.
I try to test this polyfil in IE 11 and looks like it is working with it.
/*!
* css-var-polyfill.js - v1.0.0
*
* Copyright (c) 2018 Aaron Barker <http://aaronbarker.net>
* Released under the MIT license
*
* Date: 2018-03-09
*/
let cssVarPoly = {
init: function() {
// first lets see if the browser supports CSS variables
// No version of IE supports window.CSS.supports, so if that isn't supported in the first place we know CSS variables is not supported
// Edge supports supports, so check for actual variable support
if (window.CSS && window.CSS.supports && window.CSS.supports('(--foo: red)')) {
// this browser does support variables, abort
console.log('your browser supports CSS variables, aborting and letting the native support handle things.');
return;
} else {
// edge barfs on console statements if the console is not open... lame!
console.log('no support for you! polyfill all (some of) the things!!');
document.querySelector('body').classList.add('cssvars-polyfilled');
}
cssVarPoly.ratifiedVars = {};
cssVarPoly.varsByBlock = {};
cssVarPoly.oldCSS = {};
// start things off
cssVarPoly.findCSS();
cssVarPoly.updateCSS();
},
// find all the css blocks, save off the content, and look for variables
findCSS: function() {
let styleBlocks = document.querySelectorAll('style:not(.inserted),link[rel="stylesheet"]');
// we need to track the order of the style/link elements when we save off the CSS, set a counter
let counter = 1;
// loop through all CSS blocks looking for CSS variables being set
[].forEach.call(styleBlocks, function(block) {
// console.log(block.nodeName);
let theCSS;
if (block.nodeName === 'STYLE') {
// console.log("style");
theCSS = block.innerHTML;
cssVarPoly.findSetters(theCSS, counter);
} else if (block.nodeName === 'LINK') {
// console.log("link");
cssVarPoly.getLink(block.getAttribute('href'), counter, function(counter, request) {
cssVarPoly.findSetters(request.responseText, counter);
cssVarPoly.oldCSS[counter] = request.responseText;
cssVarPoly.updateCSS();
});
theCSS = '';
}
// save off the CSS to parse through again later. the value may be empty for links that are waiting for their ajax return, but this will maintain the order
cssVarPoly.oldCSS[counter] = theCSS;
counter++;
});
},
// find all the "--variable: value" matches in a provided block of CSS and add them to the master list
findSetters: function(theCSS, counter) {
// console.log(theCSS);
cssVarPoly.varsByBlock[counter] = theCSS.match(/(--.+:.+;)/g) || [];
},
// run through all the CSS blocks to update the variables and then inject on the page
updateCSS: function() {
// first lets loop through all the variables to make sure later vars trump earlier vars
cssVarPoly.ratifySetters(cssVarPoly.varsByBlock);
// loop through the css blocks (styles and links)
for (let curCSSID in cssVarPoly.oldCSS) {
// console.log("curCSS:",oldCSS[curCSSID]);
let newCSS = cssVarPoly.replaceGetters(cssVarPoly.oldCSS[curCSSID], cssVarPoly.ratifiedVars);
// put it back into the page
// first check to see if this block exists already
if (document.querySelector('#inserted' + curCSSID)) {
// console.log("updating")
document.querySelector('#inserted' + curCSSID).innerHTML = newCSS;
} else {
// console.log("adding");
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = newCSS;
style.classList.add('inserted');
style.id = 'inserted' + curCSSID;
document.getElementsByTagName('head')[0].appendChild(style);
}
};
},
// parse a provided block of CSS looking for a provided list of variables and replace the --var-name with the correct value
replaceGetters: function(curCSS, varList) {
// console.log(varList);
for (let theVar in varList) {
// console.log(theVar);
// match the variable with the actual variable name
let getterRegex = new RegExp('var\\(\\s*' + theVar + '\\s*\\)', 'g');
// console.log(getterRegex);
// console.log(curCSS);
curCSS = curCSS.replace(getterRegex, varList[theVar]);
// now check for any getters that are left that have fallbacks
let getterRegex2 = new RegExp('var\\(\\s*.+\\s*,\\s*(.+)\\)', 'g');
// console.log(getterRegex);
// console.log(curCSS);
let matches = curCSS.match(getterRegex2);
if (matches) {
// console.log("matches",matches);
matches.forEach(function(match) {
// console.log(match.match(/var\(.+,\s*(.+)\)/))
// find the fallback within the getter
curCSS = curCSS.replace(match, match.match(/var\(.+,\s*(.+)\)/)[1]);
});
}
// curCSS = curCSS.replace(getterRegex2,varList[theVar]);
};
// console.log(curCSS);
return curCSS;
},
// determine the css variable name value pair and track the latest
ratifySetters: function(varList) {
// console.log("varList:",varList);
// loop through each block in order, to maintain order specificity
for (let curBlock in varList) {
let curVars = varList[curBlock];
// console.log("curVars:",curVars);
// loop through each var in the block
curVars.forEach(function(theVar) {
// console.log(theVar);
// split on the name value pair separator
let matches = theVar.split(/:\s*/);
// console.log(matches);
// put it in an object based on the varName. Each time we do this it will override a previous use and so will always have the last set be the winner
// 0 = the name, 1 = the value, strip off the ; if it is there
cssVarPoly.ratifiedVars[matches[0]] = matches[1].replace(/;/, '');
});
};
// console.log(ratifiedVars);
},
// get the CSS file (same domain for now)
getLink: function(url, counter, success) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.overrideMimeType('text/css;');
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
// console.log(request.responseText);
if (typeof success === 'function') {
success(counter, request);
}
} else {
// We reached our target server, but it returned an error
console.warn('an error was returned from:', url);
}
};
request.onerror = function() {
// There was a connection error of some sort
console.warn('we could not get anything from:', url);
};
request.send();
}
};
cssVarPoly.init();
:root {
--externalcolor: red;
--samename: orange;
--samename: #0f0;
--foo: green;
--FOO: #0f0;
--halfsuccess: orange;
--success: green;
--success2: #0f0;
}
html {
font-family: var(--fontsans);
}
.success {
color: green;
}
.fail {
color: red;
}
span {
display: inline-block;
margin: 5px;
}
.samename {
color: var(--samename);
}
.demo1 {
color: #f00;
color: var(--success);
}
.demo2 {
color: #f00;
color: var( --success2);
}
.demo3 {
color: #f00;
color: var(--halfsuccess);
color: var(--success);
}
.demo4 {
color: red;
border-color: #f00;
}
.inlineoverlink {
color: #f00;
}
p {
padding: var(--spacing-l);
}
.lower {
color: var(--foo);
}
.upper {
color: var(--FOO);
}
.externalcolor {
color: var(--externalcolor);
}
.fallback {
color: #f00;
color: var(--wrongname, green);
}
// for the top documentation
.supports {
color: green;
.no {
display:none;
}
}
.showforpolyfill {
display:none;
}
.cssvars-polyfilled {
.supports {
color: red;
.no {
display:inline;
}
}
.showforpolyfill {
display:inline;
}
.hideforpolyfill {
display:none;
}
}
.hide,
.hide-the-docs .documentation {
display:none;
}
/* declare some font-family stuff at bottom of file to reflect on stuff above it*/
:root {
--fontsans: arial;
}
<!-- Copy below for codepen update -->
<h1>CSS Variables Polyfill</h1>
<p>This is now managed (and available for PRs) at https://github.com/aaronbarker/css-variables-polyfill.</p>
<p>
This is an attempt at a very basic CSS variables (custom properties) polyfil. In reality this is more of a <em>partial</em> polyfill as it will not cover variables inside of variables, DOM scoping or anything else "fancy". Just taking variables declared anywhere in the CSS and
then re-parsing the CSS for var() statements and replacing them in browsers that don't natively support CSS variables.
</p>
<p>According to caniuse.com, of current browsers only IE, Edge and Opera Mini do not support CSS variables. This polyfil appears to work on all three really well. I don't see why this wouldn't work on older browsers as well, but I haven't been able to test it on them yet.</p>
<p>As far as we can tell your browser <span class="supports">does <span class="no">not</span> support</span> native CSS variables. <span class="showforpolyfill">That means if you see green tests results below, it is thanks to the polyfill :).</span> <span class="hideforpolyfill">All the green test results below are actually native CSS Variable support. Good job using a good browser :)</span></p>
<h3>Does this work on externally CSS files?</h3>
<p>Yes!</p>
<h3>Even ones loaded from another domain?</h3>
<p>To go across domain, CSS needs to be served up with <code>Access-Control-Allow-Origin:*</code> headers.</p>
</div>
Toggle documentation (for Opera Mini vs Codepen issue)
<style>
:root {
--newcolor: #0f0;
}
.inlineoverlink {
color: var(--success2);
}
</style>
<h2>Tests</h2>
<p>On mosts tests (unless otherwise noted) success will be green text. We start with a <code>color:red;</code> and then override it with a <code>color:var(--success);</code> (or similar) which is green.</p>
<ul>
<li><span class="samename">declare same variable over and over</span></li>
<li><span class="demo1">no whitespace on var() calls</span></li>
<li><span class="demo2">whitespace on var() calls</span></li>
<li><span class="demo3">Multiple variables in same call. orange means first var worked, green var worked</span></li>
<li><span class="inlineoverlink">orange if link won, green if style after link won</span></li>
<li><span class="lower">--foo: lowercase foo</span></li>
<li><span class="upper">--FOO: uppercase FOO</span></li>
<li><span class="fallback">uses fallback <code>--var(--wrongname, green)</code></span></li>
<li><span class="demo-import">css declared in an <code>#import</code></span> - not polyfilled yet. Identfied with a suggested fix, but will require a bit of a re-write (to use document.styleSheets), so haven't done it yet.</li>
</ul>
<h2>Tests on external, cross-domain file</h2>
<div class="documentation">
<p><strong>Edge</strong> appears to be working well on Edge 13. Edge 12 was having some problems.</p>
<p><strong>Opera mini</strong> seems to work well too. This demo fails because not all the page is displayed, but I think that is a codepen issue, not a polyfill issue. When the upper documentation is removed, all tests display well.</p>
<p><strong>IE 11</strong> seems to do fine.</p>
</div>
<ul>
<li><span class="demo4">Gets stuff from external .css file. Should start red and change to green on LINK load. border proves the CSS loaded, missing colors means script didn't get parsed and reinserted</span></li>
<li><span class="externalcolor">--externalcolor: should start red and change to green on LINK load</span></li>
<li><span class="externalfallback">uses fallback. should be green</span></li>
</ul>
<p>Another set of text under the test for Opera Mini testing.</p>
<!-- Copy above for codepen update -->
Testing result:
References:
(1) Codepen example link
(2) aaronbarker/css-variables-polyfill

Using Selenium to determine the visibility of elements for Print media

I would like to determine if particular elements on a page are visible when printed as controlled by CSS #media rules.
Is there a way to do this with Selenium?
I know there is the isDisplayed method, which takes the CSS into account, but there is nothing I can find to tell Selenium which media type to apply.
Is there a way to do this?
Or is there another way to test web pages to make sure the elements you want are printed (and those you don't aren't)?
Update:
For clarity, there are no plans to have a javascript print button. The users will print using the normal print functionality of the browser (Chrome, FF and IE). #media css rules will be used to control what is shown and hidden. I would like Selenium to pretend it is a printer instead of a screen, so I can test if certain elements will be visible in what would be the printed version of the page.
I've managed to write a script that does just what you want: it hides screen-only styles and sets print-only styles to be screen-only.
You need to inject the following JavaScript with Selenium:
(function pretendToBeAPrinter() {
//For looking up if something is in the media list
function hasMedia(list, media) {
if (!list) return false;
var i = list.length;
while (i--) {
if (list[i] === media) {
return true;
}
}
return false;
}
//Loop though all stylesheets
for (var styleSheetNo = 0; styleSheetNo < document.styleSheets.length; styleSheetNo++) {
//Current stylesheet
var styleSheet = document.styleSheets[styleSheetNo];
//Output debug information
console.info("Stylesheet #" + styleSheetNo + ":");
console.log(styleSheet);
//First, check if any media queries have been defined on the <style> / <link> tag
//Disable screen-only sheets
if (hasMedia(styleSheet.media, "screen") && !hasMedia(styleSheet.media, "print")) {
styleSheet.disabled = true;
}
//Display "print" stylesheets
if (!hasMedia(styleSheet.media, "screen") && hasMedia(styleSheet.media, "print")) {
//Add "screen" media to show on screen
styleSheet.media.appendMedium("screen");
}
// Get the CSS rules in a cross-browser compatible way
var rules;
try {
rules = styleSheet.cssRules;
} catch (error) {
console.log(error);
}
try {
rules = styleSheet.rules;
} catch (error) {
console.log(error);
}
// Handle cases where styleSheet.rules is null
if (!rules) {
continue;
}
//Second, loop through all the rules in a stylesheet
for (var ruleNo = 0; ruleNo < rules.length; ruleNo++) {
//Current rule
var rule = rules[ruleNo];
//Hide screen-only rules
if (hasMedia(rule.media, "screen") && !hasMedia(rule.media, "print")) {
//Rule.disabled doesn't work here, so we remove the "screen" rule and add the "print" rule so it isn't shown
console.info('Rule.media:');
console.log(rule.media)
rule.media.appendMedium(':not(screen)');
rule.media.deleteMedium('screen');
console.info('Rule.media after tampering:');
console.log(rule.media)
}
//Display "print" rules
if (!hasMedia(rule.media, "screen") && hasMedia(rule.media, "print")) {
//Add "screen" media to show on screen
rule.media.appendMedium("screen");
}
}
}
})()
You can see it in action at JSFiddle.
Bookmarklet
You can also install it as a bookmarklet.
More information:
About mediaList
About document.styleSheets
Note: I've only tested this in Google Chrome and Mozilla Firefox. It may or may not work in other browsers.
There is some cases that it can be useful to use visual automation tools such as applitools.
We implements it in some of our tests, and it's great so far.
//jquery
function printDetail() {
window.print();
}
//html
<button type="button" class="btn" value="Print Div" onclick="printDetail()"><i class="icon-print"></i> Print</button>
//css
#media print{
.header{display:none;}
.footer{display:none;}
.leftside{display:none;}
.rightside{display:block;}
}
// http://jsfiddle.net/kisspa/52H7g/
I think I have a little clever way to accomplish this:
Can I assume that the PRINT button is going to be on the html page as is the case in the jsfiddle.net link above?
Basically, can I EXCLUDE the FILE->PRINT or RIGHT CLICK->PRINT options and only assume that the only way someone can print your page is by clicking on a print button embedded in your html page as shown in the jsfiddle link above if not what are other test cases?
Finally, can I assume that your selenium tests will ONLY run in the Chrome browser and not firefox? This is important because the PRINT command behaves different in Chrome as it does in Firefox. My fix will only work w/ Chrome.

Modernizer JS Media Query check. Load / Unload

I am working on a code that checks if the browser supports Media Queries. If it does, it then checks the window width and if it falls under 700px it loads a CSS file, but if the window width resizes and goes back to something wider than 700px, the CSS file does not "unload" and thus, it looks bad. Can you please help me understand what and how is the best way to use this?
Here's my code:
function check_media_query_support() {
if (!Modernizr.mq('only all')) {
if ($(window).width() <= 700) {
Modernizr.load({
load:'../styles/jquery-ui/test_unsupported_mq_700.css'
});
} else {
}
if ($(window).width() <= 400) {
Modernizr.load({
load: '../styles/jquery-ui/test_unsupported_mq_400.css'
});
}
}
}
function resizeUi() {
check_media_query_support();
}
Modernizr won't listen to window size changes, with the functionality you are looking for, you actually probably want a responsive polyfill, like respond.js

Changing size and content of header at scrolling in browser with CSS

Any idea how to make such a thing as seen here http://studiompls.com/case-studies/crown-maple/
Header goes smaller and logo changes to different button. Can it be done with CSS without writing any JS?
Cheers!
Update:
if JS is a must, any link you can recommend to learn? Thanks.
Easy use jquery:
$(window).scroll(function(){
if($(window).scrollTop() >= $('.header').outerHeight()) {
// put content here for if the page has scrolled 200 pixels
}
});
Make sure you have a js file though
You can do it with jquery.
It's pretty easy.
Here's a demo: http://jsfiddle.net/jezzipin/JJ8Jc/
$(function(){
$('#header_nav').data('size','big');
});
$(window).scroll(function(){
if($(document).scrollTop() > 0)
{
if($('#header_nav').data('size') == 'big')
{
$('#header_nav').data('size','small');
$('#header_nav').stop().animate({
height:'40px'
},600);
}
}
else
{
if($('#header_nav').data('size') == 'small')
{
$('#header_nav').data('size','big');
$('#header_nav').stop().animate({
height:'100px'
},600);
}
}
});
I made a fiddle that only uses CSS, no Javascript, to achieve roughly the same effect: the header grows smaller when you scroll down past the first section, and its icon changes. And of course when you scroll back up, the header grows again and gets its old icon back. Done with nothing more esoteric than a couple of :hovers (and a transition, but that's just icing; it works on non-transition-aware browsers).
This may not be exactly what you are after, but you can use it as a fallback in case the user has Javascript switched off.
Here is whole tutorial on that effect and I don't think it is possible to do it without js 'cause you need to checking on scroll, and do toggleClass with jQueryUI for example or something :)
hope it helps ;)
Cheers
Since you need to style the inner element of navigation it will be better to add
class on navigation to style inner items
<div class="outer">
<div id="menu">addd</div>
and js
$(window).scroll(function () {
var sc = $(window).scrollTop();
if (sc > 50) {
$("#menu").addClass("big");
} else {
$("#menu").removeClass("big");
}
});
and finally css
#menu {
position:fixed;
height:50px;
background:#ccc;
left:0;
top:0;
float:left;
width:100%;
}
.outer {
height:800px;
}
#menu.big {
height:20px;
}
here is the link

onfocus="this.blur();" problem

// I am trying to apply an "onfocus="this.blur();"" so as to remove the dotted border lines around pics that are being clicked-on
// the effect should be applied to all thumb-nail links/a-tags within a div..
// sudo code (where I am):
$(".box a").focus( // so as to effect only a tags within divs of class=box | mousedown vs. onfocus vs. *** ?? | javascript/jquery... ???
function ()
{
var num = $(this).attr('id').replace('link_no', '');
alert("Link no. " + num + " was clicked on, but I would like an onfocus=\"this.blur();\" effect to work here instead of the alert...");
// sudo bits of code that I'm after:
// $('#link_no' + num).blur();
// $(this).blur();
// $(this).onfocus = function () { this.blur(); };
}
);
// the below works for me in firefox and ie also, but I would like it to effect only a tags within my div with class="box"
function blurAnchors2()
{
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
a[i].onfocus = function () { this.blur(); };
}
}
}
Thanks guys - I have gone for the css(a:focus):
img, a:focus{
outline: none;
}
It seems to be working right(tabbing is still working and the borders are gone when clicking) for me... in both ie and firefox. Will have to now retrofit some other links to use it...
Thanks again.
It's not recommended to blur. If all you're looking at doing is hiding the focus lines, use this instead:
a[i].onfocus = function () { this.hideFocus = true; };
This will work for all versions of IE. For other browsers (including IE8 in standards mode) you can set the outline CSS style to hide focus outlines:
a {
outline: none;
}
This would make your page much more keyboard friendly than blurring an element as it takes focus.
I would suggest using only CSS to remove the border.
img, a:active{
outline: none;
}
Or is there a specific reason why JS must be used?

Resources