cssAudio - ActiveCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - Activehtmlicon-personicon-teamoctocatspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <div id="canvas">
  <div id="canvas-left">
    <div class="texture"></div>
  </div>
  <div id="canvas-back"></div>
  <div id="grid" class="grid">
    <span id="fallback">Your browser doesn't <a href="http://caniuse.com/#feat=css-grid" target="_blank">support</a> CSS grids yet!</span>
  </div>
  <div class="texture" id="texture"></div>

  <button id="draw">
    <span id="draw-top"></span>
    <span id="draw-left"></span>
    <span id="draw-back"></span>
    <span>Another one</span>
  </button>

  <div id="description">
    <span id="description-top"></span>
    <span id="description-left"></span>
    <span id="description-back"></span>
    <p class="author">Mondrian + CSS grid</p>
    <p class="title">Untitled (Div's on DOM)</p>
    <p class="year">2017. <a href="https://twitter.com/marco_ciampini" target="_blank" rel="noopener noreferrer">@marco_ciampini</a> for <a href="https://twitter.com/toasterco" target="_blank" rel="noopener noreferrer">@toasterco</a></p>
  </div>
</div>
            
          
!
            
              html,
body {
  margin: 0;

  width: 100vw;
  height: 100vh;
}

body {
  position: relative;

  display: flex;
  align-items: center;
  justify-content: center;

  background: #fff;

  perspective: 2000px;
  perspective-origin: 50% 50%;

  transition: perspective-origin .3s ease-out;
}

/*=================================================
 * Canvas
 ================================================*/
#canvas {
  position: relative;

  height: 100vh;
  width: 100vw;

  transform-style: preserve-3d;
  transform: none;

  transition: transform .3s ease-out;
}

#canvas-left {
  position: absolute;
  top: 0;
  left: 0;

  height: 100%;
  width: 15px;

  background-color: white;

  transform-origin: top left;
  transform: rotateY(90deg);

  border-bottom: 1px solid #aaa;

  overflow: hidden;
}
#canvas-left .grid {
  width: 50vw;
}
#canvas-left .texture {
  opacity: .2;

  background-size: 500px auto;
}

#canvas-left::after {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  background: linear-gradient(to left,
      rgba(0, 0, 0, 0.2) 40%, rgba(0, 0, 0, 0.1));

  content: '';
}

#canvas-back {
  position: absolute;
  top: 0;
  left: 0;

  width: 100%;
  height: 100%;

  transform: translateZ(-15px);

  transition: transform .2s ease;

  box-shadow: -5px 3px 25px 0px rgba(0, 0, 0, 0.2)
}

/*=================================================
 * Grid root node (drawing container)
 ================================================*/
.grid {
  position: absolute;
  top: 0;
  left: 0;

  width: 100%;
  height: 100%;

  background: black;

  border: 1px solid #e4e4e4;
  border-left: none;

  overflow: hidden;
}


/*=================================================
 * Canvas paper overlay texture
 ================================================*/
.texture {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  background-image: url(data:image/png;base64,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);

  background-size: 600px auto;

  opacity: .25;
}


/*=================================================
 * Description text.
 ================================================*/
#description {
  position: absolute;
  top: 105%;
  left: 250px;

  display: none;

  padding: 1em 3em 1em 1.5em;

  border: 0;
  background: #fff;

  color: #222;


  font-family: Aria, sans-serif;
  font-size: 18px;

  border: 1px solid #ddd;

  transform-style: preserve-3d;
  transform: translate3d(0, 0, -13px);
}

#description a {
  color: #777;

  text-decoration: none;
}

#description a:not(:first-of-type) {
  color: #000;

  font-weight: 700;
}

#description p {
  margin: 0;
}

#description .author,
#description .year {
  color: #777;
}

#description .title {
  margin-top: .1em;
  margin-bottom: .3em;

  font-weight: 700;
}

#description-left {
  position: absolute;
  top: 0;
  left: 0;

  width: 2px;
  height: 100%;

  background-color: white;

  transform-origin: top left;
  transform: rotateY(90deg);

  border-top: 1px solid #aaa;
}

