Jak przewijać stronę, gdy okno dialogowe jest dłuższe niż ekran?

87

Mam w mojej aplikacji modalne okno dialogowe, które może być dość długie w kierunku y. Wiąże się to z problemem, w wyniku którego część zawartości okna dialogowego jest ukryta u dołu strony.

wprowadź opis obrazu tutaj

Chciałbym, aby pasek przewijania okna przewijał okno dialogowe, gdy jest wyświetlane i jest zbyt długie, aby zmieściło się na ekranie, ale pozostawić główną część na miejscu za modalem. Jeśli używasz Trello , wiesz, do czego zmierzam.

Czy jest to możliwe bez używania JavaScript do sterowania paskiem przewijania?

Oto CSS, które do tej pory zastosowałem do mojego modalu i okna dialogowego:

body.blocked {
  overflow: hidden;
}

.modal-screen {
  background: #717174;
  position: fixed;
  overflow: hidden;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  opacity: 0.9;
  z-index: 50;
}

.dialog {
  background: #fff;
  position: fixed;
  padding: 12px;
  top: 20%;
  left: 50%;
  z-index: 10000;
  border-radius: 5px;
  box-shadow: 0, 0, 8px, #111;
}
David Tuite
źródło
spróbuj overflow: auto lub overflow: przewiń w oknie dialogowym ...
lakshmi priya

Odpowiedzi:

198

po prostu użyj

.modal-body {
    max-height: calc(100vh - 210px);
    overflow-y: auto;
}

zaaranżuje twój modal, a następnie przewinie w pionie

Amit Kumar Pawar
źródło
7
To powinna być akceptowana odpowiedź. Eleganckie i proste.
brianfit
2
dlaczego musimy używać 210px? Czy jest jakiś szczególny powód?
ShellZero,
9
@ShellZero, to suma: nagłówka modalnego, stopki modalnej, górnej i dolnej przestrzeni między modalem a granicami okna.
Stalinko
3
Czy istnieje rozwiązanie bez stopki na stałe i wysokości nagłówka?
Pavel
2
Jeśli chcesz, aby wyglądało to jak zwykłe przewijanie w systemie iOS, możesz dodać -webkit-overflow-scrolling: touch; a także, ponieważ Mobile Safari traktuje przewijanie przez przepełnienie inaczej niż zwykłe przewijanie strony, chyba że wyraźnie zabroniono.
Adam Gerthel
40

Oto, co naprawiło to dla mnie:

max-height: 100%;
overflow-y: auto;

EDYCJA : Teraz używam tej samej metody, która jest obecnie używana na Twitterze, gdzie tryb modalny działa trochę jak oddzielna strona na górze bieżącej treści, a zawartość za modalem nie przesuwa się podczas przewijania.

W istocie jest to:

var scrollBarWidth = window.innerWidth - document.body.offsetWidth;
$('body').css({
  marginRight: scrollBarWidth,
  overflow: 'hidden'
});
$modal.show();

Z tym CSS w trybie modalnym:

position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;

JSFiddle: https://jsfiddle.net/0x0049/koodkcng/
Wersja czystego JS (IE9 +): https://jsfiddle.net/0x0049/koodkcng/1/

Działa to bez względu na wysokość lub szerokość strony lub okna dialogowego modalnego, umożliwia przewijanie bez względu na to, gdzie znajduje się mysz / palec, nie powoduje gwałtownego skoku, niektóre rozwiązania wyłączają przewijanie głównej zawartości i również świetnie wyglądają.

0x0049
źródło
To jedyna odpowiedź, która dotyczy PO. Jak przewijać STRONĘ, gdy okno modalne jest zbyt długie. w rzeczywistości nie przewija strony, ale stwarza iluzję przewijania strony, co pasuje do przypadku, gdy nie chce się zajmować miejsca w pionie z dolnym marginesem na ekranie. wszystkie inne rozwiązania, w tym zaakceptowana odpowiedź, mają ten problem.
Ynot
13

Zmiana position

position:fixed;
overflow: hidden;

