supporting multiple resolution and density of images in phonegap - css

I am new to phonegap and facing a problem, I am making a phonegap app which will run on multiple platform devices of different screen size and different screen resolution so I have to load images of different resolution depending on screen resolution.
this can be achieved in android by simply putting your images of different resolution in hdpi, mdpi and ldpi folder and it(android) fetches images automatically depending on devices screen resolution. But how to do this in phonegap.
I have seen lot of articles on responsive web design they all say about positioning the elements on web page but non of them has told about how to place images on the basis of screen resolutions.
thanks i advance.
edited question
i have used following code for html
<div id="header" data-role="header" data-position="fixed">
<img alt="app_icon" src="pictures/app_logo.png" display="inline" class="align-left" />
<img alt="brand_icon" src="pictures/company_logo.png" display="inline" class="align-right" /><h1></h1>
</div>
now I have images inside assets/www/pictures folder. this folder consists of 2 images of same resolution app_logo.png and company_logo.png and 2 images of higher resolution app_logo_big.png and company_logo_big.png now through media queries i will know the screen size and apply the styles but as far as i know i cannot change img src from css. So now how will i use these images of different resolution

Then Dynamically Change Image through jquery:
HTML:
<div id="header" data-role="header" data-position="fixed">
<img id="app-icon" src="pictures/app_logo.png" display="inline" />
</div>
Javascript:
$(document).ready(function () {
if(window.devicePixelRatio == 0.75) {
$("#app-icon").attr('src', '/images/lpdi/app-icon.png');
}
else if(window.devicePixelRatio == 1) {
$("#app-icon").attr('src', '/images/mdi/app-icon.png');
}
else if(window.devicePixelRatio == 1.5) {
$("#app-icon").attr('src', '/images/hpdi/app-icon.png');
}
else if(window.devicePixelRatio == 2) {
$("#app-icon").attr('src', '/images/xpdi/app-icon.png');
}
}
Through CSS: Use Media Queries for Different Resolution :
HTML:
<div id="header" data-role="header" data-position="fixed">
<span id="app-icon"></div>
<span id="brand-icon"></div>
</div>
CSS:
/* Low density (120), mdpi */
#media screen and (-webkit-device-pixel-ratio: 0.75) {
#app-icon { background-image:url(pictures/ldpi/app-icon.png); }
#brand-icon { background-image:url(pictures/ldpi/brand-icon.png); }
}
/* Medium density (160), mdpi */
#media screen and (-webkit-device-pixel-ratio: 1) {
#app-icon { background-image:url(pictures/mpi/app-icon.png); }
#brand-icon { background-image:url(pictures/mdpi/brand-icon.png); }
}
/* High density (240), hdpi */
#media screen and (-webkit-device-pixel-ratio: 1.5) {
#app-icon { background-image:url(pictures/hdpi/app-icon.png); }
#brand-icon { background-image:url(pictures/hdpi/brand-icon.png); }
}
/* Extra high density (320), xhdpi */
#media screen and (-webkit-device-pixel-ratio: 2) {
#app-icon { background-image:url(pictures/xdpi/app-icon.png); }
#brand-icon { background-image:url(pictures/xdpi/brand-icon.png); }
}
If you want to filter through,
ORIENTATION - and (orientation: landscape)
Device WIDTH and (min-device-width : 480px) and (max-device-width : 854px)
Example:
#media screen and (-webkit-device-pixel-ratio: 1.5) and (min-device-width : 640px) and (max-device-width : 960px) and (orientation: landscape) {
/* Your style here */
}

You can also do this using a handlebars helper, which less code intensive and in my opinion the recommended method:
if (screen.width <= 480) {
imgFolder = 'img/low/';
}
else {
imgFolder = 'img/high/';
}
Handlebars.registerHelper('imgFolder', function () {
return imgFolder
});
while img/low/ and img/high contain images in different resolutions with the same name.
Then in your template:
<img src="{{imgFolder}}yourImage.png" />
Of course, you have to set the screen size values according to the devices your app targets.
Appendix:
If you do not have 1:1 pixel mapping in cordova browser (which is NOT recommended - your images will have a blurry/unsharp look) screen.width will differ from browsers width (window.innerWidth) and you have to use $(window).width() or window.innerWidth. You might be able to fix a wrong mapping using media queries.