#description-left::after {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  background: linear-gradient(to left,
      rgba(0, 0, 0, 0.2) 40%, rgba(0, 0, 0, 0.05));

  content: '';
}

#description-top {
  position: absolute;
  top: 0;
  left: 0;

  width: 100%;
  height: 2px;

  background-color: white;

  transform-origin: top left;
  transform: rotateX(-90deg);

  transition: transform .2s ease;
}
#description-top::after {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  background: linear-gradient(to top,
      rgba(0, 0, 0, 0.2) 40%, rgba(0, 0, 0, 0.05));

  content: '';
}

#description-back {
  position: absolute;
  top: 0;
  left: 0;

  width: 100%;
  height: 100%;

  transform: translateZ(-2px);

  transition: transform .2s ease;

  box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}


/*=================================================
 * Draw button.
 ================================================*/
#draw {
  position: absolute;
  top: 105%;
  left: 0;

  display: none;

  border: 0;
  background: #fff;

  font-family: Aria, sans-serif;
  font-size: 26px;
  line-height: 2;
  padding: 0 1em;

  border: 1px solid #ddd;

  transform-style: preserve-3d;
  transform: translateZ(-5px);

  transition: transform .2s ease;
}

#draw:focus {
  outline: none;
}

#draw-left {
  position: absolute;
  top: 0;
  left: 0;

  width: 10px;
  height: 100%;

  background-color: white;

  transform-origin: top left;
  transform: rotateY(90deg);

  transition: transform .2s ease;

  border-top: 1px solid #aaa;
}
#draw-left::after {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  background: linear-gradient(to left,
      rgba(0, 0, 0, 0.2) 40%, rgba(0, 0, 0, 0.1));

  content: '';
}

#draw-top {
  position: absolute;
  top: 0;
  left: 0;

  width: 100%;
  height: 10px;

  background-color: white;

  transform-origin: top left;
  transform: rotateX(-90deg);

  transition: transform .2s ease;
}
#draw-top::after {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  background: linear-gradient(to top,
      rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.1));

  content: '';
}

#draw-back {
  position: absolute;
  top: 0;
  left: 0;

  width: 100%;
  height: 100%;

  transform: translateZ(-10px);

  transition: transform .2s ease;

  box-shadow: 0 0 30px rgba(0, 0, 0, 0.2);
}

#draw:hover {
  transform: translateZ(-12px);
}
#draw:hover #draw-left {
  transform: rotateY(90deg) scaleX(.8);
}
#draw:hover #draw-top {
  transform: rotateX(-90deg) scaleY(.8);
}
#draw:hover #draw-back {
  transform: translateZ(-8px);
}


#draw:active {
  transform: translateZ(-16px);
  background-color: #f6f6f6;
}
#draw:active #draw-left {
  transform: rotateY(90deg) scaleX(.4);
}
#draw:active #draw-top {
  transform: rotateX(-90deg) scaleY(.4)
}
#draw:active #draw-back {
  transform: translateZ(-4px);
}


/*=================================================
 * Fallback screen
 ================================================*/
#fallback {
  position: absolute;
  top: 50%;
  left: 50%;

  transform: translate3d(-50%, -50%, 0);

  color: white;

  font-size: 18px;
  font-family: Arial, sans-serif;
}

#fallback a {
  color: #ff0;
}


/*=================================================
 * Gallery Mode
 ================================================*/

.galleryMode body {
  perspective-origin: -100% 35%;
}
.galleryMode #canvas {
  transform: scale(.7) rotateY(5deg);
}

@media screen and (max-height: 770px) {
  .galleryMode #canvas {
    transform: translateY(-8%) scale(.7) rotateY(5deg);
  }
}
            
          
!
            
              // Editable settings.
var CONF = {
  maxNesting: 2,
  gridGap: 14,
  galleryMode: true,
  colorA: '#f9d51a',
  colorB: '#cc000b',
  colorC: '#0166ba',
  colorFg: '#ffffff',
  colorBg: '#000000'
};

// Fixed settings.
var ROWS_NUMBER = 2;
var COLS_NUMBER = 2;
var MIN_CELLS = 2;
var MAX_CELLS = ROWS_NUMBER * COLS_NUMBER;

