sass: how to render different images for mobile only - sass

I am not 100% clear on how to implement images for mobile only view that are different than the ones I have for desktop view
So for example, if I have this image for desktop:
&.card {
.card-image {
#include background-helper('gallery/old-pic.jpg', center, contain, no-repeat);
}
}
which comes from the mixin file where I have this code:
#mixin background-helper($image: false, $position: center, $size: contain, $repeat: no-repeat){
#if $image {
background-image: asset-url($image);
background-repeat: $repeat;
background-size: $size;
background-position: $position;
}
}
Not sure what logic to add that would tell my application to render something other than old-pic.jpg if the user is viewing it on a mobile phone.

It seems you have to use media queries.
for example:
$break-small: 320px;
$break-large: 1200px;
.card-image {
#media screen and (max-width: $break-small) {
#include background-helper('gallery/mobile-pic.jpg', center, contain, no-repeat);
}
#media screen and (min-width: $break-large) {
#include background-helper('gallery/old-pic.jpg', center, contain, no-repeat);
}
}

Related

How to make css rules applied when changing to landscape mode?

I need my page to adapt from portrait to landscape for Iphone X without having to reload the page.
Here are the media Queries I use:
// Screen size variables
$screen-sm-min: 576px; // Small tablets and large smartphones (landscape view)
$screen-lg-min: 992px; // Tablets and small desktops
//$screen-lg-min: 1024px;
$screen-xl-min: 1200px; // Large tablets and desktops
// Mixins
#mixin xs { #media (max-width: #{$screen-sm-min}),
(min-device-width : 375px) and (max-device-width : 667px),
(min-device-width : 414px) and (max-device-width : 736px),
(min-device-width : 375px) and (max-device-width : 812px) and (-webkit-device-pixel-ratio : 3)
{#content;} } // Tiny devices
#mixin md { #media (max-width: #{$screen-lg-min}), (min-device-width : 768px) and (max-device-width : 1024px),
(min-device-height : 1024px) and (max-device-width : 1366px)
{#content;} } // Medium devices
And here is a link to the page:
http://dev2.lemeilleurducbd.com/location_etu/home.html
I have looked on Google but I could not find an answer to this issue.
Thanks for your help
CSS solution
You can use orientation in media queries.
landscape rules apply when the browser window width is greater than height:
#media (orientation: landscape) {
...
}
portrait rules apply when browser window height is greater than width:
#media (orientation: portrait) {
...
}
JS solution (Source)
Note: Unfortunately this feature is not supported in safari.
You can listen to the orientationChange event for when the orientation changes, and read screen.orientation when you need to know the current orientation.
screen.addEventListener("orientationchange", function () {
console.log("screen orientation: " + screen.orientation);
});
Another option would be to listen to window resizes and compare the ratio of width and height.
if (width/height > 1) { //landscape } else { portrait }.
I recommend throttling the window resize listener.
I put a piece of javascript on the body tag, that was adapting the body width according to the windowWith, this is what was preventing to go on landscape mode without reloading the page..

Can I remove or ignore a defined sass function?

We are using Rails+Sprockets+Compass. Compass defines a linear-gradient function, which conflicts with the css function of the same name.
After our scss file does an #import "compass", is there a way to remove Compass's linear-gradient function so that I can insert a raw linear-gradient into css?
I know I can redefine the function, but I still can't figure out how to redefine it so that I can insert a raw linear-gradient. I want to remove the function entirely.
The problem is that we're migrating to libsass, which means that Compass's Ruby-based functions no longer work. So this
#import "compass";
.tmp {
button-background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
which I would like to be output as-is, compiles to this:
.tmp {
button-background: _linear-gradient_legacy(compact(to bottom), #fdefd4, #fdc154...);
}
where _linear-gradient_legacy is a Ruby-based compass function that will no longer be expanded under libsass.
Compass expects you to use the provided background and background-image functions whenever you use either of the gradient functions (linear/radial). This is how you get your prefixes. The reason why the functions involved are written in Ruby is so that you can get an SVG gradient for browsers that don't support gradients.
If you want absolutely none of that, just redefine the function like so:
#function linear-gradient($options...) {
#return #{'linear-gradient(#{$options})'};
}
Before redeclaring the function:
#import "compass/css3";
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
#include background(linear-gradient(to bottom, #fdefd4, #fdc154));
}
Output:
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZkZWZkNCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZkYzE1NCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #fdefd4), color-stop(100%, #fdc154));
background: -moz-linear-gradient(top, #fdefd4, #fdc154);
background: -webkit-linear-gradient(top, #fdefd4, #fdc154);
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
After:
#import "compass/css3";
#function linear-gradient($options...) {
#return #{'linear-gradient(#{$options})'};
}
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
#include background(linear-gradient(to bottom, #fdefd4, #fdc154));
}
Output:
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
Otherwise, you'll have to implement your own versions of the Ruby functions in Sass.

SASS compile error when using variable with media query

This is kind of simple, when compiling the following code fails with the error:
Line 6 of media.scss: Invalid CSS after "...ia (min-width: ": expected expression (e.g. 1px, bold), was "$desktop
Here is the code (as simple as possible):
$desktop: 1920px;
$tablet: 1024px;
$phone: 480px;
// Style adjustments for desktop size
#media (min-width: $desktop) {
}
// Style adjustments for tablet size
#media (min-width: $tablet) and (max-width: $desktop) {
}
// Style adjustments for phone size
#media (max-width: $phone) {
}
Is this a bug? Maybe it's not possible to use variables in media queries with SASS.
No problem with the code. Variables are possible in SASS 3.2. Link