Creating support for more sizes is a problem, but you can fix it with #media queries in CSS. Check this example code:
/* iPads (landscape) ----------- */
#media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape) {
/* Styles */
}
/* iPads (portrait) ----------- */
#media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : portrait) {
/* Styles */
}
/* Desktops and laptops ----------- */
#media only screen
and (min-width : 1224px) {
/* Styles */
}
/* Large screens ----------- */
#media only screen
and (min-width : 1824px) {
/* Styles */
}
With this code you can add support for all devices. Check this link for getting more code for more browsers
Functions which you can use:
Width and height: (min-device-width : 768px) and (max-device-width : 1024px)
Orientation: (orientation: landscape) or (orientation: portrait)
Device pixel ratio: (-webkit-device-pixel-ratio: 1.5)
EDIT:
HTML:
<div id="header" data-role="header" data-position="fixed">
<span id="app_icon" alt="app_icon" src="pictures/app_logo.png" display="inline" class="align-left"></span>
<span id="brand_icon" alt="brand_icon" src="pictures/company_logo.png" display="inline" class="align-right"></span><h1></h1>
</div>
Change img into span and add IDs.
CSS:
#media screen and (-webkit-device-pixel-ratio: 0.75) {
#app_icon {
width: 100px; /* Example size */
height: 100px; /* Example size */
background: url(pictures/app_logo_small.png);
}
}
#media screen and (-webkit-device-pixel-ratio: 1) {
#app_icon {
width: 150px; /* Example size */
height: 150px; /* Example size */
background: url(pictures/app_logo_medium.png);
}
}
#media screen and (-webkit-device-pixel-ratio: 1.5) {
#app_icon {
width: 200px; /* Example size */
height: 200px; /* Example size */
background: url(pictures/app_logo_large.png);
}
}
#media screen and (-webkit-device-pixel-ratio: 2) {
#app_icon {
width: 300px; /* Example size */
height: 300px; /* Example size */
background: url(pictures/app_logo_xlarge.png);
}
}
With this example you can change your code and fix it. Hope this help!

I have found I've had to start adding support for pixel ratios of 0.5, 1, 1.3, 1.5, 2 and 3 using these media queries.
Note I am using -webkit-min-device-pixel-ratio rather than -webkit-device-pixel-ratio.
I had found that on one of my test devices (Galaxy Tab 3 - 8") the pixel ratio was 1.3 and wasn't picking up any of the specific styles I had set in my phonegap app.
#media screen and (-webkit-min-device-pixel-ratio: 0.5) {
#app_icon {
width:64px;
height:64px;
background: url('../images/bigstart.png') no-repeat center bottom;
background-size: 64px 64px;
}
}
#media screen and (-webkit-min-device-pixel-ratio: 1) {
#app_icon {
width:64px;
height:64px;
background: url('../images/bigstart.png') no-repeat center bottom;
background-size: 64px 64px;
}
}
}
#media screen and (-webkit-min-device-pixel-ratio: 1.3) {
#app_icon {
width:64px;
height:64px;
background: url('../images/bigstart#2x.png') no-repeat center bottom;
background-size: 64px 64px;
}
}
#media screen and (-webkit-min-device-pixel-ratio: 1.5) {
#app_icon {
width:64px;
height:64px;
background: url('../images/bigstart#2x.png') no-repeat center bottom;
background-size: 64px 64px;
}
}
#media screen and (-webkit-min-device-pixel-ratio: 2) {
#app_icon {
width:64px;
height:64px;
background: url('../images/bigstart#2x.png') no-repeat center bottom;
background-size: 64px 64px;
}
}
#media screen and (-webkit-min-device-pixel-ratio: 3) {
#app_icon {
width:64px;
height:64px;
background: url('../images/bigstart#3x.png') no-repeat center bottom;
background-size: 64px 64px;
}
}

I think you have to divide the reported screen dimensions by the screen density to get the media query width and height dimensions.

Related

CSS Only Landscape not working portrait working

