Screen media queries overriding print rules (in Chrome) - css

Have a look at the following CodePen: http://codepen.io/anon/pen/YwYYBN (I removed non-relevant parts of the code).
At the top of the CSS is a couple media queries for resizing the slides (these are auto generated by Less). Here's an example of one:
#media only screen and (min-width: 430px) {
.slides .slide {
width: calc( 100% / 1);
}
}
Then, a little further on, is a print media query which is supposed to override it, because I always want the size of the slides to be 50% on a print:
#media print {
.slides .slide {
width: calc( 100% / 2);
color: gold;
}
}
The problem is the width in this print query is completely ignored; when printing it always uses the width defined by the currently active screen rule! You can test this by issuing a print the CodePen with different screen sizes.
The #media rule should work as far as I can see; the rule is matched print, and it also appears later in the CSS. I know it is active, because the items do change color to gold. But the width doesn't change. I've even tried making it more specific (by pointing it to body .slides .slide and adding a min-width to the query) to no avail. Even !important does not work.
Can anyone tell me what is happening here?

Ok, the problem was caused by a transition:
.slides .slide {
-webkit-transition: width 0.6s cubic-bezier(0.6, 0.65, 0.52, 0.97);
transition: width 0.6s cubic-bezier(0.6, 0.65, 0.52, 0.97);
}
The change in width actually triggered this transition, which frozen at the moment of generating the print view. After removing the transition, everything is working well.
This transition should not run however, as it's inside a print media query. I've submitted a bug report to Chromium for this and they acknowledged the issue.

Related

iOS Glitch: gap/space above 100vh body

On iOS (15.3) when using a 100vh html/body, the displayed page has a small gap/space above the body tag on first load with real iOS devices (tested on iPhone 8).
After analysing and reducing the content, it turns out that it is independent of the html markup.
Debugged this for quite some time, and finally found a fix.
Add the following code to your css. My guess is that the repaint adjusts the layout correctly. If the translateY doesn't work for you, try another way to trigger a repaint.
/* ------------------------------
iOS FIX: gap/space above body element on first load
-------------------------------- */
#media (max-width: 450px) {
#supports (display: grid) {
body {
animation: pageReflow 0.1s;
}
}
}
#keyframes pageReflow {
from {
transform: translateY(1px);
}
to {
transform: translateY(0px);
}
}

flipInX not working as expected on smaller resolutions

This problem seems to only happen on Safari (I tested on version 9.0.2).
If I scale my screen down to 565px width, or smaller, refresh the page, the <article>'s I have applied flipInX to flash on the screen and don't appear.
If I remove the margin-bottom: 40px; CSS from the <article> block, then it works.
Is this a bug in Safari?
Example
I had to add this CSS
.main {
-webkit-transform: translateZ(60px);
}

IE11 triggers css transition on page load when non-applied media query exists

I have a situation which only occurs on IE11. Chrome, Firefox, Safari (tablet and phone) all work as expected. I have created a transition for a panel(DIV) that slides in/out from the side. On pageload it should NOT "animate" but snap into the appropriate position. But on IE11 when the page loads the transition is "played" ONLY if there is a media query involved with that element matching the highest level of CSS specificity for the selector. The strange thing is that the media query is not even appropriate (should never be applied when the page is loaded in my test).
The following simple code duplicates my issue:
CSS
.standard {
transition: all 1s ease-in-out;
transform: rotate(45deg);
width:50px; height:50px; border:1px solid black; background-color:green; margin:3em;
}
button + .standard {
transform: rotate(30deg);
}
button.on + .standard {
transform:rotate(0deg);
}
/* REMOVE THE FOLLOWING COMMENTS to see issue on page load using IE11 - make sure window is larger than 800 pixels */
/*
#media only screen and (max-width:800px) {
button.on + .standard {
background-color:red;
transform:rotate(270deg);
}
}
*/
HTML
<button class="on" onclick="this.classList.toggle('on');">Rotate Test</button>
<div class="standard"> </div>
So if size of the browser window is greater than 800 pixels the media query should not be applied. However, IE11 seems to act like it applies the media query and then reverts back to the non-media query CSS which actually triggers the transition. If the media query content selector does not match the highest level of CSS specificity as defined outside the media query, the transition will not be observed on page load (in other words if my media query CSS selector was less specific [say button + .standard], you would not see the transition "played").
Any ideas how to prevent this transition from "playing" on page load using IE11 without having to write javascript?
Worked with MicroSoft support and logged a bug. There is a workaround for this issue.
Instead of using the media query
#media only screen and (max-width:800px)
change the query to be the following:
#media only screen and (min-width:1px) and (max-width:800px)
This should not be required (it should be implied) but placing the min-width in the query resolves the "PLAYING" of transition on page load. MS should fix it but since there is a workaround, the likelihood of a quick turnout is low.
Not a completely javascript free solution but you can add a class to the entire page on the body tag:
body.pageload * {
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
}
and remove that class after the page has loaded
$("window").load(function() {
$("body").removeClass("pageload");
});
The answer of user3546826 works when the window is larger than the defined max-width. When the window is smaller than the transition is still animated by IE / Edge. This can be avoided with the following workaround (just an example):
#sidebar-wrapper {
position: fixed;
width: 240px;
bottom:0;
right:0;
top:50px;
overflow: hidden;
-webkit-transition: left 0.4s ease-in-out;
-moz-transition: left 0.4s ease-in-out;
-o-transition: left 0.4s ease-in-out;
transition: left 0.4s ease-in-out;
}
#media screen and (min-width: 768px) {
#sidebar-wrapper {
left: 0; /* define left here for IE / Edge */
}
}
#media screen and (min-width: 1px) and (max-width: 767px) {
#sidebar-wrapper {
left: -240px;
}
}