Understanding Retina device CSS Media queries

I am working on a WordPress theme and am trying to incorporate retina enabled CSS queries into my CSS file.
I would just like to clarify that I have the media queries set up correctly before I change out all my background images.
I have doubled the size of all my background images and perfixed
them with the "#2x" naming convention. e.g icon-user#2x.png.
I have added a jQuery function into my code to swap out the images with the CSS class of hires.
In my CSS document I have a normal CSS class for a background image.
Normal CSS query
.side-nav .arrow {
background: url(../images/arrow-nav.png) no-repeat top left;
width: 5px;
height: 8px;
display: inline-block;
margin-left: 10px
}
Is this the correct way i would change the .side-nav .arrow class for a retina enabled device? When declaring the background size do I keep the size that of the original smaller image?
/* All Retina Ready devices larger than 1.5 pixel ratio */
#media only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5) {
.side-nav .arrow {
background-image:url(../images/arrow-nav#2x.png);
-webkit-background-size:5px 8px;
-moz-background-size:5px 8px;
-o-background-size:5px 8px;
background-size:5px 8px
}
}
jQuery Code
$(function () {
if (window.devicePixelRatio == 2) {
var images = $("img.hires");
/* loop through the images and make them hi-res */
for(var i = 0; i < images.length; i++) {
/* create new image name */
var imageType = images[i].src.substr(-4);
var imageName = images[i].src.substr(0, images[i].src.length - 4);
imageName += "#2x" + imageType;
/* rename image */
images[i].src = imageName;
}
}
});
Thank you
As long as there is some form of scaling taking place, like when you declare
<meta name="viewport" content="width=..."> (for android/ios/blackberry/WP8)
or
#ms-viewport {width: ... ;} (for non-WP8 IE10)
or ... even if you declare nothing most mobile devices will by default automatically scale such that viewport width=980px
then all CSS dimensions you declare with 'px' will exist in the same proportion to their viewport regardless of differences between their physical DPI/PPI
this means you shouldn't have to change a single thing about your style class except the background image's URL when the media query matches a high res device:
#media only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5),
only screen and (min-resolution: 144dpi) {
.side-nav .arrow {
background-image:url(../images/arrow-nav#2x.png);
}
}

Extract body class for use in Scss

I am learning Sass but a bit stuck trying to work something out. I'd like to have a unique background image and header image on different pages. How can I perhaps extract the body class name form the markup and interpret that in scss?
Essentially I require some way to prevent having to do this (which is totally the point of scss right?!)
body.page1 {
background: url(../img/bkg-page1.png) left top repeat-x;
header {
background: url(../img/header-page1.png) center top no-repeat;
height: 320px;
}
}
body.page2 {
background: url(../img/bkg-page2.png) left top repeat-x;
header {
background: url(../img/header-page2.png) center top no-repeat;
height: 320px;
}
}
I realise using variables is the right direction, but not sure how to relay the markup class to the scss.
Any pointers would be most appreciated.
What you're looking for is an #each loop:
#each $class in (page1, page2, page3) {
body.#{$class} {
background: url(../img/bkg-#{$class}.png) left top repeat-x;
header {
background: url(../img/header-#{$class}.png) center top no-repeat;
height: 320px;
}
}
}
This assumes that the class name corresponds to the image name, as indicated in your sample.
body.page1 {
background: url(../img/bkg-page1.png) left top repeat-x;
}
body.page1 header {
background: url(../img/header-page1.png) center top no-repeat;
height: 320px;
}
body.page2 {
background: url(../img/bkg-page2.png) left top repeat-x;
}
body.page2 header {
background: url(../img/header-page2.png) center top no-repeat;
height: 320px;
}
body.page3 {
background: url(../img/bkg-page3.png) left top repeat-x;
}
body.page3 header {
background: url(../img/header-page3.png) center top no-repeat;
height: 320px;
}
You could use a #for loop instead (which eliminates the need for the list of class names) if your class names are always going to have numbers at the end of their name.

Resources