Pixels and ems in SCSS

I’ve been transferring over CSS to SCSS, and while doing so, I’ve encountered something I find quite odd. I’ve noticed that SCSS isn’t so accepting of ems in media queries, and I’m not sure why.

for example: I have my mixin:

@mixin bp($point){
	$bp-mobile: 	"(min-width: 22.857em)";
	$bp-m-land: 	"(min-width: 28.571em)"; 
	$bp-sm-tablet: 	"(min-width: 42.500em)"; 
	$bp-tablet: 	"(min-width: 49.286em)"; 
	$bp-desktop: 	"(min-width: 68.571em)";
	$bp-x-desktop: 	"(min-width: 91.429em)"; 
	$bp-xx-desktop:	"(min-width: 120.000em)"; 
	$bp-xxx-desktop:"(min-width: 137.143em)";

	@if $point == mobile{
		@media #{$bp-mobile}{@content;}
	} 
	@if $point == m-land{
		@media #{$bp-m-land}{@content;}
	} 
	@if $point == sm-tablet{
		@media #{$bp-sm-tablet}{@content;}
	} 
	@if $point == desktop{
		@media #{$bp-desktop}{@content;}
	} 
	@if $point == x-desktop{
		@media #{$bp-x-desktop}{@content;}
	} 
	@if $point == xx-desktop{
		@media #{$bp-xx-desktop}{@content;}
	} 
	@if $point == xxx-desktop{
		@media #{$bp-xxx-desktop}{@content;}
	} 
}

When I go to include this mixin into my style sheets, it ignores the query, however if add the @mixin as:

@mixin bp($point){
	$bp-mobile: 	"(min-width: 320px";
	
	@if $point == mobile{
		@media #{$bp-mobile}{@content;}
	} 
}

It seems to work, I was hoping someone could tell me why.

They only thing I can find on this is to put a pixel to ems converter in my styles: for example: converts pixels to ems

I’m hoping some can elaborate more on this.

Give us your broken browser-outputted CSS (remember, SCSS just converts the SCSS to regular CSS that isn’t an abomination.)

It’ll be easier to debug if we can see what the browser is rendering; the browser will muddle through the crap that is SCSS and show us the goodies/output (CSS).

This one breaks while using ems:

@media (min-width: 22.857em) {
  #toggle-nav-button {
    display: block;
    position: absolute;
    top: 1%;
    left: 6%;
    color: white;
    padding: 10px 14px;
    background: #003D77;
    text-decoration: none;
  }

  .cbp-hrmenu {
    width: 100%;
    background: #034C9E;
    z-index: 9999;
    position: relative;
    top: 0;
  }

  .cbp-hrmenu ul {
    margin: 0 5px !important;
    list-style-type: none;
    max-height: 100%;
    transition: max-height 30ms ease;
    overflow: hidden;
  }

  #cbp-hrmenu ul.initial-state {
    max-height: 0;
  }

  .cbp-hrmenu>ul,.cbp-hrmenu .cbp-hrsub-inner {
    margin: 0 auto;
  }

  .cbp-hrmenu>ul>li {
    display: block;
    border-bottom: 1px solid;
    line-height: 18px;
    margin-bottom: 0;
  }

  .cbp-hrmenu>ul>li>a {
    font-weight: 700;
    padding: 1.5em 2em;
    color: #FFDD00;
    display: block;
    text-align: center;
  }

  .cbp-hrmenu>ul>li>a:hover {
    color: #47a3da;
  }

  .cbp-hrmenu>ul>li.cbp-hropen a,.cbp-hrmenu>ul>li.cbp-hropen>a:hover {
    color: #fff;
    background: #003D77;
  }

  .cbp-hrmenu .cbp-hrsub {
    display: none;
    position: absolute;
    background: #003D77;
    width: 100%;
    left: 0;
    z-index: 9999;
    overflow-x: hidden;
  }

  .cbp-hropen .cbp-hrsub {
    display: block;
    padding-bottom: 3em;
  }

  .cbp-hrmenu .cbp-hrsub-inner>div {
    float: left;
    padding: 0 1em 0;
  }

  .cbp-hrmenu .cbp-hrsub-inner:before,.cbp-hrmenu .cbp-hrsub-inner:after {
    content: " ";
    display: table;
  }

  .cbp-hrmenu .cbp-hrsub-inner:after {
    clear: both;
  }

  .cbp-hrmenu .cbp-hrsub-inner>div a {
    line-height: 1.95em;
  }

  .cbp-hrmenu .cbp-hrsub-inner>div a:hover {
    line-height: 1.75em;
    color: #47a3da;
  }

  .cbp-hrsub h4 {
    color: #FFDD00 !important;
    padding: 1em 0 0.5em;
    margin: 0;
    font-size: 120%;
    font-weight: 300;
  }

  .menuBar {
    display: inline-block;
    margin-top: 0;
  }
}

I took out the basic css, and gave you what I'm putting in the query that keeps breaking in ems:

This is the one in pixels:

@media (min-width: 300px) {
  #toggle-nav-button {
    display: block;
    position: absolute;
    top: 1%;
    left: 6%;
    color: white;
    padding: 10px 14px;
    background: #003D77;
    text-decoration: none;
  }

  .cbp-hrmenu {
    width: 100%;
    background: #034C9E;
    z-index: 9999;
    position: relative;
    top: 0;
  }

  .cbp-hrmenu ul {
    margin: 0 5px !important;
    list-style-type: none;
    max-height: 100%;
    transition: max-height 30ms ease;
    overflow: hidden;
  }

  #cbp-hrmenu ul.initial-state {
    max-height: 0;
  }

  .cbp-hrmenu>ul,.cbp-hrmenu .cbp-hrsub-inner {
    margin: 0 auto;
  }

  .cbp-hrmenu>ul>li {
    display: block;
    border-bottom: 1px solid;
    line-height: 18px;
    margin-bottom: 0;
  }

  .cbp-hrmenu>ul>li>a {
    font-weight: 700;
    padding: 1.5em 2em;
    color: #FFDD00;
    display: block;
    text-align: center;
  }

  .cbp-hrmenu>ul>li>a:hover {
    color: #47a3da;
  }

  .cbp-hrmenu>ul>li.cbp-hropen a,.cbp-hrmenu>ul>li.cbp-hropen>a:hover {
    color: #fff;
    background: #003D77;
  }

  .cbp-hrmenu .cbp-hrsub {
    display: none;
    position: absolute;
    background: #003D77;
    width: 100%;
    left: 0;
    z-index: 9999;
    overflow-x: hidden;
  }

  .cbp-hropen .cbp-hrsub {
    display: block;
    padding-bottom: 3em;
  }

  .cbp-hrmenu .cbp-hrsub-inner>div {
    float: left;
    padding: 0 1em 0;
  }

  .cbp-hrmenu .cbp-hrsub-inner:before,.cbp-hrmenu .cbp-hrsub-inner:after {
    content: " ";
    display: table;
  }

  .cbp-hrmenu .cbp-hrsub-inner:after {
    clear: both;
  }

  .cbp-hrmenu .cbp-hrsub-inner>div a {
    line-height: 1.95em;
  }

  .cbp-hrmenu .cbp-hrsub-inner>div a:hover {
    line-height: 1.75em;
    color: #47a3da;
  }

  .cbp-hrsub h4 {
    color: #FFDD00 !important;
    padding: 1em 0 0.5em;
    margin: 0;
    font-size: 120%;
    font-weight: 300;
  }

  .menuBar {
    display: inline-block;
    margin-top: 0;
  }
}

Is there a website you can link us where it shows hte issue? The query is valid so perhaps it’s not targeting the screen sizes you want and there’s a misunderstanding there.

This isn’t related to your problem but I highly recommend using breakpoint. One of the best features is breakpoints can be nested in other rules which results in more clear, readable code. Not to mention there is a means of isolating styles to support browsers that lack media query support. If you want to take it further I recommend checking out susy which is a grid library for sass that integrates directly with breakpoint.

Thanks @oddz, I will definitely look into susy for my upcoming project. I was reading that it said Susy is built to coincide with Compass. Do you know if it’s a must to use Compass with Susy?

@RyanReese, I found my problem, I was missing a bracket! :stuck_out_tongue: off all the things I missed… a bracket! Apparently all I needed was break from staring at code. Thanks though!

1 Like

Must have been in a code block you didn’t post because I didn’t see any missing bracket, and the outputted CSS from your example validated :slight_smile: . Glad you figured it out.

and back to square one… I can’t seem to figure out what I’m missing as to why ems are not working.

Here is a link to my navigation. It seems to break on the smallest screen and the sm-tablet screen, and I just can’t see where. This is making me insane!

All your media queries for small screens are like so

@media (min-width: 21.429em)

What do you expect to happen if users are under that screen size? There are no media queries in place for the smallest screen users.

At around 16px font size (just an example), that would be around 342px min-width. Many smart phones are 320ish or even as low as 280.

This is why I do not like em for media queries. Unnecessarily complicates matters.

normally I’ve never set a min-width for small screens. I usually start at landscape size so 400px and up generally. Would that make a difference with SCSS?

SCSS is CSS.

So perhaps…

$bp-mobile: 	"(min-width: 22.857em)";

Needs to just be made into max-width…I dunno how you plan on overriding smaller styles or whatnot…or roll the styles onto larger screens and let the larger styles override the smaller. Depends on what you plan to do.

You seem to have a lot of breakpoints…more than probably is necessary.

I work from mobile first, if that helps. My problem is not the number of queries, some of those queries serve other purposes, not necessarily intended for the navigation. Even if I don’t give my smallest area (mobile) a defined query, which immediately fixes my problem, it still causes issues in my small tablet query. I’m not sure why but it doesn’t like seem to like ems, but it responds nicely to pixels. This is what I’m not comprehending.

I think you just need to lower the smallest media query.
Look at this

$bp-mobile: 	"(min-width: 320px";

That is what you need to at least emulate on hte ems
This is what you have for ems

$bp-mobile: 	"(min-width: 22.857em)";

Which can easiliy be calculated over. 22.857*16px = 365. That won’t target mobile at all. All other calculations are screwed up from that.

What is your font size? You have incorrect calculations it seems.

font-size:14px;
line-height:21px;

If take 320px and convert it to ems at my base pixel size of 14 I get 22.857em.

Your website is referencing “(min-width: 21.429em)” which seems to have fixed that issue. Though with font-size:100% it will base it off the user font size so it could very well again break if users have larger font sizes set.

http://consolidatedgypsum.ca/navigation/

I just find it weird that it works in pixels and not in ems. I’m going to try and see if reset my font size to standard browser size and see if that works better.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.