How to create truely responsive typography in CSS3 relative to screen width

Imagine you have a container div:
.container {
max-width: 95%;
margin-right: auto;
margin-left: auto;
}
This creates a lovely, fully responsive left and right margin, proportionate to any browser screen width, right?
For extra small and extra large screens, you can even add a couple of #media queries to bound it, so the content is always readable:
#media (min-width: 450px) {
.container {
max-width: 100% // Remove the padding
}
}
# media (min-width: 1170px) {
.container { max-width: 1170px // Prevent your content scaling to infinity
}
}
Now imagine you wanted to have the same principals applied to typography and font sizes.
A relative % font size with min and max values, proportionate to screen width. I'm not talking about lots of jumpy static #media queries (as say, ahem BS3 relies), but a smooth transition, just like the container above.
And I want to do it without javascript (boo! no lettering.js!). Any CSS3 gurus out there?
Answers on a postcard please.
There newer methods emerging using relative units (vw/vh/vmax/vmin) a good article for this is: http://snook.ca/archives/html_and_css/vm-vh-units
however, this is still not widely supported. The best method I've found is applying font adjustments per resolution to the html selector (example below). You only declare the base font-size at the mobile view and progressively enhance using "rem" values (which are relative to the root selector).
Caveat to this, lte IE 8, Opera Mini, and iOS Safari 3.2 doesn't support the rem value, IE 9/10 doesn't support it in the shorthand "font" property. So it depends on your browser support needs. Using px values as fallbacks defeats the purpose of the relative units so... unless you're using modernizr's .no-cssremvalue to specify px units as fallbacks, and then you should be using modernizr to check for vw/vh/vmax/vmin support anyways.
alternate methods:
I'd also look into the Zurb Foundation 5's front-end framework as they've used a rather interesting method using meta tags to adjust the font-sizes responsively. http://foundation.zurb.com/docs/components/global.html
There are js libraries like flowtype.js and a few others as well, just look around (lots of new stuff out there since Aug '13)
:root { font-size:68.75% }
body{ font-size:1rem; /*IE9 & 10*/
line-height:1.625; /*IE9 & 10*/
font:1rem/1.625 sans-serif }
h1{ font-size:2.9375rem }
h2{ font-size:1.8125rem }
h3{ font-size:1.4375rem }
#media (min-width:30rem){ :root{ font-size:81.25% } }
#media (min-width:37.5em){ :root{ font-size:93.75% } }
#media (min-width:50em){ :root{ font-size:112.5% } }
#media (min-width:62.4375em){ :root{ font-size:118.75% } }
/* etc. */
You can use css animations, as long as the browser supports it
HTML
<div class="ProportionateFont">Text To Animate</div>
CSS
#media (max-width: 450px) {
.ProportionateFont {
animation: SmallerFont 0.3s;
animation-fill-mode: forwards;
-webkit-animation: SmallerFont 0.3s;
-webkit-animation-fill-mode: forwards;
}
}
#media (min-width: 450px) {
.ProportionateFont {
animation: LargerFont 0.3s;
animation-fill-mode: forwards;
-webkit-animation: LargerFont 0.3s;
-webkit-animation-fill-mode: forwards;
}
}
#keyframes SmallerFont {
0% { font-size:24px; }
100% { font-size:12px; }
}
#-webkit-keyframes SmallerFont {
0% { font-size:24px; }
100% { font-size:12px; }
}
#keyframes LargerFont {
0% { font-size:12px; }
100% { font-size:24px; }
}
#-webkit-keyframes LargerFont {
0% { font-size:12px; }
100% { font-size:24px; }
}
When screen is less than 450px (min-width:450px media query), the animation will be applied
When screen is more than 450px (max-width:450px media query), the animation will be applied
Fiddle Demo
Animation Doc
Keyframes Doc
Two solutions that I know of:
Create hundreds of media queries for hundreds of screen widths and apply an appropriate font size to each one. It will appear as though the copy is smoothly changing size when it fact it's just using media queries like normal. It's just there are a lot of them.
Use SVG Text. Scales smoothly and is SEO friendly. Here is a quick example I found that shows smooth scaling SVG text (among other things)
http://jsfiddle.net/9tUAd/33/
<div class="svg-wrap">
<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 550 350" xml:space="preserve" preserveAspectRatio="xMinYMin meet" height="100%" width="100%">
<text x="0" y="50%" fill="#ffffff" stroke="none" width="100%">Simplified example</text>
</svg>
There is no pure CSS solution to smoothly scaling text, outside of media queries.
You can use viewport units.
h1{font-size: 5.4vw}
That would give you a font size that is equal to 5.4% of the viewport width I believe. I just learned about this because I was looking myself.
Here's the link: http://css-tricks.com/viewport-sized-typography/
1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger
(from the link above)

