Skip to content

Instantly share code, notes, and snippets.

@easierbycode
Forked from ebidel/index.html
Created July 24, 2019 23:36

Revisions

  1. @ebidel ebidel revised this gist Feb 15, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    <!-- based on https://twitter.com/ebidel/status/933496242272747520 -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
  2. @ebidel ebidel created this gist Feb 15, 2018.
    93 changes: 93 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><responsive-element></title>
    <link rel="stylesheet" href="styles.css">
    </head>
    <body>

    <responsive-container id="container1">
    <div>move the &lt;-- frame around or click-me</div>
    </responsive-container>

    <responsive-container small="400px" id="container2">
    <ul>
    <li>one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    <li>five</li>
    <li>six</li>
    <li>seven</li>
    <li>eight</li>
    <li>nine</li>
    <li>ten</li>
    </ul>
    </responsive-container>

    <div id="container3">
    <div>right nav</div>
    </div>

    <script>
    const ResizeObservableElement = (superclass) => class extends superclass {
    static get observer() {
    if (!this._observer) {
    // Set up a single RO for all elements that inherit from this class. This
    // has much better performance than creating a separate RO in every
    // element instance. See https://goo.gl/5uLKZN.
    this._observer = new ResizeObserver(entries => {
    for (const entry of entries) {
    // Custom event works for both node.onresize and node.addEventListener('resize') cases.
    const evt = new CustomEvent('resize', {detail: entry, bubbles: false})
    entry.target.dispatchEvent(evt);
    }
    });
    }
    return this._observer;
    }

    constructor() {
    super();
    this.constructor.observer.observe(this);
    }
    };

    class ResponsiveContainer extends ResizeObservableElement(HTMLElement) {
    static get is() { return 'responsive-container'; }
    get mode() { return this.getAttribute('mode'); }
    set mode(val) {
    val ? this.setAttribute('mode', val) : this.removeAttribute('mode');
    }
    constructor() {
    super();
    this.smallSize = parseInt(this.getAttribute('small')) || 400;
    // Component responds to it's own resizes.
    this.addEventListener('resize', e => {
    const w = e.detail.contentRect.width;
    this.mode = w <= this.smallSize ? 'small' : 'large';
    });
    }
    }

    customElements.define(ResponsiveContainer.is, ResponsiveContainer);


    // Main page can subscribe to component's resize updates too.
    document.querySelector('#container2').addEventListener('resize', e => {
    console.log(e.detail.contentRect.width, e.detail.contentRect.height);
    });


    // Just a tester to see how component responds.
    const c = document.querySelector('#container1');
    c.addEventListener('click', e => {
    c.classList.add('off');
    setTimeout(() => c.classList.remove('off'), 2000);
    });
    </script>
    </body>
    </html>
    76 changes: 76 additions & 0 deletions styles.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    * {
    box-sizing: border-box;
    }
    html, body {
    height: 100vh;
    margin: 0;
    }
    body {
    display: flex;
    font-family: sans-serif;
    color: #455A64;
    background: #fff;
    }
    ul {
    list-style: none;
    padding: 0;
    width: 100%;
    }
    li {
    background: #ffff;
    padding: 16px;
    margin: 8px;
    }
    #container1, #container2, #container3 {
    display: flex;
    align-items: center;
    justify-content: center;
    }
    reponsive-container {
    display: block;
    }
    #container1 {
    display: flex;
    height: 100vh;
    width: 300px;
    background: #eee;
    will-change: width;
    transition: width 600ms ease-in-out;
    }
    #container1.off {
    width: 0;
    }
    #container2 {
    background: #ffcc00;
    position: relative;
    flex: 1;
    overflow: auto;
    min-width: 100px;
    }
    #container2::before {
    font-weight: bold;
    text-transform: uppercase;
    background: blue;
    padding: 8px;
    position: absolute;
    content: attr(mode);
    top: 0;
    right: 0;
    transform: rotateZ(45deg) translate(65px, -35px);
    width: 200px;
    text-align: center;
    color: white;
    }
    #container2[mode="large"] ul {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    }
    #container2[mode="large"] li {
    width: 200px;
    height: 200px;
    }
    #container3 {
    background: #ccc;
    min-width: 100px;
    }