代码之家  ›  专栏  ›  技术社区  ›  darkhorse

如何阻止同级容器随主体滚动?

  •  0
  • darkhorse  · 技术社区  · 4 年前

    我正在尝试使用CSS在我的页面中实现一些modals。到目前为止,一切似乎都很顺利。代码如下:

    * {
        box-sizing: border-box;
    }
    
    body {
        margin: 0;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    }
    .header {
        width: 100%;
        height: 50px;
        position: fixed;
        top: 0;
        left: 0;
        background-color: dodgerblue;
    }
    .content {
        padding-top: 50px;
        padding-left: 20px;
        padding-right: 20px;
    }
    .fake-content {
        height: 200px;
        margin-top: 20px;
        background-color: rgba(0, 0, 0, 0.1);
        border-radius: 4px;
    }
    h1 {
        background-color: white;
    }
    #section-2 {
        position: sticky;
        top: 50px;
        left: 0;
    }
    .content :target {
        scroll-margin-top: 50px;
    }
    
    .modal {
        visibility: hidden;
        height: 100vh;
        width: 100%;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 20;
        display: none;
        outline: none;
    }
    .modal:target,
    .modal.show {
        visibility: visible;
        display: block;
    }
    .modal:target ~ .page,
    .modal:target ~ .content,
    .modal.show ~ .page,
    .modal.show ~ .content {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }
    
    .modal-dialog {
        display: flex;
        flex-direction: column;
        width: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        min-height: 100%;
        position: absolute;
        /*position: relative;*/
    }
    
    
    .modal-content {
        width: 400px;
        min-height: 200px;
        max-width: 100%;
        background-color: white;
        border-radius: 12px;
        padding: 20px;
        margin: auto;
        position: relative;
        animation: fadeIn 1s;
    }
    
    .modal-content .close {
        position: fixed;
        top: 5px;
        left: 5px;
        font-size: 24px;
        color: white;
        background-color: rgba(0, 0, 0, 0.5);
        width: 30px;
        height: 30px;
        text-align: center;
        line-height: 30px;
        border-radius: 50%;
        text-decoration: none;
    }
    
    @keyframes fadeIn {
        0% {
            bottom: 50px;
            opacity: 0;
        }
    
        100% {
            bottom: 0;
            opacity: 1;
        }
    }
    
    .modal-dialog::-webkit-scrollbar {
        width: 1em;
    }
    .modal-dialog::-webkit-scrollbar-thumb {
        background-color: blue;
        border-radius: 50px;
    }
    
    .mt-0 {
        margin-top: 0 !important;
    }
    
    .modal-fullscreen .modal-dialog {
    
    }
    .modal-fullscreen .modal-content {
        border-radius: 0;
        width: 100%;
        min-height: 100vh;
    }
    <div class="modal" id="modal-1" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <h2 class="mt-0">Modal 1</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="modal" id="modal-2" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <h2 class="mt-0">Modal 2</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="modal modal-fullscreen" id="modal-3" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <h2 class="mt-0">Modal 3 (Full)</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="modal modal-fullscreen" id="modal-4" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <br />
                <h2 class="mt-0">Modal 4 (Full)</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="page">
        <!-- Header start -->
        <div class="header">
        </div>
        <!-- Header end -->
    
        <!-- Content start -->
        <div class="content">
    
            <!-- Section 1 start -->
            <h1 id="section-1">
                Section 1
                <a href="#section-1">#</a>
            </h1>
            <button type="button">Use JavaScript</button>
            <br /><br />
            <a href="#modal-1">Modal 1</a>
            <a href="#modal-2">Modal 2</a>
            <a href="#modal-3">Modal 3</a>
            <a href="#modal-4">Modal 4</a>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <!-- Section 1 end -->
    
            <!-- Section 2 start -->
            <h1 id="section-2">
                Section 2
                <a href="#section-2">#</a>
            </h1>
            <a href="#modal-1">Modal 1</a>
            <a href="#modal-2">Modal 2</a>
            <a href="#modal-3">Modal 3</a>
            <a href="#modal-4">Modal 4</a>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <!-- Section 2 end -->
    
        </div>
        <!-- Content end -->
    </div>

    如您所见,基本功能运行得非常好。不幸的是,一个问题是CSS块:

    .modal:target ~ .page,
    .modal:target ~ .content,
    .modal.show ~ .page,
    .modal.show ~ .content {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }
    

    我主要添加了固定位置来停止 .page 当模态打开时滚动。它工作得很好,但每次打开模式时,页面滚动都会重置为顶部。没有JavaScript有没有办法解决这个问题?也许我看得不对。因此,阻止同级容器滚动的正确方法是什么?

    0 回复  |  直到 4 年前
        1
  •  1
  •   Jake    4 年前

    有件事我想对你有用。以下是我所做的:

    • 给情态动词打了个招呼 fixed 位置,带 overflow: auto . 这使得modal位于内容的其余部分之上,这样它就不会随之滚动,然后让modal的内容决定其内部的可滚动性。
    • 放一个 .wrapper .page 把它给了我 溢出:自动 . 这使我们能够在不需要访问的情况下更改内容的滚动行为 body 使用JavaScript。
    • 定位 .包装器 显示在页眉下方并占据页面其余部分的高度
    • 将收割台移到 page .包装器 部门。
    • .包装器 overflow: hidden 当模态打开时,这样它就不会失去它的滚动位置,所以当模态打开时我们看不到2个滚动条。

    * {
        box-sizing: border-box;
    }
    
    body {
        margin: 0;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    }
    .header {
        width: 100%;
        height: 50px;
        position: fixed;
        top: 0;
        left: 0;
        background-color: dodgerblue;
    }
    .content {
        padding-top: 50px;
        padding-left: 20px;
        padding-right: 20px;
    }
    .fake-content {
        height: 200px;
        margin-top: 20px;
        background-color: rgba(0, 0, 0, 0.1);
        border-radius: 4px;
    }
    h1 {
        background-color: white;
    }
    #section-2 {
        position: sticky;
        top: 50px;
        left: 0;
    }
    .content :target {
        scroll-margin-top: 50px;
    }
    
    .modal {
        visibility: hidden;
        height: 100vh;
        width: 100%;
        position: fixed;
        overflow: auto;
        top: 0;
        left: 0;
        z-index: 20;
        display: none;
        outline: none;
    }
    .modal:target,
    .modal.show {
        visibility: visible;
        display: block;
    }
    .modal:target ~ .page,
    .modal:target ~ .content,
    .modal.show ~ .page,
    .modal.show ~ .content {
    }
    
    .modal-dialog {
        display: flex;
        flex-direction: column;
        width: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        min-height: 100%;
        position: absolute;
        /*position: relative;*/
    }
    
    
    .modal-content {
        width: 400px;
        min-height: 200px;
        max-width: 100%;
        background-color: white;
        border-radius: 12px;
        padding: 20px;
        margin: auto;
        position: relative;
        animation: fadeIn 1s;
    }
    
    .modal-content .close {
        position: fixed;
        top: 5px;
        left: 5px;
        font-size: 24px;
        color: white;
        background-color: rgba(0, 0, 0, 0.5);
        width: 30px;
        height: 30px;
        text-align: center;
        line-height: 30px;
        border-radius: 50%;
        text-decoration: none;
    }
    
    @keyframes fadeIn {
        0% {
            bottom: 50px;
            opacity: 0;
        }
    
        100% {
            bottom: 0;
            opacity: 1;
        }
    }
    
    .modal-dialog::-webkit-scrollbar {
        width: 1em;
    }
    .modal-dialog::-webkit-scrollbar-thumb {
        background-color: blue;
        border-radius: 50px;
    }
    
    .wrapper
    {
    position: relative;
    top: 50px;
    height: calc(100vh - 50px);
    overflow: auto;
    }
    .modal.show ~ .wrapper
    {
    overflow: hidden;
    }
    
    .mt-0 {
        margin-top: 0 !important;
    }
    
    .modal-fullscreen .modal-dialog {
    
    }
    .modal-fullscreen .modal-content {
        border-radius: 0;
        width: 100%;
        min-height: 100vh;
    }
    <div class="modal" id="modal-1" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <h2 class="mt-0">Modal 1</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="modal" id="modal-2" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <h2 class="mt-0">Modal 2</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="modal modal-fullscreen" id="modal-3" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <h2 class="mt-0">Modal 3 (Full)</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
    <div class="modal modal-fullscreen" id="modal-4" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <a href="#" class="close">&times;</a>
                <br />
                <h2 class="mt-0">Modal 4 (Full)</h2>
                <a href="#">Link 1</a>
                <a href="#">Link 2</a>
                <a href="#">Link 3</a>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
                <div class="fake-content"></div>
            </div>
        </div>
    </div>
    
        <!-- Header start -->
        <div class="header">
        </div>
    <div class="wrapper">
    <div class="page">
        <!-- Header end -->
    
        <!-- Content start -->
        <div class="content">
    
            <!-- Section 1 start -->
            <h1 id="section-1">
                Section 1
                <a href="#section-1">#</a>
            </h1>
            <button type="button">Use JavaScript</button>
            <br /><br />
            <a href="#modal-1">Modal 1</a>
            <a href="#modal-2">Modal 2</a>
            <a href="#modal-3">Modal 3</a>
            <a href="#modal-4">Modal 4</a>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <!-- Section 1 end -->
    
            <!-- Section 2 start -->
            <h1 id="section-2">
                Section 2
                <a href="#section-2">#</a>
            </h1>
            <a href="#modal-1">Modal 1</a>
            <a href="#modal-2">Modal 2</a>
            <a href="#modal-3">Modal 3</a>
            <a href="#modal-4">Modal 4</a>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <div class="fake-content"></div>
            <!-- Section 2 end -->
    
        </div>
        <!-- Content end -->
    </div>
    </div>