Material Navigation

Recently I wanted to use the navigation transition suggested by the Material Design guidelines (the element into the list growns when selected) into a web page, but I've not been able to find any working example online. So I've managed to provide my own implementation.
This is part CSS and part Javascript, as I've not found any CSS-only method to interact with "previous" elements given a selected node (required to slide them up on node's activation). The active/inactive class toggle may be eventually replaced with the usual "checked input trick".

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <style>
        body, html {
            padding: 0;
            margin: 0;
        }

        .container {
            padding: 0 15px;
        }

        .cell {
            width: 100%;
            height: 200px;
            margin-bottom: 10px;
            background: #FFF;

            /*
                Let the browser manage smooth transitions when CSS properties
                are changed, instead of animate them through slow Javascript...
            */
            transition: all .5s;
        }

        .cell .off {
            width: 100%;
            background-size: cover;
            background-position: center center;
            transition: all .5s;
        }

        .cell .on {
            padding: 0px 15px;
        }

        .cell.inactive .off {
            height: 100%;
        }

        .cell.inactive .on {
            display: none;
        }

        .cell.active {
            /*
                The active element is as large and tall as the whole viewport
            */
            height: 100vh;
            width: 100vw;

            /*
                This is to extend the active cell wide screen.
                Width will be set in Javascript section.
            */
            margin-left: -15px;
        }

        .cell.active .off {
            height: 300px;
        }
    </style>
</head>

<body>
    <div class="container">
        <!--
            A few cell to scroll and animate.
            The button is used to switch the state from inactive to active, and
            viceversa.
        -->
        <div class="cell inactive">
            <div class="off" style="background-image: url('https://picsum.photos/200/300?1')">
                <div class="cell-1">
                    <button class="btn">Switch</button>
                </div>
            </div>
            <div class="on">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae posuere ante. Ut a facilisis eros. Aliquam in lorem viverra, mollis libero a, cursus urna. Suspendisse eget rutrum lectus. Integer vel quam in velit porttitor sollicitudin. Vestibulum non finibus nulla, vitae lobortis lectus. Aenean eget leo ut nisi vestibulum scelerisque. Nam ultrices arcu vel tincidunt euismod. In hac habitasse platea dictumst. Suspendisse et odio urna. Curabitur id aliquet urna.</p>
            </div>
        </div>

        <div class="cell inactive">
            <div class="off" style="background-image: url('https://picsum.photos/200/300?2')">
                <div class="cell-1">
                    <button class="btn">Switch</button>
                </div>
            </div>
            <div class="on">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae posuere ante. Ut a facilisis eros. Aliquam in lorem viverra, mollis libero a, cursus urna. Suspendisse eget rutrum lectus. Integer vel quam in velit porttitor sollicitudin. Vestibulum non finibus nulla, vitae lobortis lectus. Aenean eget leo ut nisi vestibulum scelerisque. Nam ultrices arcu vel tincidunt euismod. In hac habitasse platea dictumst. Suspendisse et odio urna. Curabitur id aliquet urna.</p>
            </div>
        </div>

        <div class="cell inactive">
            <div class="off" style="background-image: url('https://picsum.photos/200/300?3')">
                <div class="cell-1">
                    <button class="btn">Switch</button>
                </div>
            </div>
            <div class="on">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae posuere ante. Ut a facilisis eros. Aliquam in lorem viverra, mollis libero a, cursus urna. Suspendisse eget rutrum lectus. Integer vel quam in velit porttitor sollicitudin. Vestibulum non finibus nulla, vitae lobortis lectus. Aenean eget leo ut nisi vestibulum scelerisque. Nam ultrices arcu vel tincidunt euismod. In hac habitasse platea dictumst. Suspendisse et odio urna. Curabitur id aliquet urna.</p>
            </div>
        </div>

        <div class="cell inactive">
            <div class="off" style="background-image: url('https://picsum.photos/200/300?4')">
                <div class="cell-1">
                    <button class="btn">Switch</button>
                </div>
            </div>
            <div class="on">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae posuere ante. Ut a facilisis eros. Aliquam in lorem viverra, mollis libero a, cursus urna. Suspendisse eget rutrum lectus. Integer vel quam in velit porttitor sollicitudin. Vestibulum non finibus nulla, vitae lobortis lectus. Aenean eget leo ut nisi vestibulum scelerisque. Nam ultrices arcu vel tincidunt euismod. In hac habitasse platea dictumst. Suspendisse et odio urna. Curabitur id aliquet urna.</p>
            </div>
        </div>

        <div class="cell inactive">
            <div class="off" style="background-image: url('https://picsum.photos/200/300?5')">
                <div class="cell-1">
                    <button class="btn">Switch</button>
                </div>
            </div>
            <div class="on">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae posuere ante. Ut a facilisis eros. Aliquam in lorem viverra, mollis libero a, cursus urna. Suspendisse eget rutrum lectus. Integer vel quam in velit porttitor sollicitudin. Vestibulum non finibus nulla, vitae lobortis lectus. Aenean eget leo ut nisi vestibulum scelerisque. Nam ultrices arcu vel tincidunt euismod. In hac habitasse platea dictumst. Suspendisse et odio urna. Curabitur id aliquet urna.</p>
            </div>
        </div>

        <div class="cell inactive">
            <div class="off" style="background-image: url('https://picsum.photos/200/300?6')">
                <div class="cell-1">
                    <button class="btn">Switch</button>
                </div>
            </div>
            <div class="on">
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae posuere ante. Ut a facilisis eros. Aliquam in lorem viverra, mollis libero a, cursus urna. Suspendisse eget rutrum lectus. Integer vel quam in velit porttitor sollicitudin. Vestibulum non finibus nulla, vitae lobortis lectus. Aenean eget leo ut nisi vestibulum scelerisque. Nam ultrices arcu vel tincidunt euismod. In hac habitasse platea dictumst. Suspendisse et odio urna. Curabitur id aliquet urna.</p>
            </div>
        </div>
    </div>

    <!--
        The old, good jQuery...
    -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" crossorigin="anonymous"></script>

    <script>
        /*
            Handy jQuery extension from here
            https://stackoverflow.com/a/5386150
        */
        jQuery.fn.reverse = [].reverse;

        $('.cell .btn').click(function() {
            var cell = $(this).closest('.cell');
            cell.toggleClass('inactive').toggleClass('active');

            if (cell.hasClass('active')) {
                /*
                    Lock scrolling on body, to focus on the activated cell
                */
                $('body').css({overflow: 'hidden'});

                /*
                    Here we move the top elements up for the distance required
                    to translate the active cell to the top of the viewport.
                    Moving the previous elements we obtain the illusion of them
                    leaving space to the cell, as it already happens to the
                    bottom (the effect is due height grown of the cell).
                */
                var wscroll = $(window).scrollTop();
                var distance = cell.offset().top - wscroll;
                cell.prevAll().css({'margin-top': "-" + (distance / cell.prevAll().length) + "px"});
            }
            else {
                /*
                    Reset the initial properties
                */
                $('body').css({overflow: 'auto'});
                cell.prevAll().reverse().css({'margin-top': '0'});
            }
        });
    </script>
</body>

</html>
Show Comments