issue with CSS media queries(scrollbar) - html

I am having problem with css media query in Firefox. It works correct in Chrome like I made two DIVs and want a scrollbar. If I decrease the screen size of firefox upto 800px then both DIVs collapse and after some pixels media query works but that not happens in Chrome.
check this fiddle http://jsfiddle.net/RMvqC/2/

I SOLVED this issue by calling the "mqGenie" javascript in the head of my project.
Now the widths of my media queries work fine ( with the same value ) on Chrome, Safari, Firefox and IE with or without scroolbars.
This javascript Adjusts CSS media queries in browsers that include the scrollbar width in the viewport width so they fire at the intended size.
You can download it from this url:
http://stowball.github.io/mqGenie/

Firefox & Webkit based browsers render the scrollbar differently. In Firefox, MediaQuery considered width of scrollbar which is 15px with the screen width, but in Webkit based browsers it's not considered scrollbar with the screen width. So, that's why the floated DIVs are collapsed in Firefox.
I did some stuff with css may be that's help you. (check this fiddle)
html {
/* force scrollbars */
height: 101%;
}
body {
margin: 0;
padding:0;
white-space:nowrap;
}
#box1,
#box2 {
display:inline-block;
width: 400px;
height: 200px;
vertical-align:top;
white-space:normal;
}
#box1 {
background: #ce0000;
margin-right:-5px;
}
#box2 {
background: #8e0000;
}
#media screen and (max-width: 799px) {
body {
white-space:normal;
}
#box1,
#box2 {
width: 300px;
}
}

Firefox & Opera follows W3C spec which is to include scrollbar width in media queries width (the reason might be to avoid infinite loop as described in a comment here), while Webkit does not (possibly coz they think it makes no sense)
There is a workaround (I've only tested this on FF), apparently if you force scrollbar to be visible all the time, then the width will now be consistent with Webkit. Here's the code:
html
{
overflow:hidden;
height:100%;
}
body
{
position:relative;
overflow-y:scroll;
height:100%;
-webkit-overflow-scrolling:touch; /* So iOS Safari gets the inertia & rubber-band effect */
}
If you want to apply this to FF & Opera only, you can resort to CSS hacks:
/* Firefox */
#-moz-document url-prefix()
{
html
{
overflow:hidden;
height:100%;
}
body
{
position:relative;
overflow-y:scroll;
height:100%;
/*-webkit-overflow-scrolling:touch;*/
}
}
/* Opera */
x:-o-prefocus, html
{
overflow:hidden;
height:100%;
}
x:-o-prefocus, body
{
position:relative;
overflow-y:scroll;
height:100%;
}
It goes without saying, the caveat is the scrollbar will be visible at all times, which might be an okay compromise.

Play safe!
My final strategy is added 20px to the media queries and that is my default white space on the layout.
With one exception: #media (min-width: 320px) At that size a don't leave the 20px white space and include one more rule to solve minor background issues:
html body {
min-width: 320px;
}
20px is the scroll bar default width size.
FYI: https://www.sitepoint.com/rwd-scrollbars-is-chrome-better/

You can implement a solution for Firefox pretty easily by using a CSS-hack. After wrapping your content in an extra <div> add this lines to your CSS:
/* Firefox-Hack */
body, x:-moz-any-link {
overflow-x: hidden;
}
#wrapper, x:-moz-any-link {
margin: 0 -7.5px;
}
Check the jsbin (jsfiddle is down right now)
To have richer responsive experience you could add another media query: another jsbin
The CSS-hack was found at paulirish.com

This is peripherally related, but I found a way to detect which media-query the browser is actually using at any given moment, without having to muck around with scrollbar and body widths...
Basically, define a an absolutely positioned 1-x-1-pixel-sized list somewhere in your body, with a list-item for each media-query condition you want to be "watchable".
Then in each media-query definition, show/hide the corresponding list-item, and then simply check whether that item is visible from within your script.
Example:
<body>
...
<ul id="mediaQueryHelper">
<li id="desktop"></li>
</ul>
</body>
<style type="text/less">
#mediaQueryHelper {
position: absolute;
height: 1px;
width: 1px;
visibility: hidden;
top: -999px;
left: -999px;
}
#media screen and (min-width: 481px)
{
#desktop { display: inline; }
}
#media screen and (min-width: 320px) and (max-width: 480px)
{
#desktop{ display: none; }
}
</style>
<script type="text/javascript">
$(document).ready(function()
{
var _desktop = $("#desktop");
$(window).resize(function() {
console.log("media-query mode: " + _desktop.is(":visible") ? "DESKTOP" : "MOBILE");
});
});
</script>

