在 react-bootstrap 中水平滑块被从页面下推

Horizontal slider gets pushed down from page in react-bootstrap

所以我正在创建一个带有侧边栏和顶部栏的应用程序,其中右侧的内容发生变化,而侧边栏和顶部栏是固定的。现在我想创建一个页面,我可以在其中放置卡片的水平旋转木马/滑块,但为了方便,它会被向下推。我不认为它与卡片有任何关系,但只与滑块有关,因为一张卡片可以正确显示。

带滑块的页面]1 and Page with 1 card,理想情况下,滑块应与显示卡片的 space 相同。我认为它可能与 react-bootstrap Col 有关,但我不确定。

Page.js

const array = [...Array(50).keys()];

return (
    <Container fluid className="justify-content-between align-content-between mt-0 mt-lg-4">
                <Row>
                    <Col lg="9" m="4" className="mt-4 mt-lg-0">
                        <div>
                            <Slider items={array} />
                        </div>
                    </Col>
        </Container>
)

Slider.js

return (
    <div className="slider">
        { items.map((item, index) => (
            <div key={index} className="slider-card-wrapper">
                {/*<div>lol</div>*/}
                <ProductCard />
            </div>
        )) }
    </div>
)

Slider.css

.slider {
    display : -webkit-box;
    overflow-x : scroll;
    overflow-y : hidden;

    border-radius : 5px;
}

.slider-card-wrapper {
    margin-left : 10px;
    margin-right : 10px;
}

ProductCard.js

return (
    <Card className="product-card">
        { isIMG &&
        <div className="product-card-img">
            <Card.Img variant="top" className="product-card-img" src="" />
            <div className="product-card-img-overlay"/>
            <div className="product-card-img-text">
                text
            </div>
        </div>
        }
      <Card.Body className="product-card-body">
          body
          body
          <br/>
          body
      </Card.Body>
    <div className="product-card-divider" />
    <Card.Footer className="product-card-footer">
        <Link className="product-card-footer-link" to="/dashboard/product">
            VIEW ITEM
        </Link>
    </Card.Footer>
    </Card>
)

ProductCard.css

.product-card {
    max-height : 400px;
    max-width : 250px;
    border-radius : 10px 10px 5px 5px;
    border : 0;
    -webkit-box-shadow: 0 0 14px #e7e7e7;
    box-shadow: 0 0 14px #e7e7e7;
    word-wrap : break-word;
}

.product-card-img {
    position : relative;
    border-radius : inherit;
    border-color : transparent;
}

.product-card-img-actual {
    display : block;
    overflow : hidden;
    border-radius : inherit;
}

.product-card-img-overlay {
    position : absolute;
    text-align : left;
    left : 0;
    right : 0;
    top : 0;
    bottom : 0;

    border-radius : inherit;
    background : #1f1f1fff;
    opacity : 0.15;
}

.product-card-img-text {
    margin-left : 10px;
    margin-bottom : 10px;
}

.product-card-body {
    text-align : center;
}

.product-card-footer {
    text-align : center;
    justify-content : center;

    border-top-width : 3px;
    border-color : #e0e0e0;

    background : transparent;
}

.product-card-footer-link {
    color : #008d74;
    text-decoration : None;
    font-weight : bold;
    margin-top : 2px;
    margin-bottom : 2px;
}

Sidebar.js

return (
    <div className={classNames("sidebar", {"open" : isSidebarOpen})}>
        <ChevronDoubleLeftIcon
          className={classNames("sidebar-toggle", {"closed" : !isSidebarOpen})}
          onClick={onSideBarOpen}
        />
        <Nav className="flex-column">
            { routes.map((route, index) => (
                route.sub_routes ?
                    <SidebarMenu
                        key={index}
                        data={route}
                    />
                    :
                    <SidebarItem
                        key={index}
                        text={route.name}
                        icon={route.icon}
                        path={route.path}
                    />
            )) }
        </Nav>
    </div>
)

Sidebar.css

.sidebar {
    min-width: 230px;
    max-width: 240px;
    height : 100vh;
    margin-left: -200px;
    background: #f7f9fb;
    transition: all .5s;
}