do

position:absolute;
overflow:scroll;
bitoshi.n
źródło
1
Obawiam się, że nie działa. To tak, jakby okno nie zdawało sobie sprawy, że okno dialogowe ma wysokość.
David Tuite
Problem w tym, czy position: fixed;można to zmienić na absolutne, czy inaczej?
bitoshi
2
Jeśli to zrobię, napotkam inny problem. Jeśli użytkownik jest już przewinięty w dół strony po otwarciu okna dialogowego, pojawi się ono na samej górze strony, poza ujęciem w bieżącym oknie.
David Tuite
1
To zadziałało dla mnie - zarówno w zwykłych modach, jak i kiedy miałem modal w modalu (który Bootstrap mówi, że nakładające się modale nie są obsługiwane ... wymaga niestandardowego kodu ).
eggy
To jest właściwie prawidłowa odpowiedź na OP, ponieważ przewijasz stronę, nie przewijasz modalu
carkod
6

Oto moja demonstracja okna modalnego, które automatycznie zmienia rozmiar do zawartości i zaczyna przewijać, gdy nie mieści się w oknie.

Demo okna modalnego (patrz komentarze w kodzie źródłowym HTML)

Wszystko zrobione tylko z HTML i CSS - żaden JS nie jest wymagany do wyświetlania i zmiany rozmiaru okna modalnego (ale nadal potrzebujesz go do wyświetlania okna - w nowej wersji w ogóle nie potrzebujesz JS).

Aktualizacja (więcej dem):

Chodzi o to, aby mieć zewnętrzne i wewnętrzne DIV, gdzie zewnętrzna określa stałą pozycję, a wewnętrzna tworzy przewijanie. (W wersji demonstracyjnej jest więcej DIV, aby wyglądały jak rzeczywiste okno modalne).

        #modal {
            position: fixed;
            transform: translate(0,0);
            width: auto; left: 0; right: 0;
            height: auto; top: 0; bottom: 0;
            z-index: 990; /* display above everything else */
            padding: 20px; /* create padding for inner window - page under modal window will be still visible */
        }

        #modal .outer {
            box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -o-box-sizing: border-box;
            width: 100%;
            height: 100%;
            position: relative;
            z-index: 999;
        }

        #modal .inner {
            box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -o-box-sizing: border-box;
            width: 100%;
            height: auto;       /* allow to fit content (if smaller)... */
            max-height: 100%;   /* ... but make sure it does not overflow browser window */

            /* allow vertical scrolling if required */
            overflow-x: hidden;
            overflow-y: auto;

            /* definition of modal window layout */
            background: #ffffff;
            border: 2px solid #222222;
            border-radius: 16px; /* some nice (modern) round corners */
            padding: 16px;       /* make sure inner elements does not overflow round corners */
        }
Radek Pech
źródło
Czy możesz zablokować stronę po otwarciu wyskakującego okienka, aby zapobiec przewijaniu? Jeśli użytkownik ma mysz poza wyskakującym okienkiem, przewinie stronę zamiast wyskakującego okienka, a gdy to się stanie i przejdzie nad wyskakującym okienkiem, otrzyma wyskakujące okienko i przewijanie strony. Dzięki
Adyyda
@Adyyda Możesz zatrzymać przewijanie, zawijając stronę w DIV z overflow:hiddeni ustawiając jej rozmiar na taki sam jak strona i na jej wartość margin-topujemną scroll-top.
Radek Pech
To było dobre i odpowiednie rozwiązanie Radek - responsywny, cross browser, po prostu zrobiony przy użyciu CSS. Zaoszczędziło mi trochę czasu, dzięki
Tremendus Apps
@RadekPech czym to się różni od robienia html,body{ overflow:hidden }?
Steven Vachon
@StevenVachon Na stronie tak prostej jak wersja demonstracyjna i przy ograniczonej liczbie obsługiwanych przeglądarek może nie być żadnej różnicy. Ale na bardziej złożonej stronie lub w określonych ustawieniach przeglądarki html,body{ overflow:hidden }może po prostu nie działać zgodnie z oczekiwaniami. Więc może to wyglądać na przesadę, ale lepiej jest bezpiecznie niż przepraszać .
Radek Pech
2

