Contenu en offset jusqu'au bord de l'écran

On affiche un contenu qui est décalé jusqu'au bord de l'écran, tout en restant à l'intérieur d'un contenu centré et limité en largeur

by oilvier

HTML

<div class="layout">
  <div class="main">
      <div class="expand expand--full"></div>
      <div class="expand expand--left"></div>
      <div class="expand expand--right"></div>
      
      <div class="foo">
        <div>
          <div class="expand"></div>
        </div>
        <div>
          <div class="expand expand--right"></div>
        </div>
      </div>
      <div class="foo">
        <div>
          <div class="expand expand--left"></div>
        </div>
        <div>
          <div class="expand"></div>
        </div>
        <div>
          <div class="expand"></div>
        </div>
        <div>
          <div class="expand"></div>
        </div>
      </div>
  </div>
</div>

SCSS

/* Reset rapide */               
*, 
*:before, 
*:after {box-sizing: border-box;}
body {margin:0; padding:0; background-color:Gainsboro;}


$layout-width:400px;
$container-padding:20px;

.main {padding:1px $container-padding; background-color:white;}
.expand {margin:20px 0; border:2px solid DarkBlue; background-color:CornflowerBlue; padding:50px 0;}

.foo {display:flex;
  & > div {flex:1 1 0%;}
}

/* Layout */
.layout {margin:0 auto; max-width:$layout-width;} 

/**
* L'élément avec cette classe doit prendre toute la largeur de la page.
* Dans le cas où notre élément est appelé au sein d'un autre élément avec 
* la classe `.layout`, nous devons modifier son comportement pour qu'il 
* vienne toucher les 2 bords de l'écran
* 1. On pousse notre conteneur au centre de l'écran 
* 2. Et on l'étire jusqu'au bord
* On utilise `left` ET `right` pour les éventuels cas de `direction:rtl`
* 3. Afin d'éviter l'apparition d'un scroll horizontal, on ajoute aussi `overflow-x:hidden;` sur la balise  ``html` 
*/
html {overflow-x:hidden; /* [3] */}
.expand--full {position:relative; left:50%; /* [1] */ right:50%; margin-left:-50vw; /* [2] */ margin-right:-50vw; width:100vw;}

@media screen and (min-width: $layout-width) {
  /**
   * Si on veut reproduire cet effet d'un seul côté
   * On doit récupérer la (largeur exacte du parent / 2)
   * Sous entendu que si le parent a du padding, il faut la soustraire à notre largeur
   * (c'est le cas ici)
   */
  .expand--left {margin-left:calc(-50vw + ( ( #{$layout-width} - (#{$container-padding} * 2) ) / 2 ) );}
  .expand--right {margin-right:calc(-50vw + ( ( #{$layout-width} - (#{$container-padding} * 2) ) / 2 ) );}  
}
































/* ==========================================================================
	Configuration des variables
   ==========================================================================...