.sidebar.open {
    margin-left: -10px;
    transform: scale(1);
    transition: .5s;
}

.sidebar-item {
    display: inline-flex;
    margin-top: 1em;
    color: #000000;
    font-weight: bold;
}

.sidebar-item:hover {
    background-color: #f2f4f7;
}

.sidebar-menu {
    color: #000000;
    font-weight: bold;
    margin-top: 1em;
}

.sidebar-menu-item {
    color: #000000;
    font-weight: bold;
    margin-top: 0.75em;
    margin-left: 1.75em;
}

.sidebar-menu-item:hover {
    background-color: #f2f4f7;
}

.sidebar-menu-icon {
    color: #000000;
}

.sidebar-toggle {
    position: relative;
    height: 1.25em;
    width: 1.25em;
    top: 10px;
    left: 0px;
    z-index: 999;
    float: right;

    background-color: #f7f9fb;
    color: #000000;
    cursor: pointer;
    border-radius: 0px .25em .25em 0px;

    transition: transform .5s ease-in-out;
}

.sidebar-toggle.closed {
    transform-origin: center;
    transform: translateX(-0px) rotate(180deg) ;
}

.nav-item {
    color: #000000;
    font-weight: bold;
}

.nav-link {
    color: #000000;
    font-weight: 600;
    max-width: 190px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-icon {
    color: #000000;
    width: 1.25em;
    height: 1.25em;
    margin-right: 0.75em;
}

Topbar.js

return (
    <Navbar bg="light" expand="lg" sticky="top">
            <Container fluid>
                <Navbar.Brand href="#">PPDB</Navbar.Brand>
                <Navbar.Toggle aria-controls="navbarScroll"/>
                <Navbar.Collapse id="navbarScroll">
                    <Nav
                        className="me-auto my-2 my-lg-0 justify-content-center"
                        style={{maxHeight: '100px'}}
                        navbarScroll
                    >
                        <Nav.Link href="Dashboard">Home</Nav.Link>
                    </Nav>
                    <Form className="d-flex">
                        <FormControl
                            type="search"
                            placeholder="Search"
                            className="me-2"
                            aria-label="Search"
                        />
                    </Form>
                </Navbar.Collapse>
            </Container>
        </Navbar>
)

Layout.js

return (
    <div>
        <Container fluid className={"h-100"} style={{paddingLeft : "0px", paddingRight : "0px"}}>
            <Topbar />
            <Row className={"h-100"}>
                <Sidebar />
                <Col>
                    <Suspense fallback={<Spinner animation="border" role="status" />}>
                        <Routes>
                            <Route path='/' element={<h1> BASE </h1>} />
                            { routes.map((route, index) => (
                                route.sub_routes ?
                                    route.sub_routes.map((sub_route, i) => (
                                        <Route
                                            path={sub_route.path}
                                            key={i}
                                            element={<sub_route.component />}
                                        />
                                    ))
                                    :
                                    <Route
                                        path={route.path}
                                        key={index}
                                        element={<route.component />}
                                    />
                            )) }
                        </Routes>
                    </Suspense>
                </Col>
            </Row>
        </Container>
    </div>
)

您在那里过度使用了 Grid(就像许多其他人一样),因为您没有真正的 two-dimensional 布局。我强烈建议尽可能坚持使用 flexbox。在 react-bootstrap 中有一个名为 Stack 的组件。只使用 Stack 你会走得很远。在您的情况下,我将仅使用此组件布局应用程序:

查看以下沙箱:https://codesandbox.io/s/clever-elion-frb220。我提供了颜色、ID、名称和一些填充,因此您可以看到此布局的结构:

  • 上部 Stack 是垂直的,用于堆叠顶部 appbar/navbar 和应用程序的其余部分
  • Lower Stack 是水平的,用于堆叠侧边栏(可能具有固定宽度)和内容部分

关于您的问题:在您的 Layout 组件中,您定义了一个 Row,但没有定义 Cols 无处不在 - 导入的 Sidebar 组件不是 Col.

网格例如在以下情况下很有用:

  • 你有 table 喜欢的结构 (two-dimensional)
  • 您想在某些断点上定义具有不同布局的响应式设计
  • 您想使用偏移量,以便始终对齐。