Samo ustalone pozycjonowanie powinno rozwiązać ten problem, ale innym dobrym obejściem tego problemu jest umieszczenie modalnych elementów div lub elementów na dole strony, poza układem witryny. Większość wtyczek modalnych nadaje swoje pozycjonowanie modalne, aby umożliwić użytkownikowi przewijanie strony głównej.

<html>
        <body>
        <!-- Put all your page layouts and elements


        <!-- Let the last element be the modal elemment  -->
        <div id="myModals">
        ...
        </div>

        </body>
</html>
Chimdi2000
źródło
2

Tutaj .. U mnie działa idealnie

.modal-body { 
    max-height:500px; 
    overflow-y:auto;
}
Evans Kwachie
źródło
2

prosty sposób możesz to zrobić przez dodanie tego css Więc właśnie dodałeś to do CSS:

.modal-body {
position: relative;
padding: 20px;
height: 200px;
overflow-y: scroll;
}

i działa!

Ashiqur Rahman
źródło
1

position:fixedoznacza, że ​​cóż, okno modalne pozostanie stałe w stosunku do punktu widzenia. Zgadzam się z twoją oceną, że jest to właściwe w tym scenariuszu, mając to na uwadze, dlaczego nie dodajesz paska przewijania do samego okna modalnego?

Jeśli tak, poprawność max-heighti overflowwłaściwości powinny załatwić sprawę.

ov
źródło
0

W końcu musiałem wprowadzić zmiany w treści strony za ekranem modalnym, aby upewnić się, że przewijanie strony nigdy nie trwało wystarczająco długo.

Gdy to zrobiłem, problemy, które napotkałem podczas stosowania position: absoluteokna dialogowego, zostały rozwiązane, ponieważ użytkownik nie mógł już przewijać strony w dół.

David Tuite
źródło
właśnie pominąłeś swój problem
Amit Kumar Pawar
zarówno pytanie, jak i post z odpowiedzią przez Ciebie, a także akceptujesz swoją odpowiedź, więc dlaczego umieszczasz tutaj pytanie?
Thiyagu
2
@Thiyagu, który jest uważany za OK. Jeśli pytający znajdzie rozwiązanie, sam powinien zamieścić odpowiedź. Mogą również zaakceptować każdą odpowiedź, która im pomogła. Ostatecznym celem jest pomoc całej społeczności.
Błędy
0

Okno Pasek przewijania strony, który można kliknąć, gdy okno Modalne jest otwarte

Ten działa dla mnie. Czysty CSS.

<style type="text/css">

body.modal-open {
padding-right: 17px !important;
}

.modal-backdrop.in {
margin-right: 16px; 

</style>

Spróbuj i daj mi znać

Hiruyuki Xanada
źródło
-1

Chciałem dodać moją czystą odpowiedź CSS do tego problemu modali z dynamiczną szerokością i wysokością. Poniższy kod działa również z następującymi wymaganiami:

  1. Umieść modal na środku ekranu
  2. Jeśli tryb modalny jest wyższy niż obszar roboczy, ściemniacz przewijania (nie zawartość modalna)

HTML:

<div class="modal">
    <div class="modal__content">
        (Long) Content
    </div>
</div>

CSS / MNIEJ:

.modal {
    position: fixed;
    display: flex;
    align-items: center;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    padding: @qquad;
    overflow-y: auto;
    background: rgba(0, 0, 0, 0.7);
    z-index: @zindex-modal;

    &__content {
        width: 900px;
        margin: auto;
        max-width: 90%;
        padding: @quad;
        background: white;
        box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75);
    }
}

W ten sposób modal zawsze znajduje się w widocznym obszarze. Szerokość i wysokość modalu są tak elastyczne, jak chcesz. Usunąłem z tego ikonę zamknięcia dla uproszczenia.

karlludwigweise
źródło