var MAX_RATIO = 5;
var QUADRANT_NAMES = ['a', 'b', 'c', 'd'];

var COLOR_COUNT = {
  'colorFg': 0,
  'colorBg': 0,
  'colorA': 0,
  'colorB': 0,
  'colorC': 0
};

var COLOR_PROBABILITY = {
  '1.0': 'colorFg',
  '0.45': 'colorB',
  '0.3': 'colorA',
  '0.15': 'colorC'
}


// Dom elements.
var grid = document.getElementById('grid');
var drawButton = document.getElementById('draw');
var description = document.getElementById('description');
var fallback = document.getElementById('fallback');
var texture = document.getElementById('texture');
var canvasLeftSide = document.getElementById('canvas-left');


function initDatGui() {
  var guiControllers = [];
  var colorControllers = [];

  var gui = new dat.gui.GUI();

  gui.add(CONF, 'galleryMode').name('Gallery Mode')
      .onChange(function(galleryModeOn) {
        document.documentElement.classList.toggle('galleryMode');
      });

  guiControllers.push(gui.add(CONF, 'maxNesting')
      .min(2).max(4).step(1).name('Nesting Limit').listen());
  guiControllers.push(gui.add(CONF, 'gridGap')
      .min(0).max(50).step(1).name('Gutter'));

  var colorsFolder = gui.addFolder('Colors');
  colorControllers.push(colorsFolder.addColor(CONF, 'colorA').name('Accent 1'));
  colorControllers.push(colorsFolder.addColor(CONF, 'colorB').name('Accent 2'));
  colorControllers.push(colorsFolder.addColor(CONF, 'colorC').name('Accent 3'));
  colorControllers.push(colorsFolder.addColor(CONF, 'colorFg').name('Main'));
  colorControllers.push(colorsFolder.addColor(CONF, 'colorBg').name('Gutter'));
  colorsFolder.open();

  guiControllers.forEach(function(controller) {
    controller.onChange(_.throttle(draw, 100));
  });

  colorControllers.forEach(function(controller) {
    controller.onFinishChange(draw);
  });

  gui.close();
}


/**
 * Gives all valid cells configations, given the number of cells.
 * @param {Number} howManyCells How many cells to fit in the grid.
 * @return {Array<Array<number>>|undefined} Configuration.
 */
function getAllAreasConfigs(howManyCells) {
  if (howManyCells < MIN_CELLS || howManyCells > MAX_CELLS) {
    return undefined;
  }

  // Meaning of indexes:
  //  +=======+
  //  | 0 | 1 |
  //  |===+===|
  //  | 2 | 3 |
  //  +=======+

  switch (howManyCells) {
    case 2:
      return [
        [[0, 1], [2, 3]],
        [[0, 2], [1, 3]]
      ];
    case 3:
      return [
        [[0, 1], [2], [3]],
        [[0, 2], [1], [3]],
        [[1, 3], [0], [2]],
        [[2, 3], [0], [1]]
      ];
    case 4:
      return [
        [[0], [1], [2], [3]]
      ];
  }
}


/**
 * Converts a cell configuraiton to a different representation, using
 *   letter as area names.
 * @param chosenAreaConfig One of the possible cell areas configurations.
 * @return {Array<String>} Array representing an area configation using letters.
 */
function formatAreaConfig(chosenAreaConfig) {
  var toReturn = _.fill(Array(MAX_CELLS), '');

  chosenAreaConfig.forEach(function(cellArea, cellIndex) {
    cellArea.forEach(function(quadrant) {
      toReturn[quadrant] = QUADRANT_NAMES[cellIndex];
    });
  });

  return _.chunk(toReturn, 2).map(function(subGrid) {
    return subGrid.join(' ');
  });
}


/**
 * Recursively creates the DOM elements
 * based on the configuration received.
 * @param {Element} container The grid container.
 * @param {Number} nestingLevel Nesting level of the current grid.
 * @return {boolean} True if nesting was successful.
 */
