img with srcset attribute looks like a great way of doing responsive images. Is there an equivalent syntax that works in css background-image property?
HTML
<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="yah">
CSS
.mycontainer {
background: url('what goes here?');
}
image-set is the equivalent CSS feature. We should add equivalent srcset functionality (defining resources according to their dimensions) to the spec.
Currently implemented in all major Browsers (Firefox, Chrome, Safari, Edge) with the -webkit- prefix. Safari only supports supports the x descriptors.
Another approach, which is quite frankly more robust, would be to adapt the characteristics and options of background images to an image with the srcset attribute.
To do this, set the image to be width: 100%; height: 100%; and object-fit: cover or contain.
Here is an example:
.pseudo-background-img-container {
position: relative;
width:400px;
height: 200px;
}
.pseudo-background-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="pseudo-background-img-container">
<img class="pseudo-background-img" src="https://cdn3.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep.jpg" srcset="https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep.jpg 640w, https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep-280x175.jpg 280w, https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep-432x270.jpg 432w, https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep-216x135.jpg 216w" sizes="(max-width: 640px) 100vw, 640px">
</div>
This may not be the best approach for everyone but I imagine it will get most the desired results without any javascript workaround.
Pretty sure that:
background: -webkit-image-set( url('path/to/image') 1x, url('path/to/high-res-image') 2x );
works the same way. The browser will examine the images, see which fits best and will use that one.
You can use media queries for your purpose. It's easy as this:
.mycontainer {
background-image:url("img/image-big.jpg"); // big image
}
#media(max-width: 768px){
.mycontainer {
background-image:url("img/image-sm.jpg"); // small image
}
}
And I think it works on every browser who support media queries ;)
For a polyfill, you can use an img with srcset as a mechanism for downloading the correct image size, then use JS to hide it and set the background-image of a parent element.
Here's a fiddle: http://jsbin.com/garetikubu/edit?html,output
The use of onload and putting the JS as a blocking script in the <head> is important. If you put the script later (say at the end of <body>), you can get a race condition where img.currentSrc hasn't been set yet by the browser. It's best to wait for it to be loaded.
The example allows you to see the original img being downloaded. You can easily hide it with some CSS.
Similar solution using <picture> element:
Tutorial here
Tutorial's case:
I’m doubtful that if I use the same image for a smaller screen size,
the primary subject of my image may become too small in size. I want
to display a different image (more focused on the primary subject) in
a different screen size, but I still want to display separate assets
of the same image based on device-pixel ratio, and I want to customize
height and width of the image based on viewport.
Example code:
<picture>
<source media="(max-width: 20em)" srcset="images/small/space-needle.jpg 1x,
images/small/space-needle-2x.jpg 2x, images/small/space-needle-hd.jpg 3x">
<source media="(max-width: 40em)" srcset="images/medium/space-needle.jpg 1x,
images/medium/space-needle-2x.jpg 2x, images/medium/space-needle-hd.jpg 3x">
<img src="space-needle.jpg" alt="Space Needle">
</picture>
From 2021 onwards image-set() should be used for this purpose, according to CSSTricks.
Here's the full snippet that it recommends using for support of all modern browser versions:
.hero {
/* Fallback */
background-image: url("platypus.png");
/* Chrome/Edge/Opera/Samsung, Safari will fallback to this as well */
background-image: -webkit-image-set(url("platypus.png") 1x, url("platypus-2x.png") 2x);
/* Standard use */
background-image: image-set(url("platypus.png") 1x, url("platypus-2x.png") 2x);
}
If you are using Foundation framework (https://foundation.zurb.com/), you can use Interchange plugin for that:
<div data-interchange="[assets/img/interchange/small.jpg, small],
[assets/img/interchange/medium.jpg, medium],
[assets/img/interchange/large.jpg, large]">
</div>
https://foundation.zurb.com/sites/docs/interchange.html#use-with-background-images
Based on #Weston's answer, I've built a more general jQuery solution, you can basically just copy&paste the JS and CSS and focus on the HTML part ;)
TL;DR - fiddle: https://jsfiddle.net/dpaa7oz6/
CSS
...to ensure images will be hardly visible while loading
.srcSet{
position: fixed;
z-index: 0;
z-index: -1;
z-index: -100;
/* you could probably also add visibility: hidden; */
}
JS / jQuery
This script will go through all images that have srcSet class and bind load event that takes currentSrc (or src if not supported) and puts it as a background-image CSS to the closest parent with bgFromSrcSet class.
That itself would not be enough! So it also puts an interval checker on window load event to test if the load events have been completed, if not, it triggers them. (img load event is very often trigger only on first-time load, on following loads, image source could be retrieved from cache, resulting in img load event NOT being fired!)
jQuery(function($){ //ON DOCUMENT READY
var $window = $(window); //prepare window as jQuery object
var $srcSets = $('.srcSet'); //get all images with srcSet clas
$srcSets.each(function(){ //for each .srcSet do...
var $currImg = $(this); //prepare current srcSet as jQuery object
$currImg
.load(function(){ //bind the load event
var img = $currImg.get(0); //retrieve DOM element from $currImg
//test currentSrc support, if not supported, use the old src
var src = img.currentSrc ? img.currentSrc : img.src;
//To the closest parent with bgFromSrcSet class,
//set the final src as a background-image CSS
$currImg.closest('.bgFromSrcSet').css('background-image', "url('"+src+"')");
//remove processed image from the jQuery set
//(to update $srcSets.length that is checked in the loadChecker)
$srcSets = $srcSets.not($currImg);
$currImg.remove(); //remove the <img ...> itself
})
;
});
//window's load event is called even on following loads...
$window.load(function(){
//prepare the checker
var loadChecker = setInterval(function(){
if( $srcSets.length > 0 ) //if there is still work to do...
$srcSets.load(); //...do it!
else
clearInterval(loadChecker); //if there is nothing to do - stop the checker
}, 150);
});
});
HTML
...could look like this:
<div class="bgFromSrcSet">
<img class="srcSet"
alt=""
src="http://example.com/something.jpeg"
srcset="http://example.com/something.jpeg 5760w, http://example.com/something-300x200.jpeg 300w, http://example.com/something-768x512.jpeg 768w, http://example.com/something-1024x683.jpeg 1024w, http://example.com/something-1000x667.jpeg 1000w"
sizes="(max-width: 2000px) 100vw, 2000px"
>
Something else...
</div>
Note: class bgFromSrcSet must not be set to the img itself! It can only be set to the elements in the img DOM parent tree.
I have used the Lazysizes plugin called bg-set for adding responsiveness to background images. It works similarly as srcset does and provides a set of multiple background images based on the device width.
<div class="lazyload" data-bgset="image-200.jpg 200w, image-300.jpg 300w, image-400.jpg 400w" data-sizes="auto">
The images in the data-bgset are the same, we are just providing the width specified image which the browser will be able to choose from.
Related
I need to dynamically load banner images into a HTML5 app and would like a couple of different versions to suit the screen widths. I can't correctly determine the phone's screen width, so the only way I can think of doing this is to add background images of a div and use #media to determine the screen width and display the correct image.
For example:
<span style="background-image:particular_ad.png; #media (max-width:300px){background-image:particular_ad_small.png;}"></span>
Is this possible, or does anyone have any other suggestions?
#media at-rules and media queries cannot exist in inline style attributes as they can only contain property: value declarations. As the spec puts it:
The value of the style attribute must match the syntax of the contents of a CSS declaration block
The only way to apply styles to one specific element only in certain media is with a separate rule in your stylesheet (be it linked externally or internally in a <style> element), which means you'll need to come up with a selector for it. You can grab one using your browser's dev tools, or figure out a class and/or ID combination that isolates this element:
#myelement { background-image: url(particular_ad.png); }
#media (max-width: 300px) {
#myelement { background-image: url(particular_ad_small.png); }
}
If you're unable to find a selector that will reliably match this element alone due to the nature of your page, you can use a custom property, provided you don't need to worry about specificity or Internet Explorer:
:root { --particular-ad: url(particular_ad.png); }
#media (max-width: 300px) {
:root { --particular-ad: url(particular_ad_small.png); }
}
<span style="background-image: var(--particular-ad);"></span>
Problem
No, Media Queries cannot be used in this way
<span style="#media (...) { ... }"></span>
Solution
But if you want provided a specific behavior usable on the fly AND responsive, you can use the style markup and not the attribute.
e.i.
<style scoped>
.on-the-fly-behavior {
background-image: url('particular_ad.png');
}
#media (max-width: 300px) {
.on-the-fly-behavior {
background-image: url('particular_ad_small.png');
}
}
</style>
<span class="on-the-fly-behavior"></span>
See the code working in live on CodePen
In my Blog for example, I inject a <style> markup in <head> just after <link> declaration for CSS and it's contain the content of a textarea provided beside of real content textarea for create extra-class on the fly when I wrote an artitle.
Note : the scoped attribute is a part of HTML5 specification. If you do not use it, the validator will blame you but browsers currently not support the real purpose : scoped the content of <style> only on immediatly parent element and that element's child elements. Scoped is not mandatory if the <style> element is in <head> markup.
UPDATE: I advice to always use rules in the mobile first way so previous code should be:
<style scoped>
/* 0 to 299 */
.on-the-fly-behavior {
background-image: url('particular_ad_small.png');
}
/* 300 to X */
#media (min-width: 300px) { /* or 301 if you want really the same as previously. */
.on-the-fly-behavior {
background-image: url('particular_ad.png');
}
}
</style>
<span class="on-the-fly-behavior"></span>
Inline styles cannot currently contain anything other than declarations (property: value pairs).
You can use style elements with appropriate media attributes in head section of your document.
Yes, you can write media query in inline-css if you are using a picture tag. For different device sizes you can get different images.
<picture>
<source media="(min-width: 650px)" srcset="img_pink_flowers.jpg">
<source media="(min-width: 465px)" srcset="img_white_flower.jpg">
<img src="img_orange_flowers.jpg" alt="Flowers" style="width:auto;">
</picture>
If you are using Bootstrap Responsive Utilities or similar alternative that allows to hide / show divs depending on the break points, it may be possible to use several elements and show the most appropriate. i.e.
<span class="hidden-xs" style="background: url(particular_ad.png)"></span>
<span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Media Queries in style-Attributes are not possible right now.
But if you have to set this dynamically via Javascript.
You could insert that rule via JS aswell.
document.styleSheets[0].insertRule("#media only screen and (max-width : 300px) { span { background-image:particular_ad_small.png; } }","");
This is as if the style was there in the stylesheet. So be aware of specificity.
Hey I just wrote it.
Now you can use <div style="color: red; #media (max-width: 200px) { color: green }"> or so.
Enjoy.
I tried to test this and it did not seem to work but I'm curious why Apple is using it. I was just on https://linkmaker.itunes.apple.com/us/ and noticed in the generated code it provides if you select the 'Large Button' radio button, they are using an inline media query.
<a href="#"
target="itunes_store"
style="
display:inline-block;
overflow:hidden;
background:url(#.png) no-repeat;
width:135px;
height:40px;
#media only screen{
background-image:url(#);
}
"></a>
note: added line-breaks for readability, original generated code is minified
yes,you can do with javascript by the window.matchMedia
desktop for red colour text
tablet for green colour text
mobile for blue colour text
//isat_style_media_query_for_desktop_mobile_tablets
var tablets = window.matchMedia("(max-width: 768px)");//for tablet devices
var mobiles = window.matchMedia("(max-width: 480px)");//for mobile devices
var desktops = window.matchMedia("(min-width: 992px)");//for desktop devices
isat_find_device_tablets(tablets);//apply style for tablets
isat_find_device_mobile(mobiles);//apply style for mobiles
isat_find_device_desktops(desktops);//apply style for desktops
// isat_find_device_desktops(desktops,tablets,mobiles);// Call listener function at run time
tablets.addListener(isat_find_device_tablets);//listen untill detect tablet screen size
desktops.addListener(isat_find_device_desktops);//listen untill detect desktop screen size
mobiles.addListener(isat_find_device_mobile);//listen untill detect mobile devices
// desktops.addListener(isat_find_device_desktops);
// Attach listener function on state changes
function isat_find_device_mobile(mob)
{
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="blue";
// isat mobile style here
}
function isat_find_device_desktops(des)
{
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="red";
// isat mobile style here
}
function isat_find_device_tablets(tab)
{
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="green";
// isat mobile style here
}
//isat_style_media_query_for_desktop_mobile_tablets
<div id="daynight">tricky style for mobile,desktop and tablet</div>
You can use image-set()
<div style="
background-image: url(icon1x.png);
background-image: -webkit-image-set(
url(icon1x.png) 1x,
url(icon2x.png) 2x);
background-image: image-set(
url(icon1x.png) 1x,
url(icon2x.png) 2x);">
Inline media queries are possible by using something like Breakpoint for Sass
This blog post does a good job explaining how inline media queries are more manageable than separate blocks: There Is No Breakpoint
Related to inline media queries is the idea of "element queries", a few interesting reads are:
Thoughts on Media Queries for Elements
Media Queries are a Hack
Media Queries Are Not The Answer: Element Query Polyfill
if else blocks
if you add the rule to the print.css file you don't have to use #media.
I uncluded it in the smarty foreach i use to give some elements a background color.
<script type='text/javascript'>
document.styleSheets[3].insertRule(" #caldiv_<?smarty $item.calendar_id ?> { border-color:<?smarty $item.color ?> }", 1);
</script>
It's crazy they didn't think of media queries at HTML level, as obviously style css gets loaded after html, it's a huge disadvantage to inlining style inside html.
Yes, this is quite possible but only as using javascript event attributes in HTML elements. Here you have to keep in mind that not every html tag element could fire every js event, which can listen for changes to the DOM, such as onresize or execute js code, when DOM is loaded, as onload event does. In the example above I use body and img tags as they are capable to fire img only onload event, body tag both onload and onresize. Depending on the event, you could choose the approach to resolve your issue, as using the code from the examples.
Using a body tag:
<body onload="
const mediaQueryList = window.matchMedia('(max-width: 600px)');
function screenTest(e) {
if (e.matches) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
console.log('This is a wide screen — more than 600px wide.');
document.body.style.backgroundColor = 'aquamarine';
}
}
mediaQueryList.addEventListener('change', screenTest);
" onresize="
if (document.documentElement.offsetWidth <= 600) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
console.log('This is a wide screen — more than 600px wide.');
document.body.style.backgroundColor = 'aquamarine';
}
"><!-- Some other code goes here --></body>
Using img tag:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
width="100%" style="width: 100vw; height: 1px;"
alt="" height="1"
onload="
const mediaQueryList = window.matchMedia('(max-width: 600px)');
function screenTest(e) {
if (e.matches) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
console.log('This is a wide screen — more than 600px wide.');
document.body.style.backgroundColor = 'aquamarine';
}
}
mediaQueryList.addEventListener('change', screenTest);
" />
You should also keep in mind that if you decide to use this way of embedding mediaquery css in an HTML letter, it may not pass through the blacklists of mail servers, which in most cases cut such javascript events. But for the purposes of some ajax or banner, some dynamic application, this approach should face no problem.
I'm working on a web game that's playable on both desktop and mobile. Playing on mobile devices requires the user to play in landscape mode.
I did a simple check on device orientation via width versus height, and I'm supposed to show an image telling the player to rotate the device. So I added this to the html file:
<div id="rotateWarning"><img src="res/plsRotate.png" style="width: 100%; height: auto;"></div>
This has the problem of showing the image by default. The user would have to rotate the phone to portrait mode if it were in landscape mode, and back again. Worse, it also shows by default on Desktop browsers, and there's no way to rotate that. The code does work though, hiding the image when it's rotated the right way.
So the alternative is to set it to display: none by default, right?
The problem with that is that it never shows. It seems once set to display: none, it ignores every attempt to change it.
Is there anything I can do to fix this? Alternatively, is there a better way to implement this idea?
Edit:
Here's my HTML file:
<script>
window.addEventListener('resize', onSizeChange);
</script>
And here's my function:
function onSizeChange() {
if (getMobileOperatingSystem) {
if (window.outerHeight > window.outerWidth) {
document.getElementById('rotateWarning').style.display = 'block';
document.getElementById('logInPages').style.display = 'none';
} else {
console.log("Landscape!");
document.getElementById('rotateWarning').style.display = 'none';
document.getElementById('logInPages').style.display = 'block';
}
}
}
You can make use of the orientation media feature to hide and show the relevant element based on the orientation of the device. You'll want to hide the element by default, and show the element for portrait orientations. The element will re-display for portrait devices due to increased specificity.
#rotateWarning {
display: none;
}
#media only screen and (orientation: portrait) {
#rotateWarning {
display: block;
}
}
<div id="rotateWarning">
<img src="res/plsRotate.png" style="width: 100%; height: auto;">
</div>
I know there are similar questions, all of them are old, and I was wondering maybe there are newer techniques.
I have the following HTML:
<figure class="main-slider__slide">
<img class="main-slider__image" src="http://smth.com/a.jpg" alt="test">
</figure>
What I need is the figure container keeping the room for the img while it's not loaded yet. Without the container keeping the space I end up with twitching content which feels awful.
So far I've came up with the following SASS mixin:
#mixin image-placeholder($x,$y, $image-wrapper-class,$image-class) {
.#{$image-wrapper-class} {
position: relative;
padding-bottom: percentage($y/$x);
}
.#{$image-class} {
position: absolute;
}
}
Being applied like #include image-placeholder(1170, 405, main-slider__slide, main-slider__image); it generates CSS like
.main-slider__slide {
position: relative;
padding-bottom: 34.61538%;
}
.main-slider__image {
position: absolute;
}
The problem is that I have to hardcore the size of my images in the styles and have a separate class for every image of with certain dimensions. Do you guys know better solutions where one general placeholder class would resolve the problem?
As I wrote into comment above - I doubt that there is general solution that will allow you to obtain information about not-yet-loaded element.
However it may be possible to mimic such behavior.
One thing that came in mind is to have tiny resized version of the image to be loaded to be inlined into document and then replaced by actual image upon page load. E.g. your 1170x405 image can be squeezed by 20x factor to 50x20 that will give you ~1kb of image size in jpeg. This image may be stored as <img src="data:" class="image-placeholder"> directly into document and act as a temporary replacement for your actual image. You can scale it to original size using CSS and load original image either by JavaScript or by allowing browser to load it without displaying or by putting it immediately over placeholder. It can be also useful to apply filter: blur(10px) or something like this to image placeholder so it will not look ugly. Actually you can even animate this filter value to provide pleasant visual transition from scaled down placeholder towards original image.
I've used such approach into one of my projects and it was working well.
Hope it will help you.
I need to dynamically load banner images into a HTML5 app and would like a couple of different versions to suit the screen widths. I can't correctly determine the phone's screen width, so the only way I can think of doing this is to add background images of a div and use #media to determine the screen width and display the correct image.
For example:
<span style="background-image:particular_ad.png; #media (max-width:300px){background-image:particular_ad_small.png;}"></span>
Is this possible, or does anyone have any other suggestions?
#media at-rules and media queries cannot exist in inline style attributes as they can only contain property: value declarations. As the spec puts it:
The value of the style attribute must match the syntax of the contents of a CSS declaration block
The only way to apply styles to one specific element only in certain media is with a separate rule in your stylesheet (be it linked externally or internally in a <style> element), which means you'll need to come up with a selector for it. You can grab one using your browser's dev tools, or figure out a class and/or ID combination that isolates this element:
#myelement { background-image: url(particular_ad.png); }
#media (max-width: 300px) {
#myelement { background-image: url(particular_ad_small.png); }
}
If you're unable to find a selector that will reliably match this element alone due to the nature of your page, you can use a custom property, provided you don't need to worry about specificity or Internet Explorer:
:root { --particular-ad: url(particular_ad.png); }
#media (max-width: 300px) {
:root { --particular-ad: url(particular_ad_small.png); }
}
<span style="background-image: var(--particular-ad);"></span>
Problem
No, Media Queries cannot be used in this way
<span style="#media (...) { ... }"></span>
Solution
But if you want provided a specific behavior usable on the fly AND responsive, you can use the style markup and not the attribute.
e.i.
<style scoped>
.on-the-fly-behavior {
background-image: url('particular_ad.png');
}
#media (max-width: 300px) {
.on-the-fly-behavior {
background-image: url('particular_ad_small.png');
}
}
</style>
<span class="on-the-fly-behavior"></span>
See the code working in live on CodePen
In my Blog for example, I inject a <style> markup in <head> just after <link> declaration for CSS and it's contain the content of a textarea provided beside of real content textarea for create extra-class on the fly when I wrote an artitle.
Note : the scoped attribute is a part of HTML5 specification. If you do not use it, the validator will blame you but browsers currently not support the real purpose : scoped the content of <style> only on immediatly parent element and that element's child elements. Scoped is not mandatory if the <style> element is in <head> markup.
UPDATE: I advice to always use rules in the mobile first way so previous code should be:
<style scoped>
/* 0 to 299 */
.on-the-fly-behavior {
background-image: url('particular_ad_small.png');
}
/* 300 to X */
#media (min-width: 300px) { /* or 301 if you want really the same as previously. */
.on-the-fly-behavior {
background-image: url('particular_ad.png');
}
}
</style>
<span class="on-the-fly-behavior"></span>
Inline styles cannot currently contain anything other than declarations (property: value pairs).
You can use style elements with appropriate media attributes in head section of your document.
Yes, you can write media query in inline-css if you are using a picture tag. For different device sizes you can get different images.
<picture>
<source media="(min-width: 650px)" srcset="img_pink_flowers.jpg">
<source media="(min-width: 465px)" srcset="img_white_flower.jpg">
<img src="img_orange_flowers.jpg" alt="Flowers" style="width:auto;">
</picture>
If you are using Bootstrap Responsive Utilities or similar alternative that allows to hide / show divs depending on the break points, it may be possible to use several elements and show the most appropriate. i.e.
<span class="hidden-xs" style="background: url(particular_ad.png)"></span>
<span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Media Queries in style-Attributes are not possible right now.
But if you have to set this dynamically via Javascript.
You could insert that rule via JS aswell.
document.styleSheets[0].insertRule("#media only screen and (max-width : 300px) { span { background-image:particular_ad_small.png; } }","");
This is as if the style was there in the stylesheet. So be aware of specificity.
Hey I just wrote it.
Now you can use <div style="color: red; #media (max-width: 200px) { color: green }"> or so.
Enjoy.
I tried to test this and it did not seem to work but I'm curious why Apple is using it. I was just on https://linkmaker.itunes.apple.com/us/ and noticed in the generated code it provides if you select the 'Large Button' radio button, they are using an inline media query.
<a href="#"
target="itunes_store"
style="
display:inline-block;
overflow:hidden;
background:url(#.png) no-repeat;
width:135px;
height:40px;
#media only screen{
background-image:url(#);
}
"></a>
note: added line-breaks for readability, original generated code is minified
yes,you can do with javascript by the window.matchMedia
desktop for red colour text
tablet for green colour text
mobile for blue colour text
//isat_style_media_query_for_desktop_mobile_tablets
var tablets = window.matchMedia("(max-width: 768px)");//for tablet devices
var mobiles = window.matchMedia("(max-width: 480px)");//for mobile devices
var desktops = window.matchMedia("(min-width: 992px)");//for desktop devices
isat_find_device_tablets(tablets);//apply style for tablets
isat_find_device_mobile(mobiles);//apply style for mobiles
isat_find_device_desktops(desktops);//apply style for desktops
// isat_find_device_desktops(desktops,tablets,mobiles);// Call listener function at run time
tablets.addListener(isat_find_device_tablets);//listen untill detect tablet screen size
desktops.addListener(isat_find_device_desktops);//listen untill detect desktop screen size
mobiles.addListener(isat_find_device_mobile);//listen untill detect mobile devices
// desktops.addListener(isat_find_device_desktops);
// Attach listener function on state changes
function isat_find_device_mobile(mob)
{
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="blue";
// isat mobile style here
}
function isat_find_device_desktops(des)
{
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="red";
// isat mobile style here
}
function isat_find_device_tablets(tab)
{
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="green";
// isat mobile style here
}
//isat_style_media_query_for_desktop_mobile_tablets
<div id="daynight">tricky style for mobile,desktop and tablet</div>
You can use image-set()
<div style="
background-image: url(icon1x.png);
background-image: -webkit-image-set(
url(icon1x.png) 1x,
url(icon2x.png) 2x);
background-image: image-set(
url(icon1x.png) 1x,
url(icon2x.png) 2x);">
Inline media queries are possible by using something like Breakpoint for Sass
This blog post does a good job explaining how inline media queries are more manageable than separate blocks: There Is No Breakpoint
Related to inline media queries is the idea of "element queries", a few interesting reads are:
Thoughts on Media Queries for Elements
Media Queries are a Hack
Media Queries Are Not The Answer: Element Query Polyfill
if else blocks
if you add the rule to the print.css file you don't have to use #media.
I uncluded it in the smarty foreach i use to give some elements a background color.
<script type='text/javascript'>
document.styleSheets[3].insertRule(" #caldiv_<?smarty $item.calendar_id ?> { border-color:<?smarty $item.color ?> }", 1);
</script>
It's crazy they didn't think of media queries at HTML level, as obviously style css gets loaded after html, it's a huge disadvantage to inlining style inside html.
Yes, this is quite possible but only as using javascript event attributes in HTML elements. Here you have to keep in mind that not every html tag element could fire every js event, which can listen for changes to the DOM, such as onresize or execute js code, when DOM is loaded, as onload event does. In the example above I use body and img tags as they are capable to fire img only onload event, body tag both onload and onresize. Depending on the event, you could choose the approach to resolve your issue, as using the code from the examples.
Using a body tag:
<body onload="
const mediaQueryList = window.matchMedia('(max-width: 600px)');
function screenTest(e) {
if (e.matches) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
console.log('This is a wide screen — more than 600px wide.');
document.body.style.backgroundColor = 'aquamarine';
}
}
mediaQueryList.addEventListener('change', screenTest);
" onresize="
if (document.documentElement.offsetWidth <= 600) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
console.log('This is a wide screen — more than 600px wide.');
document.body.style.backgroundColor = 'aquamarine';
}
"><!-- Some other code goes here --></body>
Using img tag:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
width="100%" style="width: 100vw; height: 1px;"
alt="" height="1"
onload="
const mediaQueryList = window.matchMedia('(max-width: 600px)');
function screenTest(e) {
if (e.matches) {
/* the viewport is 600 pixels wide or less */
console.log('This is a narrow screen — 600px wide or less.');
document.body.style.backgroundColor = 'pink';
} else {
/* the viewport is more than 600 pixels wide */
console.log('This is a wide screen — more than 600px wide.');
document.body.style.backgroundColor = 'aquamarine';
}
}
mediaQueryList.addEventListener('change', screenTest);
" />
You should also keep in mind that if you decide to use this way of embedding mediaquery css in an HTML letter, it may not pass through the blacklists of mail servers, which in most cases cut such javascript events. But for the purposes of some ajax or banner, some dynamic application, this approach should face no problem.
I apologize in advance if I am asking asking question with impossible answer. But I just thought it was worth asking, maybe somebody knows how to achieve what I am asking for.
I have image on the page like this ( image url is generated dynamically on the server by PHP ):
<img src="/images_BIG/image_12345.jpg" />
Now - I would love to use only CSS media queries to change this image URL, let's say to this ( when browser viewport width is smaller than e.g. 800px ):
<img src="/images_SMALL/image_12345.jpg" />
I know this can be done by PHP (detecting mobile browsers and return appropriate URL) or use Javascript to change URL on the fly. But is this possible with CSS3 ? I am aiming only on HTML5 browsers so no need to care about IE.
Thank you for any thoughts and help in advance.
Wrap the image in a div. Use mobile first, so that it only downloads the small version of the image on small screens. On bigger screens, the image will be hidden and a background image will be there instead.
The two downsides - a non-semantic wrapping div, and the need to specify the height and width of the div. The upside is that you get the foreground image in the HTML.
The HTML
<div class="imgContainer"><img src="/images_SMALL/image_12345.jpg" /></div>
The CSS
// for screens bigger than 800px
#media screen and (min-device-width:800px) {
div.imgContainer {
background-image:url(../images_BIG/image_12345.jpg);
background-size:100px;
width:100px;
height:100px;
}
img {
display:none;
}
}
EDIT
Based on your comment above, I would say add the wrapping div and set its background image with jQuery.
You can set a different css file depending on your media queries:
#image1 { background: url('/images_BIG/image_12345.jpg'); width: 600px; height: 200px; }
#media screen and (max-device-width: 480px) {
#image1 { background: url('/images_SMALL/image_12345.jpg'); width: 300px; height: 100px; }
}
In this case, you would move away from an IMG tag to a different tag (<span id="image1"></span>).
Well, as I have read your comment...if the only problem is including variable urls into a css stylesheet...what about just php including (rendering) the stylesheet (wrapped with <style> tag) into the resulting html? Then you could use <?php echo $imageUrl ?> at the place of the url. I have never done this before, it might be a silly idea but it just appears possible to me now.