Mam bardzo dziwny problem ... w każdej przeglądarce i wersji mobilnej napotkałem takie zachowanie:
- wszystkie przeglądarki mają górne menu po załadowaniu strony (na przykład pasek adresu), które przesuwają się w górę po rozpoczęciu przewijania strony.
- 100vh czasami jest obliczane tylko na widocznej części rzutni, więc gdy pasek przeglądarki przesuwa się w górę, 100vh zwiększa się (pod względem pikseli)
- cały układ ponownie maluje i dostosowuje od czasu zmiany wymiarów
- zły efekt skakania dla wygody użytkownika
Jak można uniknąć tego problemu? Kiedy po raz pierwszy usłyszałem o wysokości rzutni, byłem podekscytowany i pomyślałem, że mogę użyć jej do bloków o stałej wysokości zamiast javascript, ale teraz myślę, że jedynym sposobem na to jest w rzeczywistości javascript z pewnym zdarzeniem zmiany rozmiaru ...
problem można zobaczyć na: przykładowej stronie
Czy ktoś może mi pomóc z / sugerować rozwiązanie CSS?
prosty kod testowy:
html
css
viewport-units
Nereo Costacurta
źródło
źródło
transition: 0.5s
czegoś takiego, aby zmiana była mniej gwałtowna?Odpowiedzi:
Niestety jest to celowe…
Jest to dobrze znany problem (przynajmniej w safari na urządzeniach mobilnych), który jest celowy, ponieważ zapobiega innym problemom. Benjamin Poulain odpowiedział na błąd w pakiecie internetowym :
Nicolas Hoizey dość dokładnie to zbadał: https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile -browsers.html
Brak zaplanowanej poprawki
W tym momencie niewiele można zrobić poza powstrzymaniem się od używania wysokości rzutni na urządzeniach mobilnych. Chrome zmienił się na to również w 2016 roku:
źródło
$(window).height()
ten błąd nie ma wpływu, więc pójdę tą drogą. Dziękuję Ci!position:fixed
. Jest to podobne do implementacji w Safari. Czytaj więcej: developers.google.com/web/updates/2016/12/url-bar-resizingvh
ani nie zmienia<html> 100%
wysokości po pierwszym załadowaniu. To jest naprawdę świetne - jako przebijanie układu / przepuszczanie, gdy ukrywa się pasek adresu URL, może wyglądać okropnie.Firefox
iEdge
Mobile
wciąż dynamicznie aktualizują sięvh
i<html>
zwiększają wysokość, powodując wiele odrywania i zmiany rozmiaru wszystkich elementów podczas przewijania, szczególnie złe, jeśli używamy plików SVG do obrazów tłaMożesz spróbować
min-height: -webkit-fill-available;
w swoim css zamiast100vh
. To powinno zostać rozwiązaneźródło
min-height: 100vh;
jako rezerwowy, gdzie-webkit-fill-available
nie jest obsługiwany.min-height: 100vh;
tam pozostać, ponieważ w przeciwnym razie zepsuje się w przeglądarkach takich jak Firefox (przynajmniej na komputerze stacjonarnym, iOS używa webkita bez względu na przeglądarkę).w mojej aplikacji robię to tak (maszynopis i zagnieżdżone postcss, więc odpowiednio zmień kod):
w twoim css:
działa przynajmniej na Chrome Mobile i iPadzie. To, co nie działa, to dodawanie aplikacji do ekranu głównego w systemie iOS i kilkakrotna zmiana orientacji - w jakiś sposób poziomy powiększenia psują się z wartością innerHeight, mogę opublikować aktualizację, jeśli znajdę rozwiązanie.
Próbny
źródło
W przypadku wielu witryn, które buduję, klient poprosi o baner 100vh, a jak już odkryłeś, powoduje to złe wrażenia na telefonie komórkowym, gdy zaczynasz przewijać. W ten sposób rozwiązuję problem, zapewniając płynne i spójne działanie na wszystkich urządzeniach:
Najpierw ustawiłem element banner CSS na
height:100vh
Następnie używam jQuery, aby uzyskać wysokość mojego elementu banera w pikselach i stosuję styl wbudowany przy użyciu tej wysokości.
W ten sposób rozwiązuje się problem na urządzeniach mobilnych, gdy podczas ładowania strony element banner jest ustawiany na 100vh przy użyciu CSS, a następnie jQuery zastępuje to, umieszczając wbudowany CSS na moim elemencie banner, który powstrzymuje jego zmianę rozmiaru, gdy użytkownik zaczyna przewijać.
Jednak na pulpicie, jeśli użytkownik zmieni rozmiar okna przeglądarki, mój baner nie zmieni rozmiaru, ponieważ ma teraz stałą wysokość ustawioną w pikselach z powodu powyższego jQuery. Aby rozwiązać ten problem, używam Mobile Detect, aby dodać klasę „mobile” do treści mojego dokumentu. A potem zawijam powyższe jQuery w instrukcji if:
W rezultacie, jeśli użytkownik jest na urządzeniu mobilnym, klasa „mobile” jest obecna na treści mojej strony i powyższe polecenie jQuery jest wykonywane. Tak więc mój element transparentu zastosuje tylko wbudowany CSS na urządzeniach mobilnych, podczas gdy na komputerze oryginalna reguła 100vh CSS pozostaje na swoim miejscu.
źródło
$('.banner').css({ height: window.innerHeight });
, czyli „prawdziwą” wysokość rzutni. Przykład działania innerHeightdocument.querySelector('.banner').style.height = window.innerHeight;
dla osób piszących rzeczywisty JavaScript.Spójrz na tę odpowiedź: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
źródło
Wymyśliłem komponent React - sprawdź, czy używasz React lub przejrzyj kod źródłowy, jeśli nie, abyś mógł go dostosować do swojego środowiska.
Ustawia wysokość div pełnego ekranu na,
window.innerHeight
a następnie aktualizuje ją przy zmianie rozmiaru okna.źródło
Gdy szukałem rozwiązania kilka dni, tutaj jest moje dla wszystkich korzystających z VueJS z Vuetify (moje rozwiązanie używa paska aplikacji, szuflady nawigacji i stopki): stworzyłem App.scss (używany w aplikacji. vue) o następującej treści:
źródło
Dla mnie taka sztuczka zadziałała:
źródło
@ nils wyjaśnił to jasno.
Co dalej?
Właśnie wróciłem do używania względnego „klasycznego”
%
(procentowego) w CSS.Często potrzeba więcej wysiłku, aby zaimplementować coś, niż byłoby to potrzebne
vh
, ale przynajmniej masz dość stabilne rozwiązanie, które działa na różnych urządzeniach i przeglądarkach bez dziwnych usterek interfejsu użytkownika.źródło
Właśnie znalazłem zaprojektowaną przeze mnie aplikację internetową, która ma ten problem z iPhone'ami i iPadami, i znalazłem artykuł sugerujący rozwiązanie tego problemu za pomocą zapytań o media skierowanych do określonych urządzeń Apple.
Nie wiem, czy mogę udostępnić kod z tego artykułu tutaj, ale adres jest następujący: http://webdesignerwall.com/tutorials/css-fix-for-ios-vh-unit-bug
Cytując artykuł: „po prostu dopasuj wysokość elementu do wysokości urządzenia za pomocą zapytań o media kierowanych na starsze wersje rozdzielczości iPhone'a i iPada”.
Dodali tylko 6 zapytań o media, aby dostosować elementy o pełnej wysokości, i powinno działać, ponieważ jest w pełni zaimplementowane w CSS.
Edycja w toku: Nie mogę teraz go przetestować, ale wrócę i przedstawię wyniki.
źródło
Ponieważ jestem nowy, nie mogę komentować innych odpowiedzi.
Jeśli ktoś szuka odpowiedzi, aby to zadziałało (i może korzystać z javascript - ponieważ wydaje się, że jest to w tej chwili wymagane), to podejście zadziałało dla mnie całkiem dobrze i uwzględnia również zmianę orientacji mobilnej. Używam Jquery dla przykładowego kodu, ale powinno być wykonalne z vanillaJS.
-Po pierwsze, używam skryptu, aby wykryć, czy urządzenie jest dotykane, czy unosi się. Przykład gołych kości:
Powoduje to dodanie klasy do elementu body zgodnie z typem urządzenia (najechanie myszą lub dotyk), którego można później użyć w skrypcie wysokości.
-Następnie użyj tego kodu, aby ustawić wysokość urządzenia przy obciążeniu i przy zmianie orientacji:
-Timeout jest ustawiony tak, aby urządzenie poprawnie obliczało nową wysokość po zmianie orientacji. Jeśli nie ma limitu czasu, z mojego doświadczenia wynika, że wysokość nie będzie poprawna. 500 ms może być przesadzeniem, ale zadziałało dla mnie.
Opcja -100vh na urządzeniach hover jest rezerwowa, jeśli przeglądarka zastępuje CSS 100vh.
źródło
Poniższy kod rozwiązał problem (z jQuery).
Pozostałe elementy wykorzystują
%
jako jednostkę do wymianyvh
.źródło
Oto obejście, którego użyłem w mojej aplikacji React.
iPhone 11 Pro i iPhone Pro Max - 120 pikseli
iPhone 8 - 80px
Jest to kompromis, ale stosunkowo prosta poprawka
źródło
Dla mnie działało:
body
Zajmie widoczną wysokość rzutni oraz#your-app-container
zheight: 100%
sprawi, że pojemnik ma widoczną wysokość rzutni.źródło
Mamy nadzieję, że będzie to zmienna środowiskowa CSS zdefiniowana przez UA, jak sugerowano tutaj: https://github.com/w3c/csswg-drafts/issues/2630#issuecomment-397536046
źródło
Ponieważ nie zostanie to naprawione, możesz zrobić coś takiego:
Dla mnie było to najszybsze i czystsze rozwiązanie niż gra w JavaScript, która nie mogła działać na wielu urządzeniach i przeglądarkach.
Wystarczy użyć odpowiedniej wartości,
vh
która odpowiada Twoim potrzebom.źródło
Korzystanie z vh na urządzeniach mobilnych nie będzie działać z 100vh, ze względu na ich wybór projektu przy użyciu całej wysokości urządzenia, bez pasków adresu itp.
Jeśli szukasz układu zawierającego wysokości div proporcjonalne do rzeczywistej wysokości widoku, używam następującego rozwiązania czystego css:
Masz dwie opcje ustawiania wysokości rzutni, ręcznie ustaw --devHeight na wysokość, która działa (ale musisz wprowadzić tę wartość dla każdego typu urządzenia, dla którego kodujesz)
lub
Użyj javascript, aby uzyskać wysokość okna, a następnie zaktualizuj --devheight po załadowaniu i odświeżeniu okienka ekranu (wymaga to jednak użycia javascript i nie jest czystym rozwiązaniem css)
Po uzyskaniu prawidłowej wysokości widoku można utworzyć wiele elementów div z dokładnym procentem całkowitej wysokości rzutni, po prostu zmieniając mnożnik dla każdego elementu div, do którego przypisano wysokość.
0,10 = 10% wysokości widoku 0,57 = 57% wysokości widoku
Mam nadzieję, że to może komuś pomóc;)
źródło
Możesz to zrobić, dodając następujący skrypt i styl
Styl
źródło
Spróbuj
html, body { height: 100% }
czegoś z efektem 100vh na urządzeniach mobilnych.źródło
Możesz spróbować nadać
position: fixed; top: 0; bottom: 0;
właściwości swojemu kontenerowi.źródło