I've got the following problem - I'm using a simple JS code to replace CSS file on the fly, depending on the browser window size. It looks like this:
<script type="text/javascript">
//<![CDATA[
<!--
function adjustStyle(width) {
width = parseInt(width);
if (width < 701) {
$("#size-stylesheet").attr("href", "narrow.css");
} else if ((width >= 701) && (width < 1120)) {
$("#size-stylesheet").attr("href", "medium.css");
} else {
$("#size-stylesheet").attr("href", "wide.css");
}
}
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
-->
//]]>
</script>
However, in addition to that - I'm also using LESS.CSS (http://lesscss.org/). Well, those two don't work together well - with LESS, as I understand, CSS is embedded into HTML document itself, so the CSS file isn't replaced. Is there any way to make it work? Or maybe
a better way ?
Can't you just use media queries?
<link rel='stylesheet' media='screen and (max-width: 701px)' href='narrow.css' />
<link rel='stylesheet' media='screen and (min-width: 701px) and (max-width: 1120px)' href='medium.css' />
<link rel='stylesheet' media='screen and (min-width: 1120px)' href='wide.css' />
Related
I'm trying this but it is not working:
<html>
<head>
<script src="js/menu-collapser.js" type="text/javascript" media="media screen and (max-width: 599px)"></script>
</head>
...
</html>
//menu-collapser.js :
jQuery(document).ready(function($){
$('.main-navigation li ul').hide();
$('.main-navigation li').has('ul').click(function() {
$(this).children().toggle();
});
});
Do you have an idea on how to do this in the right way? The script work if used directly in the header with the tags.
You can't do that directly using Javascript <script> tags. Media queries are used in linked CSS files or inline CSS styles. A basic example:
<link rel="stylesheet" media="screen and (min-width: 900px)" href="desktop.css"/>
<link rel="stylesheet" media="screen and (min-width: 571px)" href="tablet.css"/>
<link rel="stylesheet" media="screen and (max-width: 570px)" href="mobile.css"/>
Or directly in your stylesheets:
#media screen and (max-width: 599px) {
#mobile {
display: block;
}
}
However, you can use an external asset loader/media query library to do this (require.js, modernizr.js, enquire.js and others), In this case, I'm setting an example using enquire.js, as I think it's very effective and doesn't require jQuery by default:
Full example
1) Include enquire.js (available here):
<script type="text/javascript" src="/js/enquire.js"></script>
2) Create a load function - to load JS files:
<script type="text/javascript">
// This loads JS files in the head element
function loadJS(url)
{
// adding the script tag to the head
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// fire the loading
head.appendChild(script);
}
</script>
3) Fire enquire.js and listen for media query changes (both on-load and on-resize):
<script type="text/javascript">
enquire.register("screen and (max-width: 599px)", {
match : function() {
// Load a mobile JS file
loadJS('mobile.js');
}
}).listen();
enquire.register("screen and (min-width: 600px) and (max-width: 899px)", {
match : function() {
// Load a tablet JS file
loadJS('tablet.js');
//console.log('tablet loaded');
}
}).listen();
enquire.register("screen and (min-width: 900px)", {
match : function() {
// Load a desktop JS file
loadJS('desktop.js');
//console.log('desktop loaded');
}
}).listen();
</script>
Putting it all together
Using a simple HTML page with enquire.js loaded from an external file:
<html>
<head>
<script type="text/javascript" src="/enquire.js"></script>
<script type="text/javascript">
// This loads JS files in the head element
function loadJS(url)
{
// adding the script tag to the head
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// fire the loading
head.appendChild(script);
}
</script>
<style>
body {
font-family: arial;
}
h1 {
font-size: 50pt;
}
#mobile {
display: none;
}
#tablet {
display: none;
}
#desktop {
display: none;
}
#media screen and (max-width: 599px) {
#mobile {
display: block;
}
}
#media screen and (min-width: 600px) and (max-width: 899px) {
#tablet {
display: block;
}
}
#media screen and (min-width: 900px) {
#desktop {
display: block;
}
}
</style>
</head>
<body>
<div id="desktop">
<h1>Desktop</h1>
</div>
<div id="tablet">
<h1>Tablet</h1>
</div>
<div id="mobile">
<h1>Mobile</h1>
</div>
<script type="text/javascript">
enquire.register("screen and (max-width: 599px)", {
match : function() {
// Load a JS file
loadJS('mobile.js');
}
}).listen();
enquire.register("screen and (min-width: 600px) and (max-width: 899px)", {
match : function() {
loadJS('tablet.js');
//console.log('tablet loaded');
}
}).listen();
enquire.register("screen and (min-width: 900px)", {
match : function() {
loadJS('desktop.js');
//console.log('desktop loaded');
}
}).listen();
</script>
</body>
</html>
In addition to loading JS files, you could create a CSS loader too, which would work in the same way (conditionally), but that defeats the object of using #media in CSS. It's worth reading the usage explanations for enquire.js, as it can do a lot more than I've illustrated here.
Caveat: Nothing above uses jQuery, but you could take advantage of some of the functions it offers; loading scripts for example - or executing other functions that you need to.
Why not just load in a script conditionally?
(function() {
if( window.innerWidth > 600 ) {
var theScript = document.createElement('script');
theScript.type = 'text/javascript';
theScript.src = 'js/menu-collapser.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(theScript, s);
}
})();
Or better yet, only execute the code if the window.innerWidth > 600 ? Anyway, there are a lot of solutions you can use.
media is not a valid attribute for <script>, check it here.
So you should detect media types by manually than load the script dynamically.
There is a plug-in for css media detection in javascript, you can use it.
<script type="text/javascript" src="js/mediatypechecker.js"></script>
$(function() {
if(IsMediaType('screen') > 0 && parseInt(screen.width) < 599) {
$.getSscript("js/menu-collapser.js");
}
});
If you want it to react to later resizing events (e.g. on desktop) as well, you can do it like this:
<script>
moby = window.matchMedia("(max-width: 500px)");
moby.addListener(
moby=>{
if(moby.matches){
document.head.innerHTML+="<script src='wonderfulScreenAffectedScript.js'></script>";
}
}
);
</script>
Problem: I have a website that works fine on the desktop version. However, I created a different css styling sheet for iPhone so the carousel images would not skew. Doing this, I was able to find online a javascript function with the help of Stackoverflow, that detects iPhone and iPad devices.
However, it appears to be also making changes to android carousel slide. So the following is what I am using to detect iPhone and iPad devices:
<script language=javascript>
function isApple(userAgent){
var iPhone = userAgent.match(/iPhone/i) !== null;
var Apple = userAgent.match(/Apple/i) !== null;
var Mac = userAgent.match(/Mac/i) !== null;
var iPod = userAgent.match(/iPod/i) !== null;
var iOS = userAgent.match(/iOS/i) !== null;
return iPhone || Apple || Mac || iPod || iOS;
}
.
if(isApple(navigator.userAgent)){
document.getElementsByTagName('head')[0].insertAdjacentHTML('beforeend', '<link rel="stylesheet" href="/assets/bootstrap/css/iphone.css">');
}
</script>
The following is the css styling for the iPhone. Their is a fix height so the images in the carousel does not skew on the iPhone:
/* Portrait and Landscape iphone*/
#media only screen
and (max-device-width: 480px)
and (orientation:portrait) {
#homepage .carousel .item { height: 150px !important;}
#homepage .carousel .item img { max-width: 100%; height: auto; display: block; }
}
#media only screen
and (max-device-width: 480px)
and (orientation:landscape) {
#homepage .carousel .item { height: 250px !important; }
#homepage .carousel .item img { max-width: 100%; height: auto; display: block; }
}
I currently have my styling in the following order and I am not sure it is do to the order that is causing the issue:
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/css/theme/theme.min.css">
<!--- Bootstrap classes overrides --->
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/assets/bootstrap/css/bootstrap_overrides.css">
<!--- IPHONE classes overrides --->
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/assets/bootstrap/css/iphone.css">
<!--[if IE]>
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/css/ie/ie.min.css">
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/css/ie/ie_overrides.css">
<![endif]-->
<!--[if lte IE 9]>
<link rel="icon" href="/images/favicon1.ico" type="image/x-icon" />
<![endif]-->
That being said, is the JavaScript I am using not the right approach to detect iPhones and iPads? If so, what can be done to modify it?
If not, would I need to create another styling sheet for android devices? If so, I was able to find on stack-overflow the following JavaScript that detects whether the browser is on a android device:
$(function isAndroid(userAgent) { // Wait for page to finish loading.
if(navigator != undefined && navigator.userAgent != undefined) {
user_agent = navigator.userAgent.toLowerCase();
if(isAndroid(user_agent.indexOf('android')) > -1) { // Is Android.
document.getElementsByTagName('head')[0].insertAdjacentHTML('beforeend', '<link rel="stylesheet" href="/assets/bootstrap/css/android.css">');
}
}
});
However, I am not sure the way I modify it will work.
Any help would be appreciated.
Thank You
You can try this.
function getMobileOperatingSystem() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
if( userAgent.match( /iPad/i ) || userAgent.match( /iPhone/i ) || userAgent.match( /iPod/i ) )
{
return 'ios';
}
else if( userAgent.match( /Android/i ) )
{
return 'android';
}
else
{
return 'unknown';
}
}
Would it be possible for me to do something like
<link href="nav.css" type="text/css" rel="stylesheet" />
in this?
<script>
if (screen.width <= 800) {
Link to css here!
}
</script>
Just use a css media query like so
You can read about media queries here
#media(max-width: 800px) {
/*
* enter css here
*/
}
I want to have 2 different css files, one for a window.devicePixelRatio <= 1 and one >1 for high dpi devices.
How can I use JavaScript to choose the css?
What I've done so far (not working):
<head>
<script>
if (window.devicePixelRatio <= 1) {
<!--alert('window.devicePixelRatio = ' + window.devicePixelRatio);-->
<link href="style.css" rel="stylesheet" type="text/css" />;
} else {
<link href="stylemobi.css" rel="stylesheet" type="text/css" />;
}
</script>
</head>
Use one link tag and give it an ID and right after it put a script to set it's href
<link id="main-style" rel=...>
<script>
var stylesheet = window.devicePixelRatio <= 1 :'styles.css' : 'stylemobi.css';
document.getElementById('main-style').setAttribute('href',stylesheet );
</script>
Waiting any later to do it will mean some strange styling while the body loads
I'm not quite certain but how about,
<head>
<link id="theCSS" href="" rel="stylesheet" type="text/css" />
<script>
if (window.devicePixelRatio <= 1) {
document.getElementById('theCSS').href= "style.css";
} else {
document.getElementById('theCSS').href= "stylemobi.css";
}
</script>
</head>
Update:- Adding description--> Provided an id to the css <link> element and grabbing it in js using, document.getElementById() and assigning it'd href to whatever the css you want as per your condition
Don't use JS at all, just add some media attributes to the <link> elements to check the resolution:
<link href="style.css" rel="stylesheet" media="resolution <= 1dppx" />
<link href="stylemobi.css" rel="stylesheet" media="resolution > 1dppx" />
Otherwise, if you want to use JavaScript, you'll have to write valid JavaScript. You can't just mix and match JS and HTML.
Thanks for the answers!
I used this method now, different css styles in a single css file, automatically choosen depending on the display ppi.
body {
margin: 0;
padding: 0;
/*background-color:#008B09;*/
background-image:url("purty_wood.jpg");
background-color:#008B09;
font-family: 'ABeeZee', sans-serif;
color:#000000;
overflow:auto;
font-size:1.2em;
}
#media (-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
body {
font-size:2em;
}
}
In this case the Browser overrides automatically the standard css, if the resolution is over 192ppi or the dp-ratio is over 2. So within a single css file, i can have different settings for different displays!
(i just need to set the resolution to min 235, because some mac displays have up to 230 ppi, most smartphones have at least 250ppi.)
More Info: https://css-tricks.com/snippets/css/retina-display-media-query/
found out about this jquery plugin that adds support to media queries
So you can use:
<link rel="stylesheet" type="text/css" href="wider.css" media="only screen and (min-width: 1200px)" />
<link rel="stylesheet" type="text/css" href="handheld-iphone.css" media="only screen and (max-width: 480px), handheld" />
and so on, but it does not support this kind of media queries (in stylesheet)
#media screen and (max-width: 1024px) {
body{background:red}
}
#media screen and (max-width: 740px) {
body{background:yellow}
}
Is there any that does?
You could do something like this as well
http://jsfiddle.net/47DSD/
$(document).ready(function() {
function wResize() {
var winW = $(window).width();
var Body = $('body');
if ( winW < '1024') {
Body.css({ 'background-color':'red' });
}
if ( winW < '740' ) {
Body.css({ 'background-color':'yellow' });
}
}
wResize();
$(window).resize(function() {
wResize();
});
});
Edit:
You didnt seem to warm up to this, so how about a little more extensive example?
http://jsfiddle.net/47DSD/1/
You should look at enquire.js.
Wouter van der Graaf made a javascript plugin for media query support in browsers that don't natively support it:
http://code.google.com/p/css3-mediaqueries-js/