Short Answer
If you do not want to display the scrollbar all the time, wrap your content into <div> elements etc. you can use JavaScript to add a certain value to all media queries when the scrollbar is shown.
// check whether scrollbar is visible
var isScrollbarVisible = window.innerWidth > document.documentElement.clientWidth;
// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];
// update media rule
mediaRule.media.mediaText = '..'
Long Answer
I wrote a small script which you can include on your page. It detects when the window is resized and changes all media queries if needed. The value of the css variable --replace-media-scrollbar is used as the width of the scrollbar or 15px if no value was found. This works for the media queries with, min-width, max-width, height, min-height and max-height even when they are connected using and.
JavaScript:
function* visitCssRule(cssRule) {
// visit imported stylesheet
if (cssRule.type == cssRule.IMPORT_RULE)
yield* visitStyleSheet(cssRule.styleSheet);
// yield media rule
if (cssRule.type == cssRule.MEDIA_RULE)
yield cssRule;
}
function* visitStyleSheet(styleSheet) {
try {
// visit every rule in the stylesheet
var cssRules = styleSheet.cssRules;
for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
yield* visitCssRule(cssRule);
} catch (ignored) {}
}
function* findAllMediaRules() {
// visit all stylesheets
var styleSheets = document.styleSheets;
for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
yield* visitStyleSheet(styleSheet);
}
// collect all media rules
const mediaRules = Array.from(findAllMediaRules());
// read scrollbar width
var style = getComputedStyle(document.documentElement);
var scrollbar = style.getPropertyValue('--replace-media-scrollbar') || '15px';
// update media rules
if (scrollbar != '0px') {
var oldValue = '0px';
function updateMediaRulesScrollbar() {
var newValue = window.innerWidth > document.documentElement.clientWidth ? scrollbar : '0px';
// if value changed
if (oldValue != newValue) {
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): (calc\\([^)]*\\)|[^)]*)\\)', 'g');
var replacement = '($1: calc($2 - ' + oldValue + ' + ' + newValue + '))';
mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
console.log(mediaRule);
}
}
oldValue = newValue;
}
updateMediaRulesScrollbar();
window.onresize = updateMediaRulesScrollbar;
}
Optional CSS:
:root {
--replace-media-scrollbar: 15px;
}

Related

Is there a way to hide a video once past a certain screen resolution? [duplicate]

I have a div element that I want to hide when the width of the browser is less than or equal to 1026px. Is this possible to do with the css: #media only screen and (min-width: 1140px) {} If it isn't possible with css, Is there any alternative?
Extra info:
When the div element is hidden, I don't want a blank white gap. I'd like the page to flow as it would if I deleted the div element entirely from the code.
The div I am hiding is <div id="fadeshow1"></div>.
HTML5 Doctype.
I used javascript to place a gallery into that div.
I want it to look like this when it is bigger than 1026px width:
I want it to look like this when it is less than 1026px width:
You can do this with CSS:
#media only screen and (max-width: 1026px) {
#fadeshow1 {
display: none;
}
}
We're using max-width, because we want to make an exception to the CSS, when a screen is smaller than the 1026px.
min-width would make the CSS rule count for all screens of 1026px width and larger.
Something to keep in mind is that #media queries are not supported on IE8 and lower.
#media only screen and (max-width: 1026px) {
#fadeshow1 {
display: none;
}
}
Any time the screen is less than 1026 pixels wide, anything inside the { } will apply.
Some browsers don't support media queries. You can get round this using a javascript library like Respond.JS
if you are using bootstrap u can just use the hidden-sm ( lg or md or xs) depending on what u want. u can then go into the css file and specify the percentages u want it to show on. in the sample below it will be hiding on large screens, medium ones and extra small ones but show on small screens by taking half of the screen.
<div class="col-sm-12 hidden-lg hidden-md hidden-xs">what ever you want</div>
I don't know about CSS but this Javascript code should work:
function getBrowserSize(){
var w, h;
if(typeof window.innerWidth != 'undefined')
{
w = window.innerWidth; //other browsers
h = window.innerHeight;
}
else if(typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0)
{
w = document.documentElement.clientWidth; //IE
h = document.documentElement.clientHeight;
}
else{
w = document.body.clientWidth; //IE
h = document.body.clientHeight;
}
return {'width':w, 'height': h};
}
if(parseInt(getBrowserSize().width) < 1026){
document.getElementById("fadeshow1").style.display = "none";
}
You simply need to use a media query in CSS to accomplish this.
#media (max-width: 1026px) {
#fadeshow1 { display: none; }
}
Unfortunately some browsers do not support #media (looking at you IE8 and below). In those cases, you have a few options, but the most common is Respond.js which is a lightweight polyfill for min/max-width CSS3 Media Queries.
<!--[if lt IE 9]>
<script src="respond.min.js"></script>
<![endif]-->
This will allow your responsive design to function in those old versions of IE. *reference
This should help:
if(screen.width<1026){//get the screen width
//get element form document
elem.style.display == 'none'//toggle visibility
}
768 px should be enough as well
You have to use max-width instead of min-width.
<style>
#media (max-width: 1026px) {
#test {
display: none;
}
}
</style>
<div id="test">
<h1>Test</h1>
</div>
#media only screen and (min-width: 1140px)
should do his job, show us your css file
The easiest approach I know of is using onresize() func:
window.onresize = function(event) {
...
}
Here is a fiddle for it

