Elements

Organizational chart

25 Apr 2023

"Організаційна схема" - виконано на таблицях; - адаптується при додаванні нових елементів; - при переповненні додається скроллбар; - скрипт центрує таблицю при наявності скроллбару та надає можливість свайпати курсором;
HTML
SCSS
JS
                            <div class="wrapper">
    <ul class="tree">
        <li>
            <span>
                <!-- any content -->
                <div class="tree__card">
                    <div class="tree__logo">
                        <img src="https://images.unsplash.com/photo-1560937526-61078e7eb7d8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80"
                             alt="">
                    </div>
                    <div class="tree__col">
                        <p>Title</p>
                        <p>Descr</p>
                    </div>
                </div>
                <!-- end any content -->
            </span>
            <ul>
                <li>
                    <span>
                        <!-- any content -->
                        <div class="tree__card">
                            <div class="tree__logo">
                                <img src="https://images.unsplash.com/photo-1560937526-61078e7eb7d8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80"
                                     alt="">
                            </div>
                            <div class="tree__col">
                                <p>Title</p>
                                <p>Descr</p>
                            </div>
                        </div>
                        <!-- end any content -->
                    </span>
                </li>
                <li>
                    <span>
                        <!-- any content -->
                        <div class="tree__card">
                            <div class="tree__logo">
                                <img src="https://images.unsplash.com/photo-1560937526-61078e7eb7d8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80"
                                     alt="">
                            </div>
                            <div class="tree__col">
                                <p>Title</p>
                                <p>Descr</p>
                            </div>
                        </div>
                        <!-- end any content -->
                    </span>
                    <ul>
                        <li>
                            <span>
                               <!-- any content -->
                                <div class="tree__card">
                                    <div class="tree__logo">
                                        <img src="https://images.unsplash.com/photo-1560937526-61078e7eb7d8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80"
                                             alt="">
                                    </div>
                                    <div class="tree__col">
                                        <p>Title</p>
                                        <p>Descr</p>
                                    </div>
                                </div>
                                <!-- end any content -->
                            </span>
                        </li>
                        <li>
                            <span>
                                <!-- any content -->
                                <div class="tree__card">
                                    <div class="tree__logo">
                                        <img src="https://images.unsplash.com/photo-1560937526-61078e7eb7d8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80"
                                         alt="">
                                    </div>
                                    <div class="tree__col">
                                       <p>Title</p>
                                       <p>Descr</p>
                                   </div>
                                </div>
                                <!-- end any content -->
                            </span>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>
                        
                            .wrapper {
    overflow-y: hidden;
    scrollbar-width: thin;
    scrollbar-color: #ccc black;

    &::-webkit-scrollbar {
        height: 8px;
        background-color: #ccc;
    }

    &::-webkit-scrollbar-thumb {
        background-color: black;
    }
}

.tree {
    &, & ul, & li {
        list-style: none;
        margin: 0;
        padding: 0;
        position: relative;
    }

    text-align: center;
    margin: 0 auto;

    &, & ul {
        display: table;
    }

    ul {
        width: 100%;
    }

    li {
        display: table-cell;
        padding: 38px 0;
        vertical-align: top;

        &::before {
            content: "";
            left: 0;
            position: absolute;
            right: 0;
            top: 0;
            outline: solid 1px #666;
        }

        &:first-child {
            &::before {
                left: 50%;
            }
        }

        &:last-child {
            &::before {
                right: 50%;
            }
        }
    }

    span {
        display: inline-block;
        margin: 0 .2em 38px;
        position: relative;
    }

    ul, span {
        &::before {
            content: "";
            position: absolute;
            outline: solid 1px #707070;
            left: 50%;
            height: 38px;
            top: -38px;
        }
    }

    &>li {
        margin-top: 0;
        padding: 0;

        &::before, &::after , &>span {
            outline: none;
        }
    }

    // any content
    &__card {
        position: relative;
        display: flex;
        align-items: center;
        width: 300px;
        padding: 12px 16px;
        margin: 0 5px;
        border: 2px solid black;
        background-color: white;
        box-shadow: 0 5px 8px rgba(0,0,0, 0.04);
    }

    &__logo {
        flex: 0 0 auto;
        margin-right: 20px;
        width: 149px;
        height: 76px;
        padding: 17px;
        border: 1px solid black;

        img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    }

    &__col {
        p {
            font-size: 20px;
            line-height: 28px;

            &:last-child {
                font-size: 16px;
                line-height: 22px;
                color: black;
            }
        }
    }
}
                        
                            const structureWrap = document.querySelector('.wrapper')
structureWrap.scrollLeft = (structureWrap.scrollWidth - structureWrap.clientWidth) / 2

let isDown = false;
let startX;
let scrollLeft;

structureWrap.addEventListener('mousedown', (e) => {
    isDown = true;
    structureWrap.classList.add('active');
    startX = e.pageX - structureWrap.offsetLeft;
    scrollLeft = structureWrap.scrollLeft;
});
structureWrap.addEventListener('mouseleave', () => {
    isDown = false;
    structureWrap.classList.remove('active');
});
structureWrap.addEventListener('mouseup', () => {
    isDown = false;
    structureWrap.classList.remove('active');
});
structureWrap.addEventListener('mousemove', (e) => {
    if(!isDown) return;
    e.preventDefault();
    const x = e.pageX - structureWrap.offsetLeft;
    const walk = (x - startX) * 2;
    structureWrap.scrollLeft = scrollLeft - walk;
});
                        
0