#media only screen and (min-width:300px) and (max-width:667px) and (orientation: portrait) {Class goes here}
#media only screen and (min-width:667px) and (max-width:768px) and (orientation: landscape) {class goes here}
portrait view working good but landscape not showing any change even media query can't see in inspect code also.
I actually tested the ranges:
#media only screen and (min-width:300px) and (max-width:667px) {
div {
background-color: red;
}
}
#media only screen and (min-width:667px) and (max-width:768px) {
div {
background-color: green;
}
}
They do work. But when I add the orientation, it fails to work on the portrait.
#media only screen and (min-width:300px) and (max-width:667px) and (orientation: portrait) {
div {
background-color: red;
}
}
#media only screen and (min-width:667px) and (max-width:768px) and (orientation: landscape) {
div {
background-color: green;
}
}
Try to remove one of the orientation on the media queries. It could solve the problem. If you still want to leave the orientation condition, test it on a real device instead of a simulating tool.

Multiple media queries aren't working

I'm a little bit confused because I'm used to do some CSS using media queries... I never had this problem before. Only the first media query is working well... I have few media queries working on specifics sizes like this :
/* - IPAD LANDSCAPE - */
#media screen and (max-width: 1024px) and (orientation: landscape){
header{
background-size: 28vw 30vh, 34vw 38vh;
background-position: right 24vw top 3.5vh, right 21vw top 1vh;
}
header object{
left:16vw;
width:18vw !important;
}
header p{
font-size:14px;
top:16vh;
left:-2vw;
}
}
/* - IPAD PORTRAIT - */
#media screen and (max-width: 768px) and (orientation: portrait){
header{
background-size: 28vw 30vh, 34vw 38vh;
background-position: right 28vw top 3.5vh, right 17vw top 1vh;
}
header object{
left:10vw;
width:24vw !important;
}
header p{
font-size:20px;
top:10vh;
left:-2vw;
}
}
/* - PHONE LANDSCAPE - */
#media screen and (max-width: 750px) and (orientation: landscape){
/*...*/
}
/* - PHONE PORTRAIT - */
#media screen and (max-width: 450px) and (orientation: portrait){
/*...*/
}
I tried with and without the orientation parameter... I can't even figure out why my code isn't working well...
I watched few topics on this but it didn't help me...
Thanks for helping :-)
EDIT:
I'm using Bootstrap for the first time, does it change something on media queries ?
EDIT 2:
I saw something like #media screen and (max-width:screen-sm-max) when we use Bootstrap, should I use this instead of pxvalue ? I think it will still the same...
Try to put the smallest #media queries width block of code first.
/* - PHONE PORTRAIT - */
#media screen and (max-width: 450px) and (orientation: portrait){
/*...*/
}
/* - PHONE LANDSCAPE - */
#media screen and (max-width: 750px) and (orientation: landscape){
/*...*/
}
/* - IPAD PORTRAIT - */
#media screen and (max-width: 768px) and (orientation: portrait){
header{
background-size: 28vw 30vh, 34vw 38vh;
background-position: right 28vw top 3.5vh, right 17vw top 1vh;
}
header object{
left:10vw;
width:24vw !important;
}
header p{
font-size:20px;
top:10vh;
left:-2vw;
}
}
/* - IPAD LANDSCAPE - */
#media screen and (max-width: 1024px) and (orientation: landscape){
header{
background-size: 28vw 30vh, 34vw 38vh;
background-position: right 24vw top 3.5vh, right 21vw top 1vh;
}
header object{
left:16vw;
width:18vw !important;
}
header p{
font-size:14px;
top:16vh;
left:-2vw;
}
}
It solved this type of problem for me. Boostrap doc is following this structure too. (here #screen-sm-min are variables that you can set thank to LESS/SASS, but you cant replace it by fixed number)
/* Extra small devices (phones, less than 768px) */
/* No media query since this is the default in Bootstrap */
/* Small devices (tablets, 768px and up) */
#media (min-width: #screen-sm-min) { ... }
/* Medium devices (desktops, 992px and up) */
#media (min-width: #screen-md-min) { ... }
/* Large devices (large desktops, 1200px and up) */
#media (min-width: #screen-lg-min) { ... }
Personally I use something like that if it could help you :
#media (max-width:767px) {}
#media (max-width:767px) and (orientation:landscape) {}
#media (min-width:768px) and (max-width:991px) {}

Bootstrap responsive on mobile devices

How can I set automatic line breaks on mobile devices? At the moment my code looks like:
HTML
<div class="container-fluid bg-1 text-center">
<h2>MessageOfTheDay</br>
</br></h2>
<p style="margin-bottom: 100px;">SOME LOREMIPSUMDOLORSITAMET,CONSECTETUR</p>
<h1 style="margin-bottom: 100px;">XXXXXX</br>
SOME LOREMIPSUMDOLORSITAMET,CONSECTETURSOME LOREMIPSUMDOLORSITAMET,CONSECTETUR</br>
SOME LOREMIPSUMDOLORSITAMET,CONSECTETURSOME LOREMIPSUMDOLORSITAMET,CONSECTETURSOME LOREMIPSUMDOLORSITAMET,CONSECTETUR</h1>
</div>
CSS
.bg-1{
background-color: black;
background-size: cover;
color: #ffffff;
height: auto;
min-height:620px;
padding:10px;
margin-top:0px;}
body {
font: 20px "Montserrat", sans-serif;
color: #f5f6f7;}
p {font-size: 20px;}
.margin {margin-bottom: 10px;}
h1,h2,h3{
margin-top: 0px;
margin-bottom: 0px;}
.container-fluid{
padding-top: 20px;
padding-bottom: 0px;}
h1{font-size: 50px;}
How can I fix truncate text? I want set automatic brake line on mobile.
Image
It would be a bit of a Janky fix, but this should work... Bootstrap allows us to display/hide information based screen size with built in media query's... so if you wanted to add a break at a specific point in the text, you could do something like the following:
<div class="visible-xs"><br /><br /></div>
or maybe this would even work, Not sure on the following so give it a shot and let us know if it worked for you:
<br class="visible-xs" />
the "visible-xs" class in bootstrap should make the content visible only if the screen size is less than 768px... the alternative is "hidden-xs" which hides content on smaller displays. :) Happy coding!
You can use media queries in CSS to do this. You would give the element that would be the higher up element, a class or id and then set its width to 100% and its display to inline-block or block when the screen is less than a certain size (or greater than a certain size).
With this code every .element will be 100% width then the screen size is 600px or less. if you wanted it to be when the screen is greater than or equal to 600px then you would use min-width: 600px instead.
#media (max-width: 600px) {
.element {
display: inline-block;
width: 100%;
}
}
<div class="container-fluid bg-1 text-center">
<h2>MessageOfTheDay</br>
</br></h2>
<p style="margin-bottom: 100px;" class='workdBreak'>SOME LOREMIPSUMDOLORSITAMET,CONSECTETUR</p>
<h1 style="margin-bottom: 100px;">XXXXXX</br>
<span class='workdBreak'>
SOME LOREMIPSUMDOLORSITAMET,CONSECTETURSOME LOREMIPSUMDOLORSITAMET,CONSECTETUR</br>
SOME LOREMIPSUMDOLORSITAMET,CONSECTETURSOME LOREMIPSUMDOLORSITAMET,CONSECTETURSOME LOREMIPSUMDOLORSITAMET,CONSECTETUR</h1>
</div>
</span>
#media only screen and (max-width : 480px) {
.workdBreak{
word-wrap:break-word;
}
}
Used word-wrap css property to break word if it is larger than width of container.
http://www.w3schools.com/cssref/css3_pr_word-wrap.asp
http://www.w3schools.com/cssref/css3_pr_word-break.asp
Bootsrap media query
/========== Mobile First Method ==========/
/* Custom, iPhone Retina */
#media only screen and (min-width : 320px) {
}
/* Extra Small Devices, Phones */
#media only screen and (min-width : 480px) {
}
/* Small Devices, Tablets */
#media only screen and (min-width : 768px) {
}
/* Medium Devices, Desktops */
#media only screen and (min-width : 992px) {
}
/* Large Devices, Wide Screens */
#media only screen and (min-width : 1200px) {
}
/*========== Non-Mobile First Method ==========*/
/* Large Devices, Wide Screens */
#media only screen and (max-width : 1200px) {
}
/* Medium Devices, Desktops */
#media only screen and (max-width : 992px) {
}
/* Small Devices, Tablets */
#media only screen and (max-width : 768px) {
}
/* Extra Small Devices, Phones */
#media only screen and (max-width : 480px) {
}
/* Custom, iPhone Retina */
#media only screen and (max-width : 320px) {
}