Do you include the scrollbar width of browsers in your media query? [duplicate]

I am having problem with css media query in Firefox. It works correct in Chrome like I made two DIVs and want a scrollbar. If I decrease the screen size of firefox upto 800px then both DIVs collapse and after some pixels media query works but that not happens in Chrome.
check this fiddle http://jsfiddle.net/RMvqC/2/
I SOLVED this issue by calling the "mqGenie" javascript in the head of my project.
Now the widths of my media queries work fine ( with the same value ) on Chrome, Safari, Firefox and IE with or without scroolbars.
This javascript Adjusts CSS media queries in browsers that include the scrollbar width in the viewport width so they fire at the intended size.
You can download it from this url:
http://stowball.github.io/mqGenie/
Firefox & Webkit based browsers render the scrollbar differently. In Firefox, MediaQuery considered width of scrollbar which is 15px with the screen width, but in Webkit based browsers it's not considered scrollbar with the screen width. So, that's why the floated DIVs are collapsed in Firefox.
I did some stuff with css may be that's help you. (check this fiddle)
html {
/* force scrollbars */
height: 101%;
}
body {
margin: 0;
padding:0;
white-space:nowrap;
}
#box1,
#box2 {
display:inline-block;
width: 400px;
height: 200px;
vertical-align:top;
white-space:normal;
}
#box1 {
background: #ce0000;
margin-right:-5px;
}
#box2 {
background: #8e0000;
}
#media screen and (max-width: 799px) {
body {
white-space:normal;
}
#box1,
#box2 {
width: 300px;
}
}
Firefox & Opera follows W3C spec which is to include scrollbar width in media queries width (the reason might be to avoid infinite loop as described in a comment here), while Webkit does not (possibly coz they think it makes no sense)
There is a workaround (I've only tested this on FF), apparently if you force scrollbar to be visible all the time, then the width will now be consistent with Webkit. Here's the code:
html
{
overflow:hidden;
height:100%;
}
body
{
position:relative;
overflow-y:scroll;
height:100%;
-webkit-overflow-scrolling:touch; /* So iOS Safari gets the inertia & rubber-band effect */
}
If you want to apply this to FF & Opera only, you can resort to CSS hacks:
/* Firefox */
#-moz-document url-prefix()
{
html
{
overflow:hidden;
height:100%;
}
body
{
position:relative;
overflow-y:scroll;
height:100%;
/*-webkit-overflow-scrolling:touch;*/
}
}
/* Opera */
x:-o-prefocus, html
{
overflow:hidden;
height:100%;
}
x:-o-prefocus, body
{
position:relative;
overflow-y:scroll;
height:100%;
}
It goes without saying, the caveat is the scrollbar will be visible at all times, which might be an okay compromise.
Play safe!
My final strategy is added 20px to the media queries and that is my default white space on the layout.
With one exception: #media (min-width: 320px) At that size a don't leave the 20px white space and include one more rule to solve minor background issues:
html body {
min-width: 320px;
}
20px is the scroll bar default width size.
FYI: https://www.sitepoint.com/rwd-scrollbars-is-chrome-better/
You can implement a solution for Firefox pretty easily by using a CSS-hack. After wrapping your content in an extra <div> add this lines to your CSS:
/* Firefox-Hack */
body, x:-moz-any-link {
overflow-x: hidden;
}
#wrapper, x:-moz-any-link {
margin: 0 -7.5px;
}
Check the jsbin (jsfiddle is down right now)
To have richer responsive experience you could add another media query: another jsbin
The CSS-hack was found at paulirish.com
This is peripherally related, but I found a way to detect which media-query the browser is actually using at any given moment, without having to muck around with scrollbar and body widths...
Basically, define a an absolutely positioned 1-x-1-pixel-sized list somewhere in your body, with a list-item for each media-query condition you want to be "watchable".
Then in each media-query definition, show/hide the corresponding list-item, and then simply check whether that item is visible from within your script.
Example:
<body>
...
<ul id="mediaQueryHelper">
<li id="desktop"></li>
</ul>
</body>
<style type="text/less">
#mediaQueryHelper {
position: absolute;
height: 1px;
width: 1px;
visibility: hidden;
top: -999px;
left: -999px;
}
#media screen and (min-width: 481px)
{
#desktop { display: inline; }
}
#media screen and (min-width: 320px) and (max-width: 480px)
{
#desktop{ display: none; }
}
</style>
<script type="text/javascript">
$(document).ready(function()
{
var _desktop = $("#desktop");
$(window).resize(function() {
console.log("media-query mode: " + _desktop.is(":visible") ? "DESKTOP" : "MOBILE");
});
});
</script>
Short Answer
If you do not want to display the scrollbar all the time, wrap your content into <div> elements etc. you can use JavaScript to add a certain value to all media queries when the scrollbar is shown.
// check whether scrollbar is visible
var isScrollbarVisible = window.innerWidth > document.documentElement.clientWidth;
// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];
// update media rule
mediaRule.media.mediaText = '..'
Long Answer
I wrote a small script which you can include on your page. It detects when the window is resized and changes all media queries if needed. The value of the css variable --replace-media-scrollbar is used as the width of the scrollbar or 15px if no value was found. This works for the media queries with, min-width, max-width, height, min-height and max-height even when they are connected using and.
JavaScript:
function* visitCssRule(cssRule) {
// visit imported stylesheet
if (cssRule.type == cssRule.IMPORT_RULE)
yield* visitStyleSheet(cssRule.styleSheet);
// yield media rule
if (cssRule.type == cssRule.MEDIA_RULE)
yield cssRule;
}
function* visitStyleSheet(styleSheet) {
try {
// visit every rule in the stylesheet
var cssRules = styleSheet.cssRules;
for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
yield* visitCssRule(cssRule);
} catch (ignored) {}
}
function* findAllMediaRules() {
// visit all stylesheets
var styleSheets = document.styleSheets;
for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
yield* visitStyleSheet(styleSheet);
}
// collect all media rules
const mediaRules = Array.from(findAllMediaRules());
// read scrollbar width
var style = getComputedStyle(document.documentElement);
var scrollbar = style.getPropertyValue('--replace-media-scrollbar') || '15px';
// update media rules
if (scrollbar != '0px') {
var oldValue = '0px';
function updateMediaRulesScrollbar() {
var newValue = window.innerWidth > document.documentElement.clientWidth ? scrollbar : '0px';
// if value changed
if (oldValue != newValue) {
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): (calc\\([^)]*\\)|[^)]*)\\)', 'g');
var replacement = '($1: calc($2 - ' + oldValue + ' + ' + newValue + '))';
mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
console.log(mediaRule);
}
}
oldValue = newValue;
}
updateMediaRulesScrollbar();
window.onresize = updateMediaRulesScrollbar;
}
Optional CSS:
:root {
--replace-media-scrollbar: 15px;
}

