My personal CSS/SCSS setup

My scss setup contains a base-size, BS, as general unit. I define 1 BS by dividing 100vw with the design-width. Any element using this unit will scale according to the screen width.

The base size unit BS

$BS: 100vw / 1980;

This means 1 BS resembles 1px of the screendesign width, but converted to the vw unit. What this allows me to do, is using the exact design pixel specification if needed. For example: If we have a screen designed on a canvas of 1980px width and there is a block of 600px width in it, i use $BS*600. This will be calculated to (100vw/1980*600) 30.3030vw. It's basically a simple percentage calculation.

Automated responsiveness

Furthermore there are a few scss mixins, which automatically adjust the BS according to the screen width (which usually is the device width) at changable breakpoints 500, 768, 1024, 1450 and 1980 (design-width). So, if there is no mobile design to work with, everything gets scaled down keeping the aspect ratio by default. Which is quite neat.

$BreakpointXSRelation: 1 / 500 * 1980;
$XSBS: $BS * $BreakpointXSRelation;

First I calculate the factor between the desired breakpoint and the screendesign width. In this case the factor between 500 and 1980 is 3.96. If i now multiply the BS by this factor, every element using BS accordingly will be scaled up times 3.96. This way not just the relations between elements won't be lost, but the general appearance of the website won't change either. Because once the screen width gets down to 500px, it will be 3.96 times smaller than the screendesign of 1980px. But at this point i multiply BS by the same factor 3.96 to even it out.

Set maximum width

Using the same method i can also set a maximum width, so the content doesn't scale up to be too large on big screens. The easiest example is using the design width as max-width. Because in this case i just have to do $BS = 1px at a viewport width of 1980px. On viewports wider than 1980px the design now is exactly the same as designed.

BS font-size taking rem into consideration

The font-size is also managed by a mixin which converts the BS value back to px after factoring also the unit rem in. This results in a font-size which is respecting the design and accessibility.

@mixin bsFontSize($BS, $value) {
 font-size: calc(1rem * #{$RemSizeFactor} + #{$BS} * #{$value} - #{$BaseRemSize} * 1px);
}

This might look a bit mind boggling at first glance, but is quite simple once you get behind it.

Let's look at this in a simplified way:

font-size: desiredFontSize - designDefaultSizeInPx + userDefaultSizeInPx;

So basically if the user's browser font-size is set to more than the usual 16px, this mixin will add the «more» and respectively would subtract the «less».

Downsides

Beside the need to adapt the thought process to a new unit, the only real downside is the possible glitches. Sometimes (at some screen sizes) two elements of $BS*600 width inside an element of $BS*1200 width won't exactly match borders and leave a thin line between them. This is because although i can use vw as unit, the browser is still bound to absolute pixels. Back to our example this could mean $BS*1200 is, displayed on the screen, 867px. The two child elements of $BS*600 width therefore would be 433.5px. But the browser is bound to absolute pixels and will either ceil or floor the 433.5px. That's why the glitches happen.

Long story short

Using this knot of different mixins, functions and variables i am able to create a website quite fast and even have a mobile version from the start. Which must be optimized, of course. A lot of it is already done though. This whole section block's SCSS incl. responiveness is basically as follows:

@mixin intro($type: "") {

 // get Basesize in correct relation to screen and design width
 $BS: getBaseSize($type);

 .intro {
  padding: $BS * 32;
  max-width: $BS * 1200;
  margin: 0 auto $BS * 128;
  @include bsFontSize($BS, 22);
 }

}


// Render basic styles as designed
@include intro();

// Render basic styles with breakpoints
@each $Breakpoint in $Breakpoints {
 @include breakpoint(#{$Breakpoint}) {
  @include intro(#{$Breakpoint});
 }
}

// Render custom styles with breakpoints
@include breakPointS() {
 $BS: getBaseSize("S");
}

Here, take it

If you found your webdev- or any other neurons to be tingled while reading this, please give it a try. Let me know whether you like it or you think it's total BS. Pun intended.

Github cyrill-lehmann.ch