how to dynamically size multi-css sprite image

I have an image built from multiple css sprites, as described in this question: css image building with sprites
How would I use that so that I could apply a size on the top container that would dynamically re-size all the children?
here is the working fidlle so far: http://jsfiddle.net/hWhUb/3/
here is the current html structure:
<div class="icon">
<div class="brigade brigade-purple-left"> </div>
<div class="brigade brigade-purple-middle"> </div>
<div class="brigade brigade-purple-right"> </div>
<div class="icon-type icon-hero"> </div>
</div>​
I have a few questions, that might lead to a solution:
Why are you using multiple images for something that can be easily achieved using a bit of css3 and a single image (the cross thingie)? A single image can more easily be resized, as a percentage of the container width, or even using css3 background-size property.
If you must use images for each thing, could you possibly consider never using sprites, ever? Its maintainability is pure annoyance, especially if someone has to take the project away from you later on.
Perhaps a combination of both?
If you choose the second option, I suggest using data uris.
Here's a short explaination:
http://css-tricks.com/data-uris/
It saves one more http request than sprites, easier to maintain, and the difference in overall size is rather insignificant in my honest opinion, and support is great - IE8+ and all sane browsers our there.
Setting up is easy enough, especially if you use the all-mighty sass interpreter, but there are some nifty utils out there (command-line, gui or even web-based) to transform your images into base64.
It can even support IE7 with a little effort!
Edit 3.11.12
You can also add http://css3pie.com/ to the options to check out - it lets you do the css3 tricks we so love and adore with internet explorer. It's a bit unpredictable to my taste, but for a small feat like this it can definitely do the trick.
Further, I commented on your browser-support needs below. IE7 is not what's going to stop you;)
You can use a combo of zoom for webkit/ie and -moz-transform:scale for Firefox
[class^="icon-"]{
display: inline-block;
background: url('../img/icons/icons.png') no-repeat;
width: 64px;
height: 51px;
overflow: hidden;
zoom:0.5;
-moz-transform:scale(0.5);
-moz-transform-origin: 0 0;
}
.icon-huge{
zoom:1;
-moz-transform:scale(1);
-moz-transform-origin: 0 0;
}
.icon-big{
zoom:0.60;
-moz-transform:scale(0.60);
-moz-transform-origin: 0 0;
}
.icon-small{
zoom:0.29;
-moz-transform:scale(0.29);
-moz-transform-origin: 0 0;
}
One of the ways to achieve it will be to use inline CSS and to dynamically generate attribute values in JavaScript or PHP/What you use.
Assuming you know the width of the top container and the position of the css sprites
Calculate the left middle and right
You can also opt to generate the CSS code in a separate file
http://aquagraphite.com/2011/11/dynamically-generate-static-css-files-using-php/
Using a bit of jQuery I can make the elements resize to whatever you want (resizeTo):
$(document).ready(function () {
$('#resize').click(function (e) {
e.preventDefault();
var resizeTo = 100,
resizeRatio = Number(resizeTo) / Number($(".icon").width());
$(".icon").css('width', resizeTo);
$(".child").each(function () {
var childWidth = Number($(this).width()),
childHeight = Number($(this).height()),
newChildWidth = childWidth * resizeRatio,
newChildHeight = childHeight * resizeRatio;
$(this).css({ 'width': newChildWidth, 'height': newChildHeight });
});
});
});​
However, size doesn't resize the sprites to fit the new box sizes so seems like a pointless task.
Fiddler: http://jsfiddle.net/hWhUb/4/
Though what you want to do can be accomplished, I think your approach is wrong. It's way more complicated than it needs to be, but the idea is sound.
Looking at your sprite, the only thing that can't be changed with CSS is the actual icons (the artwork). The rounded corners and background colors -- that's a different story.
CSS
.icon-cross {
background:purple url('cross.jpg') no-repeat 40px 12px;
border-radius:5px;
border:1px solid gray
}
#media only screen and (max-width:768px) {
.icon-cross {
background-size: 800px 1200px;
background-position; ??px ??px
}
}
#media only screen and (max-width:400px) {
.icon-cross {
background-size: 500px 900px;
background-position; ??px ??px
}
}
HTML
<div class="icon-cross"></div>
You can use css3 2d transforms:
.icon {
transform: scale(2);
-ms-transform: scale(2); /* IE 9 */
-webkit-transform: scale(2); /* Safari and Chrome */
-o-transform: scale(2); /* Opera */
-moz-transform: scale(2); /* Firefox */
}
and change the transform origin with: transform-origin

Resources