Change position of a box only on mobile?

I was wondering if it is possible to change the position of the search box but only on mobiles.. I tried to put id="search" on the box that contains the input with:
#media only screen and (max-width: 767px) {
#search
{
position:absolute;
top: 0;
width:90%;
background: none repeat scroll 0 0 #ffffff;
}
}
But doesn't seem to work. I want the search box just at the bottom of the header, but only on mobiles. Is this possible?
At work we use JavaScript & jQuery to move an element on different screen sizes like so:
function moveMenu(){
if($(window).width() < 767){
// If the screen is less than 767, move the menu to mobile position
$('#menu-header').prependTo('#mobile-menu-wrapper');
}
else {
// Otherwise, put it in the normal location
$('#menu-header').prependTo('#header-menu-wrapper');
}
}
Its important that if someone loads the page on a small screen, then resizes it to large that this function runs. So we also add these two bits to trigger it on page load and on page resize:
$(window).resize(function(){
moveMenu();
});
$(window).load(function(){
moveMenu();
});
This method means you don't have to duplicate menus to 'reflow' the page.
Add another search box in the Center-block
Hide this on desktop and show it on the
UPDATE: Position fixed will work but will not allow to use other elements
the code is something like this
#search1 {
display: block;
}
#search2 {
display: none;
}
#media only [....] {
#search1 {
display: none;
}
#search2 {
display: block;
}
}

