固定位置边栏内容在 Bootstrap 模态关闭时移动

Position Fixed Sidebar Content Moves on Bootstrap Modal Close

我们有一个简单的 React 应用程序,带有一个基本的侧边栏和一个 bootstrap 模式。 这就是我们观察到奇怪行为的地方。如果我们单击“X”,我们的侧边栏会在页面上下降一会儿,直到模式关闭。 使用任何其他按钮或输入都不会观察到此行为。即使我们单击执行相同操作(关闭模式)的“关闭”按钮,边栏也不会移动。只有当我们在“X”上按下鼠标时它才会移动。

如果我在“X”上按下鼠标并将光标移开,然后向上移动鼠标,侧边栏将保持“下移”状态,直到我关闭模态框。

这很奇怪,我们不知道这里会发生什么,我们将不胜感激。

这里是 React 组件的代码:

import React, { useContext, useEffect, useState, FC } from 'react'
import { NavLink } from 'react-router-dom'
import { BoxSeam, House, Check2Circle, Download } from 'react-bootstrap-icons'
import { GlobalContext } from '../context/GlobalContext'
import Header from '../components/Header'
import Snackbar from '../components/Snackbar'
import SelectLocationModal from '../components/SelectLocationModal'
import IPropsWithChildren from '../ts/interfaces/IPropsWithChildren.interface'
import INavLink from '../ts/interfaces/INavLink.interface'
import styles from '../styles/layouts/Layout.module.scss'

const PrivateLayout: FC<IPropsWithChildren> = ({ children }) => {
    // Sidebar default is closed below 768px screens & open on larger
    // Therefore, isSidebarOpen is only an appropriate name for smaller screens
    // On larger screens this would be interpreted as isSidebarClosed
    const [isSidebarOpen, setIsSidebarOpen] = useState(false);
    const { location, setLocation } = useContext(GlobalContext);
    const navLinks: INavLink[] = [
        {
            to: '/',
            icon: <BoxSeam />,
            displayText: 'Containers',
            disabled: false
        },
        {
            to: '/receiving',
            icon: <Download />,
            displayText: "Receiving",
            disabled: false
        },
        {
            to: '/approve',
            icon: <Check2Circle />,
            displayText: "Approve",
            disabled: false
        }
    ]

    const closeOnSmScreen = () => {
        setIsSidebarOpen(false);
    }

    useEffect(() => {
        const location = localStorage.getItem('LocationID');
        if (location) {
            setLocation(location);
        }
    }, [setLocation])

    return (
        <div>
            <SelectLocationModal    
                isOpen={location === ''} 
                handleClose={() => null}
            />

            <Header 
                setIsSidebarOpen={setIsSidebarOpen} 
                isSidebarOpen={isSidebarOpen} 
            />

            <div className={styles.wrapper}>
                <nav className={`${styles.sidebar} ${isSidebarOpen ? styles.active : ''} bg-light`}>
                    <div className={styles.sidebarContent}>
                        <ul className="ps-0">
                            {
                                navLinks.map((navLink, i) => (
                                    <li key={i}>
                                        <NavLink 
                                            to={ navLink.to }
                                            activeClassName={ navLink.disabled ? '' : styles.activeLink }
                                            className={`${navLink.disabled ? styles.disabledLink : ''} d-flex align-items-center flex-md-column py-2 navLink`}
                                            onClick={closeOnSmScreen}
                                            exact
                                        >
                                            {navLink.icon}
                                            <span>{navLink.displayText}</span>
                                        </NavLink>
                                    </li>
                                ))
                            }
                        </ul>
                    </div>
                </nav>
                <div className={"childrenContainer container"}>
                    {children}
                    <Snackbar />
                </div>
            </div>
        </div>
    )
}

export default PrivateLayout

和 CSS:

@import '../variables.scss';

.childrenContainer {
    padding-top: $headerHeight;
}

.activeLink {
    color: white !important;
    background-color: $primary;
}

// Sidebar
.wrapper {
    display: flex;
    align-items: stretch;
    width: 100%;
}

.sidebar {
    position: fixed;
    top: $headerHeight;
    z-index: 999;
    min-width: 85vw;
    min-height: calc(100vh - #{$headerHeight}); 
    margin-left: -85vw;
    transition: .2s ease-in;
}

.sidebar.active {
    margin-left: 0;
    box-shadow: 2px 0px 15px 0px #000;
}

.sidebarContent {
    position: sticky;
    li {
        list-style: none;
        a {
            text-decoration: none;
            color: var(--dark);
        }
    }
}


.disabledLink {
    text-decoration: line-through !important;
}

.navLink {
    padding-left: 1rem;
    span {
        padding-left: .5rem;
    }
    svg {
        height: 1.25rem;
        width: 1.25rem;    
    }
}


@media screen and (min-width:768px) {
    .childrenContainer {
        padding-top: $headerLgHeight;
    }

    .sidebar {
        position: sticky;
        padding-top: $headerLgHeight;
        margin-left: 0;
        max-width: $sidebarWidth;
        min-width: $sidebarWidth;
        height: 100vh;
    }

    .sidebar.active {
        margin-left: -$sidebarWidth;
        box-shadow: none;
        background: white !important;
    }

    .sidebarContent {
        position: fixed;
        width: $sidebarWidth;
    }

    .navLink {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding-left: 0;
        span {
            padding-left: 0;
            font-size: .67rem;
        }
        svg {
            height: 1.25rem;
            width: 1.25rem;
        }
    }
}

这是一个重现上述行为的 code snadbox(感谢 Igor Gonak 发起此活动)。

只需删除“top”,它就会停止翻转:

.sidebar {
    position: fixed;
    // top: $headerHeight;
    z-index: 999;
    min-width: 85vw;
    min-height: calc(100vh - #{$headerHeight}); 
    margin-left: -85vw;
    transition: .2s ease-in;
}