3 different files you can drop into your next responsive project.
A Pen by William Riley on CodePen.
3 different files you can drop into your next responsive project.
A Pen by William Riley on CodePen.
<div id="hero" class="panel"> | |
<div class="container"> | |
<h1>Hello, from a responsive hero</h1> | |
</div> | |
</div> | |
<div id="section1" class="panel"> | |
<div class="container"> | |
<h1>Hello, from the next panel</h1> | |
</div> | |
</div> | |
<div id="footer" class="panel"> | |
<div class="container"> | |
<h1>Built with love, by <a href="http://www.twitter.com/bill_riley">@bill_riley</a> at <a href="http://mashthekeyboard.com">Mash the Keyboard</a></h1> | |
</div> | |
</div> |
// silence is golden |
@import "compass"; | |
/* | |
_responsive.sass | |
This file has two mixins, one for mobile first approach, and the other for a desktop first approach (traditional responsive) | |
*/ | |
// most phones (landscape), most phones (portrait) | |
$break-xs: 480px; | |
// most tablets (portrait), some phones (landscape) | |
$break-sm: 740px; | |
// most tablets (landscape), some tablets (portrait) | |
$break-md: 992px; | |
// small Desktops, some tablets (landscape) | |
$break-lg: 1200px; | |
// TV, large desktops | |
$break-xlg: 1600px; | |
// building a mobile first approach? Use this! Coding mobile first has its merits: it'll cut down on code size and help you focus on the mobile experience first -- which has tangible value, depending. | |
@mixin respond-to-min($media) { | |
@if $media == "xs" { | |
@media (min-width: $break-xs) { | |
@content; | |
} | |
} | |
@else if $media == "sm" { | |
@media (min-width: $break-sm) { | |
@content; | |
} | |
} | |
@else if $media == "md" { | |
@media (min-width: $break-md) { | |
@content; | |
} | |
} | |
@else if $media == "lg" { | |
@media (min-width: $break-lg) { | |
@content; | |
} | |
} | |
@else if $media == "xlg" { | |
@media (min-width: $break-xlg) { | |
@content; | |
} | |
} | |
@else { | |
@media (min-width: $media) { | |
@content; | |
} | |
} | |
} | |
// Otherwise, use the traditional responsive set up! The rest of the code depends on this mixin. | |
@mixin respond-to($media) { | |
@if $media == "xs" { | |
@media (max-width: $break-xs) { | |
@content; | |
} | |
} | |
@else if $media == "sm" { | |
@media (max-width: $break-sm) { | |
@content; | |
} | |
} | |
@else if $media == "md" { | |
@media (max-width: $break-md) { | |
@content; | |
} | |
} | |
@else if $media == "lg" { | |
@media (max-width: $break-lg) { | |
@content; | |
} | |
} | |
@else if $media == "xlg" { | |
@media (max-width: $break-xlg) { | |
@content; | |
} | |
} | |
@else { | |
@media (max-width: $media) { | |
@content; | |
} | |
} | |
} | |
/* | |
_responsive-helpers.sass | |
Responsive helpers, hide and display things with a css class. Also leverages Modernizer for touch and no touch -- this helps if you want to include videos for animations on desktops, but none of that crappy fullscreen playback I've fought before on iOS devices. I don't have these coded for the responsive TV sizes. | |
*/ | |
.show-xs { display: none; } | |
.show-sm { display: none; } | |
.show-md { display: none; } | |
.show-lg { display: block; } | |
.hide-xs { display: block; } | |
.hide-sm { display: block; } | |
.hide-md { display: block; } | |
.hide-lg { display: none; } | |
@include respond-to(lg) { | |
.show-xs { display: none; } | |
.show-sm { display: none; } | |
.show-md { display: none; } | |
.show-lg { display: block; } | |
.hide-xs { display: block; } | |
.hide-sm { display: block; } | |
.hide-md { display: block; } | |
.hide-lg { display: none; } | |
} | |
@include respond-to(md) { | |
.show-xs { display: none; } | |
.show-sm { display: none; } | |
.show-md { display: block; } | |
.show-lg { display: block; } | |
.hide-xs { display: block; } | |
.hide-sm { display: block; } | |
.hide-md { display: none; } | |
.hide-lg { display: none; } | |
} | |
@include respond-to(sm) { | |
.show-xs { display: none; } | |
.show-sm { display: block; } | |
.show-md { display: block; } | |
.show-lg { display: block; } | |
.hide-xs { display: block; } | |
.hide-sm { display: none; } | |
.hide-md { display: none; } | |
.hide-lg { display: none; } | |
} | |
@include respond-to(xs) { | |
.show-xs { display: block; } | |
.show-sm { display: block; } | |
.show-md { display: block; } | |
.show-lg { display: block; } | |
.hide-xs { display: none; } | |
.hide-sm { display: none; } | |
.hide-md { display: none; } | |
.hide-lg { display: none; } | |
} | |
.touch { | |
.show-touch { | |
display: block !important; | |
video { | |
display: block !important; | |
} | |
} | |
.hide-touch { | |
display: none !important; | |
video { | |
display: none !important; | |
} | |
} | |
} | |
.no-touch { | |
.show-touch { | |
display: none !important; | |
video { | |
display: none !important; | |
} | |
} | |
.hide-touch { | |
display: block !important; | |
video { | |
display: block !important; | |
} | |
} | |
} | |
/* | |
_responsive-panels.scss | |
Utilizes the breakpoints you established in _responsive.sass to create a responsive layout, with minimal markup and maximum consistency. | |
*/ | |
@mixin panel($width, $padding-leftright: 20px) { | |
width: 100%; | |
height: auto; | |
display: block; | |
position: relative; | |
.container { | |
position: relative; | |
display: block; | |
width: $width; | |
height: auto; | |
margin: 0 auto; | |
padding: 0; | |
} | |
// Televisions | |
@include respond-to(xlg) { | |
.container { | |
width: ceil($break-lg - ceil($padding-leftright) * 2); | |
padding: 0 $padding-leftright; | |
} | |
} | |
// Desktops -> Some Landscape Tablets | |
@include respond-to(lg) { | |
.container { | |
width: ceil($break-md - ceil($padding-leftright / 1.5) * 2); | |
padding: 0 ceil($padding-leftright / 1.5); | |
} | |
} | |
// Some Small Desktops -> Most Landscape Tablets -> Some Large Phablets | |
@include respond-to(md) { | |
.container { | |
width: ceil($break-sm - ceil($padding-leftright / 1.75) * 2); | |
padding: 0 ceil($padding-leftright / 1.75); | |
} | |
} | |
// Some Landscape Tablets -> Most Portrait Tablets -> Some Phablets -> Some Landscape Phones | |
@include respond-to(sm) { | |
.container { | |
width: ceil($break-xs - ceil($padding-leftright / 2) * 2); | |
padding: 0 ceil($padding-leftright / 2); | |
} | |
} | |
// Some Landscape Phones -> All Portrait Phones, stops at 320px (iPhone) | |
@include respond-to(xs) { | |
.container { | |
width: 310px; | |
padding: 0 5px; | |
} | |
} | |
// If you were supporting wearables, you would respond with other sizes here, just copy and paste. I don't have the specs for these yet :) | |
} | |
// The real CSS/SCSS you'd write is: | |
html, body { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
// boom, simple and consistent. | |
.panel { | |
@include panel(1200px, 20px); | |
} | |
// then you can overwrite stuff here. Like, we want the hero to be super big, so: | |
#hero { | |
height: 400px; | |
.container { | |
height: 100%; | |
background: rgba(0,0,0,.25); | |
h1 { | |
text-align: center; | |
line-height: 400px; | |
@include respond-to($break-xs) { | |
padding-top: 50%; | |
line-height: 1.5; | |
} | |
} | |
} | |
} |