How to hide image if screen size is less than 480px (iPhone 4)?

I have a popup image that shows up on our homepage, But i want to hide it if a viewer is visiting our website from a mobile device (such as an iPhone 4), simply because the image is to big for the phone, without having to zoom out. Here is my code:
<div class="gamedayad">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://www.jacklmoore.com/colorbox/jquery.colorbox.js"></script>
<script>
function openColorBox(){
$.colorbox({href: "image url"});
}
function countDown(){
seconds--
$("#seconds").text(seconds);
if (seconds === 0){
openColorBox();
clearInterval(i);
}
}
var seconds = 5,
i = setInterval(countDown, 0);
</script>
</div>
and the CSS i have (idk if it is correct) is:
#media screen and (max-width: 480px) {
.gamedayad {
display: hidden !important;
}
}
Please help? Thanks!
Have you tried
#media screen and (max-width: 480px) {
.gamedayad {
display: none;
}
}
display: hidden; doesn't exist, it must be display: none;
Your media query is correct, just the wrong property value is all :)
The correct CSS markup is:
display: none !important;
However bear in mind you are still downloading the image in a mobile device, and hiding it. The best approach would be to only download the image if you can display it. A simple check to the window width in your script would do the trick.
var windowWidth = $(window).width();
if (windowWidth > 480) {
//download your image here
}
I think you are confusing the property "display" and the value "hidden". Try display: none;:
.gamedayad {
display: none !important;
}
Ok, so i think what my problem was that I didn't have this script at the top of the page, it was posted at the bottom (under other scripts). I did however put in the:
var windowWidth = $(window).width();
if (windowWidth > 480) {
//download your image here
}
posted by denisol, and:
#media screen and (max-width: 480px) {
.gamedayad {
display: none;
}
}
Thanks to everyone for the help!!

Div smart width

see fiddle
html
<div class="e" style="left:5px;top:5px;">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbb</div>
<div class="e" style="left:5px;top:100px;">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>​
css
.e {
font-size: 10px;
font-family: arial;
background-color: yellow;
position: absolute;
max-width: 300px;
}
you will notice the 2nd div fits the size of the content exactly, but on the first div there's a bunch of empty space to the right of the a's and b's. This is because the div hit its max width of 300px and then wrapped the b's to a 2nd line. The wrapping is good, but then I would expect the div to then shrink back down to the width of the a's so that there's no empty space to the right.
Is it possible to get it to do this?
Tested in Chrome and FF.
​
you may avoid handling the width, as my understanding is that you're looking for a way to break the text in a satisfying manner.
use word-break: break-all, to wrap the text whenever it hits the container's edge.
Example:
demo on jsFiddle
Reference:
the CSS3 word-break property on Mozilla Developer Network
To shrink a div (or any element) to the size of its text content, you can use JavaScript to get a range that contains its contents and get the size of the range using range.getBoundingClientRect():
function sizeElementToContents(el) {
var range = document.createRange();
range.selectNodeContents(el);
var textRect = range.getBoundingClientRect();
el.style.width = textRect.width + "px";
}
But, of course, that only works with Modern browsers. IE8 and IE7 have different methods for working with ranges. Actually, IE7 automatically handles max-width the way you want it to, but when our IE8 code is run to re-size the divs on IE7, it shrinks the divs to 0. To avoid writing code for specific browser versions, this code runs on IE7 and IE8, but includes a little extra logic so that it works on both browser versions:
function sizeElementToContents(el) {
var range, width;
if (document.createRange) {
range = document.createRange();
range.selectNodeContents(el);
width = range.getBoundingClientRect().width;
}
else {
range = document.body.createTextRange();
range.moveToElementText(el);
range.moveStart("character", 1);
width = range.boundingWidth;
var height = range.boundingHeight;
range.collapse();
range.moveEnd("character", 1);
if (range.boundingHeight == height) {
return; // text doesn't wrap, so don't resize
}
}
el.style.width = width + "px";
}
Working demo: http://jsfiddle.net/gilly3/HZRFb/
Forking from Biziclop's solution:
.e {
font-size: 10px;
font-family: arial;
background-color: yellow;
position: absolute;
max-width: 300px;
margin-right:100%;
}
Link to the Fiddle.
Don't ask me why it works, it might break tomorrow, but adding some extreme margin-right seems to solve the problem:
.e {
margin-right: 9999px;
}
See http://jsfiddle.net/2cTga/1/