JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<h2>Before text</h2>
<p>Nam at tortor in tellus interdum sagittis. Duis leo. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. Aenean viverra rhoncus pede. Suspendisse eu ligula.</p>
<p>Ut tincidunt tincidunt erat. In ac felis quis tortor malesuada pretium. Quisque ut nisi. Nullam sagittis. Maecenas malesuada.</p>
<p>Pellentesque commodo eros a enim. Integer tincidunt. Quisque rutrum. Morbi vestibulum volutpat enim. Morbi mollis tellus ac sapien.</p>

<ul>
  <li><span data-brix-target="#test" data-brix-filter="brix-all" class="active">All</span></li>
  <li><span data-brix-target="#test" data-brix-filter="test">Test</span></li>
  <li><span data-brix-target="#test" data-brix-filter="tags">Tags</span></li>
  <li><span data-brix-target="#test" data-brix-filter="title">Title</span></li>
</ul>

<div id="test" data-brix data-brix-buffer="4">
  <div data-brix-tags="test,tags">
    <p>
      <strong>Tags: </strong>
      <span data-brix-target="#test" data-brix-filter="test">Test</span>,
      <span data-brix-target="#test" data-brix-filter="tags">Tags</span>
    </p>
    <p>Pellentesque dapibus hendrerit tortor. Curabitur turpis. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Curabitur blandit mollis lacus. Phasellus tempus.</p>
  </div>
  <div data-brix-tags="title,tags">
    <h3>Inner title</h3>
    <p>
      <strong>Tags: </strong>
      <span data-brix-target="#test" data-brix-filter="title">Title</span>,
      <span data-brix-target="#test" data-brix-filter="tags">Tags</span>
    </p>
    <p>Integer tincidunt. Cras id dui. Fusce commodo aliquam arcu.</p>
    <p>Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Cras ultricies mi eu turpis hendrerit fringilla. Quisque rutrum.</p>
  </div>
  <div>
    <p>Etiam iaculis nunc ac metus. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.</p>
  </div>
  <div>
    <p>Sed mollis, eros et ultrices tempus, mauris ipsum aliquam...

SCSS

@import url(https://fonts.googleapis.com/css?family=Lato:300,400,700,900|Merriweather:400,300,700);

html{
  margin: 0;
  padding: 0;
}
body{
  position: relative;
  padding: 0;
  margin: 25px;
  font-family: 'Merriweather', serif;
  font-size: 14px;
  font-weight: 400;
  color: #333;
}
p{
  margin: 0 0 1em 0;
  line-height: 1.6;
  &:last-child{
    margin-bottom: 0;
  }
}
h1, h2, h3, h4, h5, h6{
  margin: 0 0 15px;
  font-family: 'Lato', sans-serif;
  font-weight: 900;
  border-bottom: 2px solid #333;
  padding-bottom: 5px;
}

[data-brix] p{
  font-family: 'Lato', sans-serif;
  color: #666;
}

[data-brix]{
  padding: 0;
  margin: 1em 0;

  &:before{
    font-size: 0px;
    content: '1';
    visibility: hidden;
    position: absolute;
    top: -9999px;
    left: -9999px;
    opacity: 0;
  }

  & > *{
    padding: 15px;
    background-color: rgba(200, 200, 200, 0.3);
    border: 1px dashed #ddd;
    margin-bottom: 15px;
  }
  &.brix-init{
    position: relative;
    overflow: hidden;
    transition: height 300ms;
    & > *{
      &.brix-init{
        position: absolute;
        margin: 0;
        transition: transform 300ms;
      }
    }
  }

}

@media screen and (min-width: 480px){
  [data-brix]:before{
    content: '2';
  }
}
@media screen and (min-width: 800px){
  [data-brix]:before{
    content: '3';
  }
}
@media screen and (min-width: 1024px){
  [data-brix]:before{
    content: '4';
  }
}

*{
  box-sizing: border-box;
}

.clearfix{
  clear: both;

  &:before{
    content: '';
    zoom: 1;
  }

  &:after{
    content: '';
    display: table;
    clear: both;
  }

}


[data-brix] > .brix-init{
  animation: brix-block-popin 600ms 1 forwards;
}

@keyframes brix-block-popin{

  from{
    opacity: 0;
  }

  to{
    opacity: 1;
  }

}


[data-brix-filter]{
  cursor: pointer;
  
  &.active{
    
    ul &{
      font-weight: 700;
    }
    
    p &{
      text-decoration: underline;
    }
    
  }
  
}

ul{
  padding-left: 1.25em;
}

Babel + JSX

console.clear();

/**
 * Brix.js - ES6 Class
 */

class Brix{

  /**
   * Brix - CSS fed DOM columns
   * @param  {object}  element  Container node
   * @param  {integer} debounce Set debounce on event fire if needed
   * @return {object}
   */
  constructor(element, debounce){
    // Store vars
    this.debounceDelay = debounce || 0;
    this.element       = element;

    // Set buffer
    let buffer = this.element.getAttribute('data-brix-buffer');
    if(buffer){

      // Get x and y buffer
      buffer = buffer.split(',');
      if(buffer.length > 1){
        this.buffer_x = buffer[0] * 1;
        this.buffer_y = buffer[1] * 1;
      }else{
        this.buffer_x = this.buffer_y = buffer[0] * 1;
      }

    }else{

      // Default 0 buffer
      this.buffer_x = this.buffer_y = 0;

    }

    // Run
    this.init();
    
    this.element.brix = this;

    return this;
  }


  /**
   * Initialize events and run check
   */
  init(){
  	this.getChildren();
    this.bindEvents();
    this.checkPos();

    // Set init class
    if(!this.element.classList.contains('brix-init')){
      requestAnimationFrame(() => {
        this.element.classList.add('brix-init');
      });
    }
  }
  
  
  update(){
  	this.getChildren();
    this.checkPos();
  }


  /**
   * Bind resize events with debounce if needed
   */
  bindEvents(){
    if(!this.debounceDelay){

      // No debounce
      window.addEventListener('resize', () => {
        this.checkPos();
      });

    }else{

      // Set up debounce checks
      this.run = null;

      window.addEventListener('resize', () => {
        this.debounceCheck();
      });

    }

    // Load event
    let onLoad = () => {
      // Remove listener and reflow
      window.removeEventListener('load', onLoad);
      this.checkPos();
    };

    // Bind load event
    window.addEventListener('load', onLoad);
  }


  /**
   * Runs checkPos() with a debounce
   */
  debounceCheck(){
    // Clear existing trigger
   ...