function createGrid(container, nestingLevel) {
  var nestingLevel = nestingLevel || 0;

  if (nestingLevel >= CONF.maxNesting) {
    return false;
  }

  // If gap == 0, use fgColor to avoid sub-pixel level lines showing through.
  container.style.backgroundColor = CONF.gridGap > 0 ?
      CONF['colorBg'] : CONF['colorFg'];

  var fragment = document.createDocumentFragment();

  var tplRows = '';
  var tplCols = '';
  var subitem;
  var allAreasConfig;
  var areas;
  var tmpSubGrid;
  var i;

  // How many cells.
  var cellsNumber = _.random(MIN_CELLS, MAX_CELLS);

  // Set container's style from configuration: display, grid-gap,
  // grid-template-rows, grid-template-columns,.
  for (i = 0; i < ROWS_NUMBER; i++) {tplRows += _.random(1, MAX_RATIO) + 'fr ';}
  for (i = 0; i < COLS_NUMBER; i++) {tplCols += _.random(1, MAX_RATIO) + 'fr ';}
  container.style.gridTemplateRows = tplRows;
  container.style.gridTemplateColumns = tplCols;
  container.style.display = 'grid';
  container.style.gridGap = CONF.gridGap + 'px';

  // Get a random template areas configuration from all the possible ones.
  allAreasConfig = getAllAreasConfigs(cellsNumber);
  areas = formatAreaConfig(allAreasConfig[_.random(allAreasConfig.length - 1)]);
  container.style.gridTemplateAreas = '"' + areas[0] + '" "' + areas[1] + '"';

  // Possibly add childnodes and set their grid-area according to the config.
  // The higher the nesting level, the lower the probability of recursion.

  var colorProb;
  var assignedColor;
  for (i = 0; i < cellsNumber; i++) {
    subitem = document.createElement('div');
    subitem.style.gridArea = QUADRANT_NAMES[i];

    if (Math.random() < 1 / (1 + nestingLevel * nestingLevel)) {
      tmpSubGrid = createGrid(subitem, nestingLevel + 1);
    } else {
      tmpSubGrid = false;
    }

    if (tmpSubGrid) {
      // This cell is being recursively split into more cells.
      subitem.style.backgroundColor = CONF.gridGap > 0 ?
          CONF['colorBg'] : CONF['colorFg'];
    } else {
      // "Leaf" cell.
      // Decide the potential color to use out of probablity.
      colorProb = Math.random();
      Object.keys(COLOR_PROBABILITY).forEach(function(prob) {
        if (colorProb <= parseFloat(prob)) {
          assignedColor = COLOR_PROBABILITY[prob];
        }
      })

      // Avoid using primary colors for more than CONF.maxNesting times.
      // Fallback to colorFg color in case.
      if (assignedColor === 'colorFg' ||
          COLOR_COUNT[assignedColor] < Math.max(1, CONF.maxNesting - 1)) {
        COLOR_COUNT[assignedColor]++;
      } else {
        assignedColor = 'colorFg';
      }

      subitem.style.backgroundColor = CONF[assignedColor];
    }

    fragment.appendChild(subitem);
  }

  // Finally append the document fragment to the grid container.
  container.appendChild(fragment);
  return true;
}


/**
 * Draws a new grid.
 */
function draw() {
  // Removes all childnodes.
  while (grid.firstChild) {
    grid.removeChild(grid.firstChild);
  }

  while (canvasLeftSide.firstChild) {
    canvasLeftSide.removeChild(canvasLeftSide.firstChild);
  }

  // Reset color count
  Object.keys(COLOR_COUNT).forEach(function(c) {
    COLOR_COUNT[c] = 0;
  });

  // Creates new grid.
  createGrid(grid);

  var gridDup = grid.cloneNode(true);
  gridDup.id = '';
  canvasLeftSide.appendChild(gridDup);

  var texture = document.createElement('div');
  texture.classList.add('texture');
  canvasLeftSide.appendChild(texture);
}

function isGridSupported() {
  var div = document.createElement('div');
  div.style.display = 'grid';

  return div.style.display === 'grid';
}


function init() {
  // On button click.
  drawButton.addEventListener('click', function() {
    CONF.maxNesting = _.random(2, 4);
    draw();
  });

  initDatGui();

  if (isGridSupported()) {
    draw();
    drawButton.style.display = 'block';
    description.style.display = 'block';
  } else {
    texture.style.display = 'none';
  }
}

init();

            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console