Responsive media query overwriting

I have wrote this media query for targeting 240*480 resolution
#media only screen and (min-width:240px)
and (max-width:480px) {
.speech-bubble-container {
right: 0 !important;
width: 100% !important;
}
}
another media query for 321*480 resolutions
#media only screen and (min-width : 321px)
and (max-width : 480px)
and (orientation :landscape) {
.speech-bubble-container {
right: -48px !important;
}
}
but when i test the website in 240*480 portrait mode device its right:0 property is not overwriting the right:-48px; -- how to achieve this?
I want to excute right:0 for 240*480 resolution device but instead of this it is overwriting by right:-48px;
I am new to responsive design.
Change your media queries like the following: SEE THE DEMO for reference. Resize the fiddle window to see it in action. When it's on portrait mode (width less than 320px), the right: 0; will be applicable while on landscape mode (width greater than 321px), the right: -48px; will be applied.
#media only screen and (max-width : 320px) {
.speech-bubble-container {
right: 0 !important;
width: 100% !important;
}
}
#media only screen and (min-width : 321px) {
.speech-bubble-container {
right: -48px !important;
}
}
Your media queries overlap. The first one it doesn't say '240x480'. It says from a range of minimum width of 240px to maximum width of 480 use these styles.
380px width falls in the above.

