Does @media only screen only allow browser access one block of code at a time

Hi,
I have this block of css code:


/* Smartphones (portrait) ----------- */
@media only screen 
and (max-width : 320px) {
	.feature img {
		width: 250px;
		height: 125px;
	}
	.new_feature img {
		width: 300px;
		height: 150px;
	}
}

/* iPads (portrait and landscape) ----------- */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) {
	.feature img {
		width: 500px;
		height: 250px;
	}
	.new_feature img {
		width: 600px;
		height: 300px;
	}
}

And I access them with this JavaScript function to allow user change classes on the fly:


function getCssProperty(elmId, property){
   var elem = document.getElementById(elmId);
   return window.getComputedStyle(elem,null).getPropertyValue(property);
}
// get css class value
var width = getCssProperty("my-div", "width");
var height = getCssProperty("my-div", "height");

I’m asking this because I can’t afford more than one computer to test my app at the time. And since it is under development, I can’t afford to test on online tools either.

Thank you,

You can have as many @media rules applying simultaneously as you like. But those two you posted are mutually exclusive. The viewport width is either in the 0–320px range, the 768–1024px range, or neither. But it can’t be both at once. :slight_smile:

Thank you, but I don’t quite understand this.
Do you mean when user view it on the iPad, the old class width would be 500px and the new class width would be 600px.
And they will not get a class width of 250px and 300px respectively.

Here’s the code I change class when user tap on a screen:


var oldClass = function() {
	var width = getCssProperty("my-div", "width");
	var height = getCssProperty("my-div", "height");
}
oldClass();

var newClass = function() {
	document.getElementById('my-div').className = 'new_feature';
	var width = getCssProperty("my-div", "width");
	var height = getCssProperty("my-div", "height");
}

It works great for one screen, but I’ve have no idea how to apply to many @media screen.
Thank you

I may be missing something obvious, but I’m not sure what you are trying to do here. What is the purpose of the JS?

Do you mean when user view it on the iPad, the old class width would be 500px and the new class width would be 600px.
And they will not get a class width of 250px and 300px respectively.

On an iPad, the second set of styles will automatically apply, and on an iPhone the first set of styles will apply. You don
t’t have to do anything to make that happen. The browser applies whatever styles match the screen width of the device.

Thank you,
Your part is clear.
For my part, I want to change a css class dynamically with javascript. It would happen on canvas.
This is the only way to get the result displayed as expect on canvas. Otherwise, it would look ugly like this: http://stackoverflow.com/questions/2588181/canvas-is-stretched-when-using-css-but-normal-with-width-height-properties

I want to make sure that javascript get the right value for the right device screen.
Hope you understand.

Well, It seems I should get screen size for JavaScript determination with this method: http://responsejs.com/labs/dimensions/

Off Topic:

OK, this seems more like a JS issue, so I’ve moved this thread to the JS forum. :slight_smile:

Hi,

I’m a bit confused what the actual question here is.
@ketting00 ;, could you reiterate what you are trying to achieve?

Well, I want to render image (still and motion) on a canvas. the best way you can do is setting attributes like this one:


<canvas id=c width=500 height=250></canvas>

If you set the width and the height with css like this:


#c {
   width: 500px;
   height: 250px;
}

And when you render image with javascript like this:


ctx.drawImage(image, 0, 0, 500, 250);

The image you render would be distorted, because, in this case, javascript 500px does not equal to css 500px like in an example on stackoverflow thread above.
So, it is not the ideal for responsive design.

However, I’m able to solve this with the getCssProperty function above. Now that javascript width is equal to css width.
The image is rendered in a proper scale.

Now that I have no idea which block of css styling code my getCssProperty function is pulling form. It could be either form [@media only screen and (max-width : 320px)] block or from [@media only screen and (min-device-width : 768px) and (max-device-width : 1024px)] block. This is just a few.

So, this is the question I’m trying to solve.
Hope I make myself clear.

Yup. With you.

Ok.

So, are you asking how the browsers evaluate and apply media queries, so that you can determine where the width of your canvas element is being set?

