The class is added normally on the element, and in located in the appropriate scss file. It is applied naturally in all browsers (Chrome, Opera, Safari, Firefox, Edge) except IE (I tested only for IE11).
The class just doesn't appear to have any properties initially, in dev tools. But after an action is taken in the page, it is loaded. The problem is that it initially displays the page wrong, and the quick fix that I've applied is not a good one - timeout in js and remove & add class after a very short time. This makes for a glitchy initial experience with that page, in IE.
Has anybody else experienced this?
And if so, do you have a better solution?
Thanks in advance!
// css here
.container {
width: 70%;
margin: 0 auto!important;
#media (max-width: 768px) {
width: 100%;
}
}
////////////////////////////////////////////////
// script here
function ieFixFunction() {
if (/MSIE \d|Trident.*rv:/.test(navigator.userAgent)) {
document.querySelector(".project-dashboard > div").classList.remove("container");
setTimeout(function () { document.querySelector(".project-dashboard > div").classList.add("container"); }, 0);
}
}
P.S.: I know that using !important is a big no-no
Related
I am trying to make a div's background change every 6 seconds. There are three images which are supposed to rotate and they are all referenced in CSS as background-images associated with a certain class name. The JavasScript rotates the class names on the div every six seconds.
It works in every browser except for one small problem: on the first load of the background images they all flicker. I understand that this can be prevented by pre-loading the images. Yet, I haven't found a solution which works on all "modern browsers" (Chrome, FF; Opera, Edge, Safari).
I have tried adding extra HTML markup with the same background image urls which then I didn't display with css ( display: none OR width: 0; height:0; overflow: hidden) - only worked in Chrome and Opera.
Then I tried writing a JS function which creates a new Image Object for each of the images and assigns a src attribute to them with newImg.src="something this only worked in Chrome too.
I also tried adding a <link rel="preload> and a <link rel="prefetch"> tag to the html head. Both only worked in Chrome and Opera although according to caniuse.com at least prefetch should have worked in Edge and FF too.
My current solution, which still only works in Chrome and Opera is similar to the first one I tried:
body::after {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
z-index: -1;
content: url('imgURL/Img1.jpg') url('imgURL/Img2.jpg') url('ImgURL/Img3.jpg');
}
Since this works in Chrome and Opera, I am sure I did not mistype the image URLs. Also, I clear the cache all the time, so it doesn't interfere with how the website appears to work.
The CSS:
.first{
background-image: url('...');
}
.second {
background-image: url('...');
}
.third {
background-image: url('...');
}
The JS function which is invoked in a setInterval every 6 seconds:
function changeImage() {
const page = document.getElementById('pageId');
const styleNames = ['first', 'second', 'third'];
const currentStyle = page.getAttribute('class');
const nextStyle = styleNames[styleNames.indexOf(currentStyle) + 1];
if (styleNames.indexOf(currentStyle) === styleNames.length - 1) {
page.className = styleNames[0];
} else {
page.className = nextStyle;
}
}
I would expect at least one of the above solutions to work in all browsers ( ie.: load images without flickering the first time they are displayed), but none worked perfectly and I am out of ideas... Any help is greatly appreciated. Thank you in advance.
I would like to remove the page responsiveness in Bootstrap 3 but only for versions of Internet Explorer. I have reviewed the documentation to remove page responsiveness overall, but can it be device or browser specific?
Quick and dirty javascript solution for IE8 and 9: (assumes grid size ~980)
if ( ( (/msie 8./i).test(navigator.appVersion) || (/msie 9./i).test(navigator.appVersion) ) {
var body = document.querySelector('body');
body.style.minWidth = '980px';
}
You could also accomplish this with CSS if you're setting classes on the <html> tags in IE conditionals.
Assuming <html class="ie8"> for example,
html.ie8 {
min-width : 980px;
}
html.ie8 body {
min-width : 980px;
}
An even more thorough way would be to override the #media calls with your own, targeting the ie html class again, and use css load hierarchy or the odd !important tag to get it done.
I am using a widget in my layout and I have it now so when a certain breakpoint is hit it will not display that larger widget and then goes to the smaller one. The larger widget does hide and the smaller one shows up but the text that is associated with both isn't right.
The text for the large widget displays and the smaller text for the small widget doesn't. I am pretty sure it has to do with the scripts each are using. The display none does hide the elements but the scripts seem to be still running.
I have absolutely no clue about JavaScript yet and would prefer a HTML or CSS answer if possible. If not then I will go with JS but will need some direction please. I have read numerous articles and even in the process of learning JS but still not sure how some of what I've read applies.
#media all and (max-width: 900px) {
// styles
}
if (document.documentElement.clientWidth < 900) {
// scripts
}
This is what I've found that seems like it is what I need but I'm not sure on the syntax of how to call the script I need. Do I just put the script itself in there without any other information? I have also read about using jquery to do this with something like this
$(window).resize(function() {
if ($(this).width() > 480) {
// call supersize method
}
});
And I've even read about using Modernizer to do this but I still have to go through the documentation.
In the bin it doesn't show any of the text at all but the larger text is there and off to the side of the small widget. I just need to shut that large script off and turn the other on at a certain media query.
Any help is greatly appreciated.
HTML
<aside class="smallScreen">
<div class="smallWeather" style='width: 200px; height: 440px; background-image:
url(http://vortex.accuweather.com/adcbin/netweather_v2/backgrounds/red_500x440_bg.jpg
); background-repeat: no-repeat; background-color: #993333;' ><div
id='NetweatherContainer' style='height: 420px;' ><script src='http://...'></script>
</div></div></aside>
</div></div></div></aside>
<aside class="largeScreen">
<div class="largeWeather" style='width: 500px; height: 440px; background-image:
url(http://vortex.accuweather.com/adcbin/netweather_v2/backgrounds/red_500x440_bg.jpg
); background-repeat: no-repeat; background-color: #993333;' ><div
id='NetweatherContainer' style='height: 420px;' ><script src='http://...'></script>
</div></div></aside>
CSS
#media screen and (min-width: 564px) and (max-width: 604px) {
.largeScreen {
display: none;
}
.smallScreen {
display: block;
width: 55%;
min-width: 240px;
height: 100%;
font-size: 0;
margin-left: auto;
margin-right: auto;
margin-bottom: 1.2rem;
}
.smallWeather {
position: relative;
display: block;
width: 240px;
height: 420px;
background: white;
margin-left: auto;
margin-right: auto;
}
What is the best way to do this and why please? Is jQuery the best way from a mobile performance standpoint?
UPDATE: Going to use enquire.js because of it's straightforward approach (although I'm still a bit sketchy on it's use) and how small it is.
This is the basic code:
enquire.register("screen and (max-width: 605px)", {
// OPTIONAL
// If supplied, triggered when a media query matches.
match : function() {},
// OPTIONAL
// If supplied, triggered when the media query transitions
// *from a matched state to an unmatched state*.
unmatch : function() {},
// OPTIONAL
// If supplied, triggered once, when the handler is registered.
setup : function() {},
// OPTIONAL, defaults to false
// If set to true, defers execution of the setup function
// until the first time the media query is matched
deferSetup : true,
// OPTIONAL
// If supplied, triggered when handler is unregistered.
// Place cleanup code here
destroy : function() {}
});
Still not done and looking for more support with this. Now that I've chose this route, I see that there is quite a few articles and questions already about enquire.js. I will update my situation as I read up.
UPDATE: This is where I'm at but it's not working yet. I have the styles associated with each script still in the HTML and display none used accordingly. Will doing this work once I get the enquire.js correct?
Here is the new jsbin
Thanks again for everything!!
I think you are looking for something like enquire.js, which is a lightweight JavaScript library for responding to CSS media queries.
If you don't want to use a library, this post on reacting to media queries in JavaScript runs through a way of doing what you are after with vanilla JavaScript.
Here's a jsFiddle Demo with some working example code, and here's a Fullscreen jsFiddle Demo, which is handy when trying to test how it works. If you use the fullscreen version and make the browser window less than 600px wide, a javascript alert will tell you that you have done so. Because the alert comes up, the browser will jump back to its original size and tell you that it got bigger than 600px again. So you can see, it calls the match function when it matches (so at the time of loading and at the time of resizing to a larger width), and it calls the unmatch function when resizing to a smaller width, because then the media query doesn't match any more. That's how you call a certain function only for mobile or only for desktop based on their screen size.
JS
enquire.register("screen and (min-width:600px)", {
match: function () {
alert("Now the screen width is more than 600px");
},
unmatch: function () {
alert("Now the screen width is less than 600px");
}
});
I included modernizr in my page, but how will I test that it's working in IE 6-7 if I don't have access to those browsers? Doing something similar to:
http://designshack.net/articles/css/build-a-freaking-awesome-pure-css-accordion/
The essential CSS:
.accslide {
height: 0px;
width: 0px;
overflow: hidden;
}
input[type="radio"]:checked+label ~ .accslide {
width: 100%;
height:auto;
}
If that second selector doesn't fire, the content will be invisible.
Is there a method to only load Modernizr if CSS3 is unsupported?
How do I test if Modernizr is working on my CSS selectors?
Modernizr doesn't add any functionality to the browser, simply checks for existing funcitionality. If you want to test for selector support you will need to add that. Here's a gist
However, even that isn't going to get you far for what you're trying to accomplish, which, I imagine, is showing the accslide element when you've checked the radio button. You will, most likely, need to use javascript if you expect to support IE6 & 7 -- IE6 doesn't even support the [type="radio"] selector, so you can't use that either.
You will need to add a click/change handler to the radio button and update it's container with a class to properly get your desired functionality, especially to support IE6.
Here's an example of what your CSS would look like:
#radioContainer .accslide {
height: 0px;
width: 0px;
overflow: hidden;
}
#radioContainer.on .accslide {
width: 100%;
height:auto;
}
Now, in javascript, when someone clicks/changes the radio button just add/remove an on class to the #radioContainer element. Note: I gave #radioContainer an ID b/c IE6 will not style an element from two css-class names (Ultimately, you would not be supporting IE6 and could simply provide .radio-container.on, which will not work for IE6)
Modernizr won't enable CSS features (like newer selectors) if the given browser doesn't support it. It's mainly a feature detection library.
Is there a way to detect browser support for background-attachment: fixed?
Edit: Although this feature is widely supported on desktop browsers it is poorly supported on portable devices which I why I would like to be able to detect the feature.
When you use { background-attachment:fixed } current mobile devices will not display the background image at all! To ensure the image is displayed on all mobile devices, you need to test for support, and if not supported to set the background-attachment property to either 'initial' (i.e. default state) or 'scroll' (which is the default state).
The bad news:
It's currently impossible to directly and specifically test for support of fixed backgrounds because mobile browsers will incorrectly report that they do support it. To see this bug for yourself, load this test in a mobile browser:
http://codepen.io/mattthew/pen/PwEqJa
function supportsCSS(value) {
try {
var style = document.body.style;
if (!("backgroundAttachment" in style)) return false;
var oldValue = style.backgroundAttachment;
style.backgroundAttachment = "fixed";
var isSupported = (style.backgroundAttachment === value);
style.backgroundAttachment = oldValue;
return isSupported;
}
catch (e) {
return false;
}
}
var el = document.getElementById('result');
var txt = '<b>This device & broswer supports:</b><br>';
txt += '{ background-attachment:fixed; } : ' + supportsCSS('fixed') + '<br>';
txt += { background-attachment:foo; } : ' + supportsCSS('foo');
el.innerHTML = txt;
based on code originally written by: #chao
The limited options:
It is possible to indirectly test for support with multiple methods.
Option 1: Remove fixed background on small screens
This option uses a CSS media query to target smaller screens to overwrite the style on devices with screen widths of 1024px or smaller (devices likely to render fixed backgrounds as invisible). The advantages of this option are: it's very lightweight and only requires a little bit of CSS:
#some_element {
background-attachment: fixed;
}
#media all and (max-device-width: 1024px) {
/*
overwrite property for devices with
screen width of 1024px or smaller
*/
#some_element {
background-attachment: scroll;
}
}
Unfortunately, there are a small number of tablet brands with screen widths of 1280px and 1366px, which overlap with the smallest desktop screens (sort this list by CSS Height). The safest play is to use a scrolling background for this overlap area so that the background image is guaranteed to display. If you want to play it safe, use max-device-width: 1366px. However, the number of people using these giant tablets is much smaller than the number of people with small screen laptops.
Option 2: test for touch events and mouse events
This option uses JS to test if the browser supports the touch events API, and is therefore more likely than not to be on a touch screen device (a device more likely than not to render fixed backgrounds as invisible). This is the heavy weight option. It requires Modernizr and jQuery:
if(Modernizr.touch) {
// this browser claims to support touch, so remove fixed background
$('#some_element').css('background-attachment','scroll');
}
Unfortunately, this option also has a gray area. Some browsers give a false positive and some give a false negative. You could test for a mouse event, such as:
$('body').mousemove(function(event){
// this device (touch or not) has a mouse, so revert to fixed background
$('#some_element').css('background-attachment','fixed');
$('body').unbind('mousemove');
});
However, it's possible that a mouse has been attached to a touch-screen laptop that doesn't support fixed backgrounds, so that code adds risk.
You might look at document.body.style and make sure that
there's a property there called "backgroundAttachment", and
you can set it to "fixed", and it retains its value when you do so.
Chrome, FF, Opera, and Safari all ignore attempts to set the property to an invalid value. IE9 throws an exception when you try. So if either one happens, that value definitely isn't supported. (If the browser just blindly sets the value and retains it, then it still might not work. But at that point, you really can't the browser to tell you much anyway.)
function supportsFixedBackground() {
try {
var style = document.body.style;
if (!("backgroundAttachment" in style)) return false;
var oldValue = style.backgroundAttachment;
style.backgroundAttachment = "fixed";
var isSupported = (style.backgroundAttachment === "fixed");
style.backgroundAttachment = oldValue;
return isSupported;
}
catch (e) {
return false;
}
}
I don't bother with IE6 anymore, and don't have another browser handy that doesn't support fixed backgrounds, so i'm unable to test setting "fixed".
I think I've got the solution for all devices. It's possible to detect clip-support, so I did just that and made a change in the DOM for when clip is supported. If it isn't, it falls back on background-attachment: fixed;
See the code at https://codepen.io/AartdenBraber/pen/gGmdWK
Support for any CSS property value can be detected via following steps:
create a temporary element (e.g. DIV);
set value of its style DOM property (element.style.backgroundAttachment in your case) to value to check (fixed in your case);
compare actual style value with specified string.
Something like this in your case:
var elem = document.createElement('div');
elem.style.backgroundAttachment = 'fixed';
var isSupported = 'fixed' === elem.style.backgroundAttachment;
#supports (background-attachment: fixed) will report true because the browser engine interpreted the property and value successfully. Then, mobile webkit decides to bind your background to the same stacking context (same rendering plane) as the element it is applied to for "better performance". (All z-indexes have their own stacking layer, and on desktop browsers, fixed backgrounds get their own layer.)
One could use JS to detect browsers with this rendering pattern, by checking for iPhone iPad iPod & Android in the user agent, which may target mobile browsers that render fixed backgrounds correctly, such as mobile Firefox which is constantly evolving. However, I found a better way in pure CSS:
CSS Only Solution for Mobile Safari & Chrome:
#supports (-webkit-overflow-scrolling: touch) targets all the same versions of mobile webkit that refuse to bind backgrounds to the viewport.
So with that in mind, you can fix your background by default, then append this #supports rule to apply a sort of mobile polyfill:
Example:
body {
background-image: url('bg.png');
background-size: cover; background-attachment: fixed;
}
#supports (-webkit-overflow-scrolling: touch) {
/* Detach problematic background */
body { background: none !important; }
/* Insert empty div at bottom of page */
#lonelyDiv {
position: fixed; top: 0px; left: 0px; z-index: -1;
width: 100%; height: 100%;
/* Using same background with size=cover may be possible in some situations */
background-image: url('bg.png'); background-size: cover;
/* Other designs may require a stretchable background...
or cropped versions for mobile aspect ratios applied after #media (orientation) rules */
background-image: url('mobile-bg.png'); background-size: 100%;
}
}
http://www.w3schools.com/cssref/pr_background-attachment.asp
There are pictures of the major browser icons a little bit down the page. The images aren't greyed out for any of the icons. It says that it is supported in all browsers
fixed is supported in all desktop browsers, except IE6 and older.
It is supported by most mobile browsers, but you may see some discrepencies due to viewport handling.
Source