Switching CSS classes based on screen size

CSS newby here...
I'm looking at a responsive framework and imagining how I would accomplish different tasks.
Based on the size of the screen, they have classes added to the body tag such as:
.PhoneVisible, .DesktopVisible, etc...
They also have classes to make links into buttons :
.btn, small-button, med-button, large-button
I'm puzzled on how you would go about changing your CSS. I.E. something like:
<a href="#" class="MyButtonOptions">XXXX</>
.PhoneVisible .MyButtonOptions { btn small-button }
.TabletVisible .MyButtonOptions { btn med-button }
.DesktopVisible .MyButtonOptions { btn large-button }
Do you have to set the varying options individually?
i.e. .PhoneVisible .MyButtonOptions { height:30px; } ?
All advice appreciated!
CSS Media Queries are definetly the way to go.
You can easily separate your CSS based upon the browser size, pixel density, etc.
Here's a list of examples from CSS-Tricks.
/* Smartphones (portrait and landscape) ----------- */
#media only screen
and (min-device-width : 320px)
and (max-device-width : 480px) {
/* Styles */
}
/* Smartphones (landscape) ----------- */
#media only screen
and (min-width : 321px) {
/* Styles */
}
/* Smartphones (portrait) ----------- */
#media only screen
and (max-width : 320px) {
/* Styles */
}
/* iPads (portrait and landscape) ----------- */
#media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px) {
/* Styles */
}
/* iPads (landscape) ----------- */
#media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape) {
/* Styles */
}
/* iPads (portrait) ----------- */
#media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : portrait) {
/* Styles */
}
/* Desktops and laptops ----------- */
#media only screen
and (min-width : 1224px) {
/* Styles */
}
/* Large screens ----------- */
#media only screen
and (min-width : 1824px) {
/* Styles */
}
/* iPhone 4 ----------- */
#media
only screen and (-webkit-min-device-pixel-ratio : 1.5),
only screen and (min-device-pixel-ratio : 1.5) {
/* Styles */
}
Take a look at this https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries.
Another way is to attach the resize event some piece of "switch code".
Something like this: http://jsfiddle.net/s5dvb/
HTML
<div id="body" class="limit400">
<h1>Hey :D</h1>
</div>
CSS
.limit400 h1 { font-size:10px; }
.limit1200 h1 { font-size:50px; }
JS
$(window).on('resize', function() {
if($(window).height() > 400) {
$('#body').addClass('limit1200');
$('#body').removeClass('limit400');
}else{
$('#body').addClass('limit400');
$('#body').removeClass('limit1200');
}
})
About the frameworks, try http://purecss.io/ or http://getbootstrap.com/
Hope it helps.
Like Nej Kutcharian posted, you can use the above approach and just to relate it back to the class scenario. Rather than switching class you use the same class and change the styling it applies depending on the size of the screen.
As shown below, any element with the class "adjust-me-based-on-size" will have a margin-left and margin-right with differing values depending on the media size, so default is 15% but if the screen is between 800 and 1200 (px) it will have 10% instead and less 800px will have no right margin and a left margin of 5%.
.adjust-me-based-on-size{
margin-left: 15%;
margin-right: 15%;
}
#media only screen and (min-width: 800) and (max-width: 1200) {
.adjust-me-based-on-size {
margin-left: 10%;
margin-right: 10%;
}
}
#media only screen and (max-width: 800px) {
.adjust-me-based-on-size {
margin-left: 5%;
margin-right: 0%;
}
}

Resources