Exactly! Thank you.

Well, to answer that, as far as I know, the rules are applied in the order they are matched.

So, for example if you have:

@media only screen and (max-width : 768px) {
  body{ background: blue; }
}

@media only screen and (max-width : 1024px) {
  body{ background: red; }
}

And you view your page on a device with a width of 320px, then the background will be red (as that was matched last).

@media only screen and (max-width : 1024px) {
  body{ background: red; }
}

@media only screen and (max-width : 768px) {
  body{ background: blue; }
}

Same screen, different media query order, the background will be blue.

You can override this with specifity or with !important.

E.g.

@media only screen and (max-width : 1024px) {
  body{ background: red; !important }
}

@media only screen and (max-width : 768px) {
  body{ background: blue; }
}

or

@media only screen and (max-width : 1024px) {
  html > body{ background: red; }
}

@media only screen and (max-width : 768px) {
  body{ background: blue; }
}

should turn the background red.

Other than that, just experiment (you could use the Web Developer plugin for Chrome to view multiple screen resolutions on one page).

If you can post a simple example demonstrating your problem, I would be happy to take a look.

OK. This is working code [not optimized yet]:
HTML:


<canvas id=canvas class=ccc></canvas>

CSS:


/* Smartphones (portrait) ----------- */
@media only screen 
and (max-width : 320px) {
	.ccc {
		width: 300px;
		height: 150px;
		background: red;
	}
}

/* iPads (portrait and landscape) ----------- */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) {
	.ccc {
		width: 680px;
		height: 480px;
		background: green;
	}
}

JS:


var video = document.createElement('video')
  , canvas = document.getElementById('canvas')
  , ctx = canvas.getContext('2d')
  ;

window.addEventListener('load', function() {
	video.src = 'my_video.ogg';
	video.play();
	playVideo(video);
});

function getCssProperty(elmId, property){
   var elem = document.getElementById(elmId);
   return window.getComputedStyle(elem,null).getPropertyValue(property);
}

var w = getCssProperty("canvas", "width");
var h = getCssProperty("canvas", "height");

var width = parseInt(w);
var height = parseInt(h);

var playVideo = function(video) {
	this.video = video;
	(function paintCanvas(video) {
		window.webkitRequestAnimationFrame(paintCanvas);
		ctx.drawImage(this.video, 0, 0, width, height);
	})();
}

In real life, I switching back and forth between video playlists and still images to display on one canvas. So there is no need to refresh page.

PS. I only has one computer. I’m not able to test on different screens.

Hi,

I’ll have a look at this later.
In the meantime you might want to check out the Chrome extension I linked to before.
It allows you to view multiple screen resolutions on one page

Hi,

I just tested this and for me it works as expected.
I had to change min-device-width and max-device-width into min-width and max-width, so that I could test on my desktop, but the canvas gets resized at the correct points.

It’s worth noting that when I resized the view port from small to large, the video became quite pixelated, but this has nothing to do with how the mdeia queries are applied.

Also, as noted in this thread, it is a bad idea to use CSS to resize your canvas (as it causes this blurry look).

Thanks to know that it works as expected.
As I said I have no problem with this pixelate-thingy :). This technique can solve it: http://www.html5rocks.com/en/tutorials/canvas/performance/

Luckily you can have as many canvas as you like on a single page.

All of my concern is to make sure that javascript pulls the right code of block for the right device’s screen.
Thank you,

Or, you just use:


canvas.width = width;
canvas.height = height;

and


ctx.drawImage(this.video, 0, 0, canvas.width, canvas.height);

To fix that.

Hi,

Yeah, but your JavaScript is referencing whatever styles are currently being applied by the browser.

function getCssProperty(elmId, property){
   var elem = document.getElementById(elmId);
   return window.getComputedStyle(elem,null).getPropertyValue(property);
}

This code is media query agnostic.

When you do this:

var width = getCssProperty("canvas", "width");

it will return return the final used value of the CSS width property of your canvas element.

Update: I’m able to borrow my friends’ computers for testing. It works.

[chrome] Browser is smarter than I thought.