<!-- Demo for CSS Tricks Article -->
<!-- Showcasing a layout using the between() function -->
<div class="Page">
<section class="Hero">
<nav class="Navigation">
<a href="#">
<div class="Logo"></div>
</a>
<ul class="Hamburger">
<li></li>
<li></li>
<li></li>
</ul>
<ul class="Navigation-list">
<li class="Navigation-item"><a href="#">About Us</a></li>
<li class="Navigation-item"><a href="#">Events</a></li>
<li class="Navigation-item"><a href="#">Resources</a></li>
<li class="Navigation-item"><a href="#">Contact</a></li>
<li class="Navigation-item">
<button class="Navigation-button">Call to action</button>
</li>
</ul>
</nav>
<div class="Hero-content">
<div class="Hero-copy">
<h1 class="Hero-title">Welcome <br /> Message</h1>
<p class="Hero-text">Atque sint aliquam numquam quam voluptate <br /> doloremque labore accusantium, iste excepturi</p>
<button class="Hero-button">Call to action</button>
</div>
</div>
</section>
<section class="NewsFeed">
<!-- Single NewsFeed Article -->
<article class="NewsFeed-article">
<div class="NewsFeed-image"></div>
<div class="NewsFeed-copy">
<p class="NewsFeed-date">April 6, 2017</p>
<h1 class="NewsFeed-title">News Feed Title</h1>
<p class="NewsFeed-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui velit doloribus nam...</p>
</div>
<a href="#" class="NewsFeed-readMore">Read more</a>
</article>
<!-- Single NewsFeed Article -->
<article class="NewsFeed-article">
<div class="NewsFeed-image"></div>
<div class="NewsFeed-copy">
<p class="NewsFeed-date">April 6, 2017</p>
<h1 class="NewsFeed-title">News Feed Title</h1>
<p class="NewsFeed-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui velit doloribus nam...</p>
</div>
<a href="#" class="NewsFeed-readMore">Read more</a>
</article>
<!-- Single NewsFeed Article -->
<article class="NewsFeed-article">
<div class="NewsFeed-image"></div>
<div class="NewsFeed-copy">
<p class="NewsFeed-date">April 6, 2017</p>
<h1 class="NewsFeed-title">News Feed Title</h1>
<p class="NewsFeed-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui velit doloribus nam...</p>
</div>
<a href="#" class="NewsFeed-readMore">Read more</a>
</article>
</section>
<section class="Featured u-narrowContainer">
<div class="Featured-copy">
<h1 class="Featured-title">Lorem ipsum <br /> dolor sit amet</h1>
<p class="Featured-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. <br /> Suscipit ipsam unde, fugit, consequuntur nulla.</p>
<button class="Featured-button">Button</button>
</div>
<div class="Featured-image"></div>
</section>
<section class="Gallery u-narrowContainer">
<h1 class="Gallery-title">Images of volunteers</h1>
<p class="Gallery-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. <br /> Suscipit laudantium, a corporis voluptatem inventore beatae.</p>
<div class="u-breakout">
<div class="Gallery-grid">
<div class="Gallery-image">
<img src="//placehold.it/500x500/D8D8D8" alt="" />
</div>
<div class="Gallery-image">
<img src="//placehold.it/500x500/ABABAB" alt="" />
</div>
<div class="Gallery-image">
<img src="//placehold.it/500x500/B3B3B3" alt="" />
</div>
<div class="Gallery-image">
<img src="//placehold.it/500x500/BFBFBF" alt="" />
</div>
</div>
</div>
</section>
<section class="Contact u-narrowContainer">
<h1 class="Contact-title">Contact Us</h1>
<div class="Contact-forms">
<p class="Contact-text">Lorem ipsum dolor sit amet <br /> Perspiciatis aperiam, atque amet?</p>
<div class="Contact-inputs">
<input type="text" placeholder="First Name"/>
<input type="text" placeholder="Last Name"/>
<input type="text" placeholder="Email Address"/>
<input type="text" placeholder="Phone"/>
</div>
<div class="Contact-textarea">
<label for="textarea">Message</label>
<textarea id="textarea" cols="30" rows="10"></textarea>
</div>
<button class="Contact-button">Button</button>
</div>
<div class="Contact-image"></div>
</section>
<footer class="Footer">
<div class="Footer-map"></div>
<div class="Footer-content">
<div class="Footer-contact">
<h3 class="Footer-contactTitle">Contact us</h3>
<p class="Footer-contactText">Magnam 24, Repellat Repellendus</p>
<p class="Footer-contactText">Cupiditate Deleniti, Libero Magni</p>
<div class="Footer-social">
<div class="Footer-socialIcon"></div>
<div class="Footer-socialIcon"></div>
<div class="Footer-socialIcon"></div>
<div class="Footer-socialIcon"></div>
</div>
</div>
<div class="Footer-newsletter">
<h1 class="Footer-newsletterTitle">Sign Up For News</h1>
<p class="Footer-newsletterText">Lorem ipsum dolor sit amet and all that</p>
<input class="Footer-newsletterInput" type="email" placeholder="Email" />
<button class="Footer-button">Button</button>
</div>
</div>
</footer>
</div>
///
/// Output a CSS calc function that contrains a value from A to B over
/// A-viewport-width to B-viewport-width. Require a media query to cap
/// the value at B.
///
/// @usage
/// .article {
/// font-size: 12px;
/// @media screen and ( min-width: 640px ) {
/// font-size: between( 12px, 16px, 640px, 1280px );
/// }
/// @media screen and ( min-width: 1280px ) {
/// font-size: 16px;
/// }
/// }
///
/// @link https://css-tricks.com/between-the-lines/
/// @demo https://codepen.io/dbj/pen/XMGgjz
///
/// @param {Number} $from Minimum size in pixels
/// @param {Number} $to Maximum size in pixels
/// @param {Number} $fromWidth Minimum viewport width in pixels
/// @param {Number} $toWidth Maximum viewport width in pixels
///
@function between( $fromValue, $toValue, $fromWidth, $toWidth ) {
$slope: ( $toValue - $fromValue ) / ( $toWidth - $fromWidth );
$base: $fromValue - $slope * $fromWidth;
@return calc(#{$base} + #{100vw * $slope});
}
$small: 324px;
$medium: 720px;
$large: 1440px;
///
/// Constrain a property between two values, between two breakpoints.
///
/// @usage
/// .widget {
/// @include responsive-property( "padding", 1em 2em, 1.5em 3em );
/// }
///
/// In this case, padding at the smallest size will be 1em 2em, and it will
/// increase proportionally with the viewport width until it reaches 1.5em 3em.
/// Works with all sized properties i.e width, max-height, font-size, etc.
///
/// Note: "auto", "0" and percentage-based values can be passed, but they will
/// not be processed. For the `$fromBp` media query, `$fromValue` will
/// be used in their place.
///
/// @uses between() function
///
/// @param {String} $property Property
/// @param {Number} $fromValue Minimum value(s)
/// @param {Number} $toValue Maximum value(s)
/// @param {Number} [$fromBp] Value(s) increase after this breakpoint
/// @param {Number} [$toBp] Value(s) are capped at this breakpoint
///
@mixin responsive-property(
$property,
$fromValue,
$toValue,
$fromBp: $medium,
$toBp: $large
) {
$fromValues: ();
$betweenValues: ();
$toValues: ();
@for $i from 1 through length( $fromValue ) {
$fv: nth( $fromValue, $i );
$tv: nth( $toValue, $i );
$bv: $fv;
$bvf: false;
$bvt: false;
@if ( type-of( $fv ) == "number" and not unitless( $fv ) and unit( $fv ) != "%" ) {
$fv: if( unit( $fv ) != "px", ( $fv / ( $fv * 0 + 1 ) * 16 ) * 1px, $fv );
$bvf: $fv;
}
@if ( type-of( $tv ) == "number" and not unitless( $tv ) and unit( $tv ) != "%" ) {
$tv: if( unit( $tv ) != "px", ( $tv / ( $tv * 0 + 1 ) * 16 ) * 1px, $tv );
$bvt: $tv;
}
@if ( $bvf != false and $bvt != false ) {
$bv: between( $bvf, $bvt, $fromBp, $toBp );
}
$fromValues: append( $fromValues, $fv );
$betweenValues: append( $betweenValues, $bv );
$toValues: append( $toValues, $tv );
}
#{$property}: $fromValues;
@media screen and (min-width: #{$fromBp}) {
#{$property}: $betweenValues;
}
@media screen and (min-width: #{$toBp}) {
#{$property}: $toValues;
}
}
$white: #ffffff;
$fadedWhite: #f9f9f9;
$lightGray: #eaeaea;
$mediumGray: #bebebe;
$darkGray: #afafaf;
$open: 'Open Sans';
$fira: 'Fira Sans';
body {
align-items: center;
display: flex;
font-family: 'Open Sans', sans-serif;
font-size: 16px;
justify-content: center;
}
section {
// horizontal padding 90px $large, 32px $medium, 16px $small
@include responsive-property( "padding", 1em, 2em, $small, $medium );
@include responsive-property( "padding", 2em, 90px );
}
button {
background: $white;
border: none;
border-radius: 3px;
}
a {
text-decoration: none;
color: $fadedWhite;
}
.u-narrowContainer {
// Utility that narrows containers
// Horizontal padding 180px $large, 32px $medium, disabled $small
// Vertical padding half that
@include responsive-property( "padding", 16px 32px, 90px 180px );
}
.u-breakout {
// Utility to escape section padding
@include responsive-property( "margin", 0 0, 0 -180px, $small, $large );
}
.Page {
width: 100%;
overflow: hidden;
max-width: $large;
}
.Logo {
width: 140px;
height: 32px;
background: $white;
border-radius: 8px;
}
.Navigation {
align-items: center;
display: flex;
justify-content: space-between;
}
.Navigation-list {
align-items: center;
display: none;
@media (min-width: $medium) {
display: flex;
}
}
.Navigation-item {
@include responsive-property( "font-size", 12px, 16px );
& + & {
padding-left: 2em;
}
}
.Navigation-button {
background: $white;
color: $darkGray;
padding: 1em 2.5em;
font-size: inherit;
}
.Hamburger {
display: block;
@media (min-width: $medium) {
display: none;
}
li {
width: 36px;
height: 5px;
border-radius: 3px;
background: $white;
margin-bottom: 4px;
}
}
.Hero {
// height 900px $large, 420px $medium, 300px $small
@include responsive-property( "height", 300px, 420px, $small, $medium );
@include responsive-property( "height", 420px, 900px, $medium, $large );
background: url('//placehold.it/1440x900/afafaf/D3D6DB');
background-size: cover;
background-position: center;
display: flex;
flex-direction: column;
}
.Hero-content {
display: flex;
padding: 0 10%;
margin: auto 0;
}
.Hero-copy {
color: $lightGray;
}
.Hero-title {
/* font-size 64px $large, 44px $medium, 36px $small */
/* margin-bottom 40px $large, 30px $medium, 10px $small*/
@include responsive-property( "font-size", 36px, 44px, $small, $medium );
@include responsive-property( "font-size", 44px, 64px, $medium, $large );
@include responsive-property( "margin-bottom", 10px, 30px, $small, $medium );
@include responsive-property( "margin-bottom", 30px, 40px, $medium, $large );
line-height: 1;
font-weight: 700;
color: $white;
}
.Hero-text {
// font-size = 18px $large, 12px $medium
@include responsive-property( "font-size", 12px, 18px );
line-height: 1.5;
}
.Hero-button {
// font-size = 16px $large, 12px $medium, 10px $small
@include responsive-property( "font-size", 10px, 12px, $small, $medium );
@include responsive-property( "font-size", 12px, 16px, $medium, $large );
background: $white;
color: $darkGray;
padding: 15px 45px;
margin-top: 40px;
}
.NewsFeed {
// Image height 280px $large, 150px $medium, 200px $small,
$imageHeightSmall: 200px;
$imageHeightMedium: 150px;
$imageHeightLarge: 280px;
color: $darkGray;
display: flex;
flex-wrap: wrap;
@include responsive-property( "margin-top", -$imageHeightMedium/2, -$imageHeightLarge/2 );
@media (min-width: $medium) {
flex-wrap: nowrap;
}
&-image {
@include responsive-property( "height", $imageHeightMedium, $imageHeightLarge );
background: url('//placehold.it/403x279/eaeaea/d3d3d3') no-repeat;
background-size: cover;
background-position: 100%;
}
}
.NewsFeed-article {
flex: 1 1 auto;
@media (min-width: $medium) {
margin: 0 16px;
}
&:not(:first-child) {
display: none;
@media (min-width: $medium) {
display: block;
}
}
}
.NewsFeed-copy {
margin-top: 28px;
}
.NewsFeed-title {
font-family: $fira;
font-size: 24px;
padding-bottom: 32px;
line-height: 1.4;
font-weight: 600;
}
.NewsFeed-date {
font-family: $fira;
font-weight: 600;
padding-bottom: 16px;
}
.NewsFeed-text {
color: $darkGray;
line-height: 1.5;
}
.NewsFeed-readMore {
font-family: $fira;
font-weight: 600;
color: $mediumGray;
display: block;
text-align: right;
padding-top: 16px;
&::after {
font-family: sans-serif;
content: ">";
padding-left: 0.5em;
}
}
.Featured {
color: $darkGray;
display: flex;
align-items: center;
flex-wrap: wrap;
@media (min-width: $medium) {
flex-wrap: nowrap;;
justify-content: space-around;
}
}
.Featured-copy {
margin-right: 32px;
margin-top: 28px;
}
.Featured-title {
// font-size 36px $large, 24px $medium
@include responsive-property( "font-size", 24px, 36px );
font-family: $fira;
font-weight: 600;
line-height: 1;
margin-bottom: 16px;
}
.Featured-text {
// font-size 18px $large, 16px $medium
@include responsive-property( "font-size", 16px, 18px );
line-height: 1.4;
}
.Featured-image {
background: url('//placehold.it/508x360/eaeaea/d3d3d3');
background-size: cover;
background-position: 100%;
padding-top: 50%;
width: 100%;
order: -1;
@media (min-width: $medium) {
margin-bottom: 0;
max-width: 508px;
order: 0;
padding-top: 33.333%;
}
}
.Featured-button {
background: $darkGray;
color: $white;
padding: 15px 45px;
font-size: 16px;
margin-top: 35px;
min-width: 190px;
}
.Gallery {
color: $darkGray;
}
.Gallery-title {
// 36px $large, 36px $medium, 24px $small
@include responsive-property( "font-size", 24px, 36px, $small, $medium );
font-weight: 600;
margin-bottom: 0.5em;
}
.Gallery-text {
line-height: 1.5;
font-size: 18px;
}
.Gallery-grid {
display: flex;
margin-top: 50px; // todo 50px?
flex-wrap: wrap;
@media (min-width: $medium) {
flex-wrap: nowrap;
}
}
.Gallery-image {
min-width: 0;
width: 100%;
> img {
height: auto;
max-width: 100%;
vertical-align: bottom;
}
@media (min-width: $small) {
width: 50%;
}
}
.Contact {
color: $darkGray;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
}
.Contact-forms {
flex: 2;
@media (min-width: $medium) {
margin-right: 10%;
}
}
.Contact-title {
// fz: 36px $large, 36px $medium, 28px $small
@include responsive-property( "font-size", 28px, 36px, $small, $medium );
flex: 100%;
font-family: $fira;
font-weight: 700;
margin-bottom: 0.5em;
}
.Contact-text {
line-height: 1.5;
}
.Contact-inputs {
// margin-bottom: 40px $medium, 0px $small
@include responsive-property( "margin", 40px auto 0, 40px auto 40px, $small, $medium );
display: flex;
flex-wrap: wrap;
input {
color: #AFAFAF;
flex: 1 1 100%;
font-family: $fira;
font-size: 12px;
border: none;
letter-spacing: 0.333px;
font-weight: 200;
box-shadow: 0 1px 0 $mediumGray;
padding: 0;
padding-bottom: 1em;
margin-bottom: 40px;
@media (min-width: $small) {
flex: 0 1 calc(50% - 22px);
&:nth-child(odd) {
margin-right: 22px;
}
}
}
}
.Contact-textarea {
color: #AFAFAF;
display: flex;
flex-direction: column;
margin-bottom: 40px;
label {
font-family: $fira;
font-size: 12px;
letter-spacing: 0.333px;
font-weight: 200;
}
textarea {
flex: 1 1 100%;
border-color: $mediumGray;
margin-top: 15px;
}
}
.Contact-button {
// width 190px $large, 150px $medium, 100% $small
@include responsive-property( "width", 100%, 150px, $small, $medium );
@include responsive-property( "width", 150px, 190px, $medium, $large );
background: $lightGray;
color: $darkGray;
font-size: 16px;
padding: 1em 2.5em;
}
.Contact-image {
// margin-right -110px $large, 0px $medium and disappear
@include responsive-property( "margin-right", 0px, -110px );
display: none;
@media (min-width: $medium) {
display: block;
background: url('//placehold.it/402x387/ffffff/D3D6DB');
background-size: cover;
background-position: center;
flex: 1;
height: 308px;
border: 1px solid $lightGray;
margin-bottom: 0;
min-width: 280px;
max-width: 400px;
}
}
.Footer {
// Padding 93px, 67px $large, 34px, 24px, $medium, $54px 32px $small
@include responsive-property( "padding", 54px 32px, 54px 24px, $small, $medium );
@include responsive-property( "padding", 34px 24px, 93px 67px, $medium, $large );
display: flex;
align-items: flex-start;
background: $darkGray;
flex-wrap: wrap;
}
.Footer-map {
// margin-right: 128px $large, 24px $medium, not visible $small
display: none;
background: url('//placehold.it/296x181/8C8C8C/F2F2F2');
background-size: cover;
background-position: center;
width: 219px;
height: 181px;
@media (min-width: $medium) {
display: block;
}
}
.Footer-content {
// 130 20 0
@include responsive-property( "margin-left", 0px, 20px, $small, $medium );
@include responsive-property( "margin-left", 20px, 130px, $medium, $large );
display: flex;
flex: 1;
justify-content: space-between;
flex-wrap: wrap;
@media (min-width: $small) {
flex-wrap: nowrap;
}
}
.Footer-contact {
font-size: 12px;
margin-bottom: 50px;
width: 100%;
@media (min-width: $small) {
margin-bottom: 0;
margin-right: 20px;
width: auto;
}
}
.Footer-contactTitle {
color: $white;
margin-bottom: 10px;
}
.Footer-contactText {
color: #D8D8D8;
line-height: 1.75;
}
.Footer-social {
margin-top: 50px;
display: flex;
justify-content: space-between;
}
.Footer-socialIcon {
background: #D8D8D8;
width: 36px;
height: 36px;
}
.Footer-newsletter {
@include responsive-property( "margin-right", 0px, 90px );
display: flex;
flex-direction: column;
justify-content: space-between;
}
.Footer-newsletterTitle {
font-size: 24px;
color: $white;
margin-bottom: 12px;
display: none;
@media (min-width: $medium) {
display: block;
}
}
.Footer-newsletterText {
color: #D8D8D8;
margin-bottom: 10px;
}
.Footer-newsletterInput {
box-sizing: border-box;
padding: 0 1em;
border-radius: 3px;
background: $white;
height: 40px;
border: 0;
margin-bottom: 25px;
}
.Footer-button {
// width 190px $large, 150px $medium, 100% $small
@include responsive-property( "width", 100%, 150px, $small, $medium );
@include responsive-property( "width", 150px, 190px, $medium, $large );
background: $lightGray;
color: $darkGray;
font-size: 16px;
padding: 1em 2.5em;
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.