I'm trying to use Foundation 5's new media queries. I created a foundation_overrides.scss file and added a link to its css file below the link to my app.css file in index.html head tag:
<link rel="stylesheet" href="stylesheets/app.css" />
<link rel="stylesheet" href="stylesheets/foundation-overrides.css" />
...here's app.scss:
#import "settings";
#import "foundation";
...and foundation-overrides.scss:
#media #{$small-up} {
body {background: red;}
}
#media #{$medium-up} {
body {background: orange;}
}
#media #{$large-up} {
body {background: yellow;}
}
#media #{$xlarge-up} {
body {background: green;}
}
#media #{$xxlarge-up} {
body {background: blue;}
}
Unfortunately this returns the following Sass error:
Syntax error: Undefined variable: "$small-up"
I've also tried uncommenting the #import "foundation/functions"; line from _settings.scss yet the error persists.
What do I need to change to use these media queries?
The reason its failing is because it can't find $small-up variable, or it doesn't exist. Also it will fail if the variable is defined after the media queries.
Try the following:
Make sure you are loading _settings.scss before your media
queries.
Make sure _settings.scss is properly imported: put a .test {} class in _settings.scss and see if it is in your generated css.
In _settings.scss make sure the variables are uncommented: for example uncomment this // $small-up: $screen;
Basically your sass should be in this order:
$small-up: $screen !default;
#media #{$small-up} { }
http://foundation.zurb.com/docs/media-queries.html
You've probably solved this by now but no answer as to what was the final cause of the issue was posted. First thing i would check is if you're sass is compiling to the correct css directory in your case 'stylesheets'. Also from your example you're clearly making an error in the name of your file. In your header you have foundation-overrides.css but your sass file is "foundation_overrides.scss". What seems most likely is that you need to change your hyphen to an underscore in your link rel name.
Related
In my layout.scss I have the following code:
#media(max-width:1100px) {
#wrap-nav .nav {#extends .block;} # Comes from generic scss file
}
in my main styles.scss I import that file, it looks like this:
#import "layout.scss";
#wrap-nav .nav {display:flex;}
I have no idea why but with a 1920px width I still see SCSS compiling this as
#wrap-nav .nav {
display: block;
}
but it shouldn't be compiled without the media query, should it? Am I missing something here?
There is a variables.scss file in a project which defines a variable and assigns it a color like this:$contrast: #edebe4The current use of the $contrast variable is to set other variables within the variables.scss file.
Now there is a specific .vue file that's used to render data to the browser and it contains this line of code in its template:<div style="background-color: #edebe4">
When I change that line to<div style="background-color: $contrast">the desired background color disappears from that element.
Is there a way to get that element to recognize the $contrast variable so that whenever the value of $contrast is changed that change flows through automatically to this element?
You can make scss variables available globally (in each component). Just add this to vue.config.js:
css: {
loaderOptions: {
scss: {
additionalData: `#import "~#/variables.scss";`
}
}
}
More info here
Just import variables.scss into your .vue
...
<style lang="scss">
#import "variables.scss"
</style>
This worked -
in variables.scss file added
.contrast-background {
background-color: $contrast;
}
in .vue file changed element to this
<div class="contrast-background">
Amendment -
Here is the final solution that was implemented, which was made possible by #Finn's post -
Changes to .vue file:
added this
<style lang="scss" scoped>
#import "#/layout/design/variables.scss";
.contrast-background {
background-color: $contrast;
}
</style>
and changed element to this
<div class="contrast-background">
This approach avoids changes to the variables.scss file.
I am using SASS, Compass, Bourbon and Neat to create a wonderful responsive website.
However, it has dawned on me that IE8 (with its lack of Media Query support) would simply output the mobile version only, because I am using the mobile first approach.
Is there any way to use SASS to generate styles for IE8 automatically, with all the largest media queries converted as the default? I'd like IE8 to get the full desktop look only.
I want to avoid using scripts like respond.js, due to performance and also maintenance down the line.
Solution:
I am using Compass with the Bourbon SASS library. Bourbon has a media() mixin that I wanted to use.
Following on from the selected answer below, I ended up creating a simple wrapper mixin for the media() mixin provided by bourbon.
#mixin bp($bp) {
#if $desktop-only {
#content;
}
#else {
#include media($bp) {
#content;
}
}
}
In my ie.scss file (used by Compass) I set the $desktop-only variable to true. This removes the media query itself and simply places in the attributes that would have been within the query. Because their order is later in the compiled CSS, it takes precedence over the mobile only setting and IE then uses that style.
It results in a slightly bloated CSS fie, but it's worth it as no additional scripts are needed to make it render the desktop version.
I've written a solution for this myself. All you need is two different CSS files (one for modern browsers and one for older IE browsers) and a cleaver mixin.
Create a second SASS file which Compass can watch and call the file something like oldIE.scss. Copy all the imports from you original SASS file (styles.scss or whatever) to this file. Then put a new variable in both of them: $compile-IE. Set the values like this:
styles.scss
$compile-IE: false;
#import "all your other imports"
oldIE.scss
$compile-IE: true;
#import "all your other imports"
Compass will now create two different CSS files for you. You can place them in the HEAD of your Markup like this:
<link type="text/css" href="styles.css" rel="stylesheet" media="all" />
<!--[if (gte IE 6) & (lte IE 8)]>
<link type="text/css" href="oldIE.css" rel="stylesheet" media="all" />
<![endif]-->
Once you have the two files in place, you can start writing SASS with your breakpoints thanks to the following mixin:
// ----- Media-queries ----- //
$breakpoints: S 480px, M 600px, L 769px;
#mixin bp($bp) {
// If compile-IE is true (IE8 <=) then just use the desktop overrides and parse them without #media queries
#if $compile-IE {
#content;
}
// If compile-IE is false (modern browsers) then parse the #media queries
#else {
#each $breakpoint in $breakpoints {
#if $bp == nth($breakpoint, 1) {
#media (min-width: nth($breakpoint, 2)) {
#content;
}
}
}
}
}
Call the mixin as following:
p {
color: blue;
font-size: 16px;
#include bp(L) {
font-size: 13px;
}
}
Now, if the variable $compile-IE is false (for modern browsers) the output will be this:
p {
color: blue;
font-size: 16px; }
#media (min-width: 768px) {
p {
font-size: 13px;
}
}
And when the variable $compile-IE is true (for older IE versions) the output will be this:
p {
color: blue;
font-size: 16px;
font-size: 13px;
}
Because the font-size: 13px is the parsed after the font-size: 16px the styles used for larger viewports (like bp L) will override the default mobile styling.
Hope this will help for you! :)
Since there are many ways to implement CSS3 Media Queries into a website, I would like to know which one is recommended by more experienced web designers. I can think of a couple:
1. All in one Stylesheet
There is a default style which applies to all screen widths, and media queries that apply only to lower screen widths and overwrite the default, all in one file. For example:
HTML
<link rel="stylesheet" href="main.css">
main.css
article
{
width: 1000px;
}
#media only screen and (max-width: 1000px)
{
article
{
width: 700px;
}
}
(please keep in mind that this is just an example)
Pros:
Default style applies to older browsers
Only one HTTP request required
Cons:
Gets messy with a lot of code
Some browsers will have to download code that they won't apply
2. Separate Stylesheets
There are separate stylesheets containing full code tailored for each screen width. Browsers only load the one that applies. For example:
HTML
<link rel="stylesheet" href="large-screen.css" media="screen and (min-width: 1001px)"> /*Also older browsers*/
<link rel="stylesheet" href="small-screen.css" media="only screen and (max-width: 1000px)">
large-screen.css
article
{
width: 1000px;
}
small-screen.css
article
{
width: 700px;
}
Pros:
Neat and organized
Only one HTTP request required
Browsers only load what they need
Cons:
(This is why I'm hesitant to use this:) When one makes a change that applies to all screen widths, the change has to be copied and pasted to the appropriate spots in all of the stylesheets.
3. Separate Stylesheets, one Global Stylesheet
The same as #1, but the global style and the media queries are in separate stylesheets. For example:
HTML
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="small-screen.css" media="only screen and (max-width: 1300px)">
main.css
article
{
width: 1000px;
}
small-screen.css
article
{
width: 700px;
}
Pros:
Also neat and managable
Does not have problem of #2 when making global changes
Global style applies to older browsers
Cons:
Smaller screen-widths require 2 HTTP requests
That's all I can think of. How should media queries be managed?
Thanks for any responses.
Well, I certainly can't claim to be an authority on the matter (I'm still learning about coding conventions myself), but I actually lean towards option #1 - a single stylesheet. I'm thinking of a specific implementation of it, though. Instead of having a single break point for each case of screen size you need new styles for, I'd suggest multiple break points - one for the CSS styles of each module where multiple screen sizes need to be addressed.
Ah...that might have been a slightly confusing statement. An example is in order...
Rather than something like:
/*default styles:*/
/*header styles*/
.header-link{ ... }
.header-link:active{ ... }
.header-image{ ... }
.header-image-shown{ ... }
.header-table-cell{ ... }
/*content styles*/
.content-link{ ... }
.content-link:active{ ... }
.content-image{ ... }
.content-image-shown{ ... }
.content-table-cell{ ... }
/*footer styles*/
.footer-link{ ... }
.footer-link:active{ ... }
.footer-image{ ... }
.footer-image-shown{ ... }
.footer-table-cell{ ... }
/*alternate styles for smaller screens:*/
#media only screen and (max-width: 1000px){
/*header styles*/
.header-link{ ... }
.header-image{ ... }
.header-image-shown{ ... }
.header-table-cell{ ... }
/*content styles*/
.content-link{ ... }
.content-image{ ... }
.content-image-shown{ ... }
.content-table-cell{ ... }
/*footer styles*/
.footer-link{ ... }
.footer-image{ ... }
.footer-image-shown{ ... }
.footer-table-cell{ ... }
}
I'd suggest option #1, just implemented as so:
/*default header styles*/
.header-link{ ... }
.header-link:active{ ... }
.header-image{ ... }
.header-image-shown{ ... }
.header-table-cell{ ... }
/*alternate header styles for smaller screens*/
#media only screen and (max-width: 1000px){
.header-link{ ... }
.header-image{ ... }
.header-image-shown{ ... }
.header-table-cell{ ... }
}
/*default content styles*/
.content-link{ ... }
.content-link:active{ ... }
.content-image{ ... }
.content-image-shown{ ... }
.content-table-cell{ ... }
/*alternate content styles for smaller screens*/
#media only screen and (max-width: 1000px){
.content-link{ ... }
.content-image{ ... }
.content-image-shown{ ... }
.content-table-cell{ ... }
}
/*default footer styles*/
.footer-link{ ... }
.footer-link:active{ ... }
.footer-image{ ... }
.footer-image-shown{ ... }
.footer-table-cell{ ... }
/*alternate footer styles for smaller screens*/
#media only screen and (max-width: 1000px){
.footer-link{ ... }
.footer-image{ ... }
.footer-image-shown{ ... }
.footer-table-cell{ ... }
}
(All the classes are placeholders. I'm not very creative...)
Though this means you'll be doing the same media query declaration multiple times (leading to a bit more code), it's a lot more handy for testing out single modules, which will overall help the maintainability of your site as it gets bigger. Try adding multiple real styles, more tags/classes/id's to the example I gave, and maybe add a bit more whitespace to them, and you'll see soon see how much quicker it is to narrow down and change/append styles (across all screen sizes) in the implementation shown by the second part of the example.
And I credit this answer quite completely to information from Scalable and Modular Architecture for CSS, by Jonathan Snook. (After all, there's no way a beginner like me would be able to figure out and reason an answer like that all by myself!) As quoted from one of the many relevant parts of that book,
"...instead of having a single break point, either in a main CSS file or in a seperate media query style sheet, place media queries around the module states."
Though, if by personal preference or other you'd rather not use this approach, then you're free to go with any of the other options you proposed - after all, Snook himself says that his book "is more style guide than rigid framework", so don't feel like this is a coding standard. (Though I feel it should be. XD)
I believe in "putting code where you expect it". If a style needs overruling I would want my code that overrules to be as close to the default style, thus in the same document. That way, a year from now, I will still know what's going on when I look at the code. In the other approach (separate css file per breakpoint) I will need to remember to goo look for overruling styles code in a separate file. Not a problem, unless I forget I did it that way a year from now. Guess it's personal preference and the browser doesn't care.
If you want to use the 2nd option there's a way to avoid "copy+pasting" the global styles that you need for both your mobile and desktop versions of the site which is veeeeeery handy and helps you keep everything more organized in my opinion and that is using SASS.
You could have something like that:
> CSS Folder
> Sass folder
- _global.scss
- _mobile_layout.scss
- _desktop_layout.scss
- main_mobile.scss
- main_desktop.scss
which will compile into
> CSS Folder
- main_mobile.css
- main_desktop.css
Hope you find it useful ^^
I recently implemented this technique with SASS 3.2 using #content blocks on a project I've been working on, and I've just gotten to the point where I need to include support for older browsers such as IE7 and 8.
Example:
.overview {
padding: 0 0 19px;
#include respond-to(medium-screens) {
padding-top: 19px;
} //medium-screens
#include respond-to(wide-screens) {
padding-top: 19px;
} //medium-screens
}
They both don't support media queries, and I've often handled this in the past by serving up all styles to these browsers when I had my media queries separated into separate partial files such as _320.scss, _480.scss and in my IE stylesheet loading them like so:
#import 320.scss;
#import 480.scss;
etc.
Which would load all styles, and always assign IE7 - 8 a 940px (or whatever the max width is) layout and styles. By nesting styles in SASS 3.2 inline like this, it eliminates the need for separate partial stylesheets, but totally screws up how I load styles for IE.
Any ideas or solutions on how to combat this? I could use a polyfill such as respond.js to force IE to use media queries, but would prefer to just serve up a non-flexible site to IE.
Any ideas on either how to best organize these files, or a better solution?
You can generate a separate stylesheet for IE<9 that contains everything your normal sheet has, but with flattened media queries based on a set width.
Full explanation here http://jakearchibald.github.com/sass-ie/, but basically you have this mixin:
$fix-mqs: false !default;
#mixin respond-min($width) {
// If we're outputting for a fixed media query set...
#if $fix-mqs {
// ...and if we should apply these rules...
#if $fix-mqs >= $width {
// ...output the content the user gave us.
#content;
}
}
#else {
// Otherwise, output it using a regular media query
#media screen and (min-width: $width) {
#content;
}
}
}
Which you'd use like this:
#include respond-min(45em) {
float: left;
width: 70%;
}
This would be inside all.scss, which would compile down to all.css with media queries. However, you'd also have an additional file, all-old-ie.scss:
$fix-mqs: 65em;
#import 'all';
That simply imports all, but flattens media query blocks given a fake width of 65em.
I use LESS for a lot of my work, but on larger projects, with many people working across files, I don't like using breakpoint files, such as 1024.less.
My and my team use a modular approach, such as header.less which contains all the code for just the header, including the associated breakpoints.
To get round IE problems (we work in a corporate environment), I use this approach:
#media screen\9, screen and (min-width: 40em) {
/* Media queries here */
}
The code inside the media query is always executed by IE7 and less. IE9 and above obeys the media queries like a proper browser should. The problem is IE8. To solve this, you need to make it behave like IE7
X-UA-Compatible "IE=7,IE=9,IE=edge"
I've found this doesn't always work if set in the metatags in the HTML, so set it using the server headers.
See the gist here:
https://gist.github.com/thefella/9888963
Making IE8 act like IE7 isn't a solution that works for everyone, but it suits my needs.
Jake Archibald has the best technique I've seen to date for achieving this. This technique automatically creates a separate stylesheet for IE, with all the same styles inside of your media queries but without the media query itself.
I also campaigned to get this technique built into the popular breakpoint extension for Sass, if you're interested in using that!
If you wanted to keep everything under one roof and only have a single http request for your older browser visitors you could do something like this
Setting up your initial respondto mixin
// initial variables set-up
$doc-font-size: 16;
$doc-line-height: 24;
// media query mixin (min-width only)
#mixin breakpoint($point) {
#media (min-width: $point / $doc-font-size +em) { #content; }
}
this will create a min-width media query and output your px value ($point) as an em value.
From this you'd need to create this mixin
#mixin rwdIE($name, $wrapper-class, $IE: true) {
#if $IE == true {
.lt-ie9 .#{$wrapper-class} {
#content;
}
.#{$wrapper-class} {
#include breakpoint($name) {
#content;
}
}
}
#else if $IE == false {
.#{$wrapper-class} {
#include breakpoint($name) {
#content;
}
}
}
}
Here if you pass a piece of Sass(SCSS) like this
#include rwdIE(456, test) {
background-color: #d13400;
}
it will return this code
.lt-ie9 .test {
background-color: #d13400;
}
#media (min-width: 28.5em) {
.test {
background-color: #d13400;
}
}
This will give you the you the IE and 'new browser' CSS in one file. If you write -
#include rwdIE(456, test, false) {
background-color: #d13400;
}
You will get -
#media (min-width: 28.5em) {
.test {
background-color: #d13400;
}
}
I hope this helps, I've got this on a codepen here too - http://codepen.io/sturobson/pen/CzGuI
There is a CSS3 Mixin I use that has a variable for IE filters. You could do something similar by having a global variable, $forIE or something, wrap the media query mixin within an if and then generate the stylesheet with or w/o the queries.
#if $forIE == 0 {
// Media Query Mixin
}
Or use the #if to import a 3rd scss (_forIE.scss?) that will override things with your IE specific styles.