Obecnie rozwijam responsywną witrynę przy użyciu Twitter Bootstrap.
Witryna ma pełnoekranowy obraz tła na telefonie komórkowym / tablecie / komputerze. Te obrazy obracają się i zanikają, używając dwóch elementów div.
Jest prawie doskonały, z wyjątkiem jednego problemu. Korzystając z iOS Safari, przeglądarki Android lub Chrome na Androida, tło nieznacznie podskakuje, gdy użytkownik przewinie stronę w dół i powoduje ukrycie paska adresu.
Strona jest tutaj: http://lt2.daveclarke.me/
Odwiedź go na urządzeniu mobilnym i przewiń w dół, a powinieneś zobaczyć zmianę rozmiaru / przesunięcie obrazu.
Kod, którego używam dla DIV w tle, jest następujący:
#bg1 {
background-color: #3d3d3f;
background-repeat:no-repeat;
background-attachment:fixed;
background-position:center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover; position:fixed;
width:100%;
height:100%;
left:0px;
top:0px;
z-index:-1;
display:none;
}
Wszystkie sugestie są mile widziane - to już od jakiegoś czasu przykuwa mi uwagę !!
position: fixed
.Odpowiedzi:
Ten problem jest spowodowany zmniejszaniem się / przesuwaniem pasków adresu URL oraz zmianą rozmiaru elementów div # bg1 i # bg2, ponieważ mają one 100% wysokości i są „ustalone”. Ponieważ obraz tła jest ustawiony jako „okładka”, dostosuje rozmiar / położenie obrazu, ponieważ obszar zawierający jest większy.
W oparciu o responsywny charakter witryny tło musi się skalować. Rozważam dwa możliwe rozwiązania:
1) Ustaw wysokość # bg1, # bg2 na 100vh. W teorii to eleganckie rozwiązanie. Jednak iOS ma błąd vh ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ). Próbowałem użyć maksymalnej wysokości, aby zapobiec problemowi, ale pozostał.
2) Pasek adresu URL nie wpływa na rozmiar widocznego obszaru, który jest określany przez JavaScript. Dlatego JavaScript może być użyty do ustawienia statycznej wysokości na # bg1 i # bg2 na podstawie rozmiaru widocznego obszaru. Nie jest to najlepsze rozwiązanie, ponieważ nie jest to czysty CSS i podczas ładowania strony występuje niewielki skok obrazu. Jest to jednak jedyne realne rozwiązanie, które widzę, biorąc pod uwagę błędy „vh” iOS (które nie wydają się być naprawione w iOS 7).
Na marginesie, widziałem wiele problemów z tymi paskami adresu URL w systemie iOS i Android. Rozumiem cel, ale naprawdę muszą przemyśleć dziwną funkcjonalność i spustoszenie, jakie wprowadzają na stronach internetowych. Najnowsza zmiana polega na tym, że nie można już „ukrywać” paska adresu URL podczas ładowania strony w systemie iOS lub Chrome za pomocą sztuczek przewijania.
EDYCJA: Chociaż powyższy skrypt działa doskonale, aby zapobiec zmianie rozmiaru tła, powoduje zauważalną lukę, gdy użytkownicy przewijają w dół. Dzieje się tak, ponieważ utrzymuje rozmiar tła na 100% wysokości ekranu bez paska adresu URL. Jeśli dodamy do wysokości 60 pikseli, jak sugeruje szwajcarski, problem znika. Oznacza to, że nie widzimy dolnych 60 pikseli obrazu tła, gdy obecny jest pasek adresu URL, ale uniemożliwia to użytkownikom zobaczenie luki.
źródło
bg.height(jQuery(window).height() + 60);
który działa pięknie na wszystkich moich urządzeniach! Dzięki :)vh
jednostek i oczywiście100vh
jest większy, gdy pasek adresu jest ukryty. To głupie, że ten skok następuje po zatrzymaniu przewijania. Po prostu wygląda na wadliwego. Skończyło się na tym, że użyłem przejścia na wysokości, aby wyglądało na zamierzone.body
otoki<div>
zawijającej całą zawartość strony. Brak skaczących środowisk na iOS lub Androidzie!Okazało się, że odpowiedź Jasona nie do końca mi odpowiada i wciąż dostaję skoku. Javascript zapewniał, że nie było przerwy na górze strony, ale tło wciąż podskakiwało, gdy pasek adresu znikał / pojawiał się ponownie. Więc oprócz poprawki JavaScript zastosowałem
transition: height 999999s
się do div. Tworzy to przejście o tak długim czasie trwania, że praktycznie zamraża element.źródło
vw
lubvh
do ustawiania rozmiaru czcionki w tym kontenerze nadrzędnym.Mam podobny problem w nagłówku naszej witryny.
Spowoduje to gwałtowne przewijanie w przeglądarce Chrome na Androida, ponieważ .header-container zostanie przeskalowany po ukryciu paska adresu URL i usunięciu palca z ekranu.
Rozwiązanie CSS:
Dodanie następujących dwóch wierszy zapobiegnie ukryciu paska adresu URL i możliwości przewijania w pionie:
źródło
Problem można rozwiązać za pomocą zapytania o media i trochę matematyki. Oto rozwiązanie dla orientacji portretowej:
Ponieważ vh zmieni się, gdy pasek adresu URL zniknie, musisz określić wysokość w inny sposób. Na szczęście szerokość widocznego obszaru jest stała, a urządzenia mobilne mają tylko kilka różnych współczynników proporcji; jeśli możesz określić szerokość i proporcje, trochę matematyki da ci wysokość rzutni dokładnie tak, jak powinna działać . Oto proces
1) Utwórz serię zapytań o media dla współczynników proporcji, na które chcesz kierować reklamy.
użyj współczynnika proporcji urządzenia zamiast współczynnika proporcji, ponieważ ten ostatni zmieni rozmiar, gdy zniknie pasek adresu URL
Dodałem „maksymalny” do współczynnika proporcji urządzenia, aby kierować reklamy na dowolne proporcje, które zdarzają się występować pomiędzy najpopularniejszymi. Nie będą tak precyzyjne, ale będą dostępne tylko dla mniejszości użytkowników i nadal będą dość zbliżone do właściwego vh.
zapamiętaj zapytanie o media, używając opcji poziomej / pionowej, więc w przypadku portait musisz odwrócić liczby
2) dla każdego zapytania o media pomnóż dowolny procent wysokości w pionie, w jakim ma znajdować się element, przez odwrotność współczynnika proporcji.
3) Musisz określić wysokość paska adresu URL, a następnie odjąć ją od wysokości. Nie znalazłem dokładnych pomiarów, ale używam 9% dla urządzeń mobilnych w krajobrazie i wydaje się, że działa całkiem dobrze.
To nie jest zbyt eleganckie rozwiązanie, ale inne opcje też nie są zbyt dobre, biorąc pod uwagę:
Twoja witryna wydaje się być wadliwa dla użytkownika,
posiadające elementy o nieodpowiednich wymiarach, lub
Używanie javascript do podstawowych stylizacji,
Wadą jest to, że niektóre urządzenia mogą mieć inne wysokości paska adresu URL lub współczynniki proporcji niż najpopularniejsze. Jednak używanie tej metody, jeśli tylko niewielka liczba urządzeń cierpi na dodawanie / odejmowanie kilku pikseli, wydaje mi się o wiele lepsze niż każdy, kto ma rozmiar strony internetowej podczas przesuwania.
Aby było to łatwiejsze, stworzyłem również mixin SASS:
źródło
@mixin vh-fix($vh: 100)
=>height: calc(100vw * (1.333 * $vh / 100) - 9%)
height: calc(100vw * (1.333 * #{$vh} / 100) - 9%)
-9%
.Wszystkie odpowiedzi tutaj używają
window
wysokości, na którą ma wpływ pasek adresu URL. Czy wszyscy zapomnieli oscreen
wzroście?Oto moje rozwiązanie jQuery:
Dodawanie
.css()
części zmienia nieuchronnie wyrównany do góry element pozycjonowany bezwzględnie na wyrównany do dołu, więc nie ma żadnego przeskoku. Chociaż przypuszczam, że nie ma powodu, aby nie dodawać tego bezpośrednio do normalnego CSS.Potrzebujemy sniffera klienta użytkownika, ponieważ wysokość ekranu na komputerach stacjonarnych nie byłaby pomocna.
To wszystko jest założeniem
#background
jest to element o stałej pozycji wypełniający okno.Dla purystów JavaScript (ostrzeżenie - nieprzetestowane):
EDYCJA: Przepraszamy, ale to nie rozwiązuje bezpośrednio twojego problemu z więcej niż jednym tłem. Jest to jednak jeden z pierwszych wyników wyszukiwania tego problemu związanego ze skokami tła na urządzeniach mobilnych.
źródło
Natknąłem się również na ten problem, gdy próbowałem stworzyć ekran wejściowy, który obejmowałby cały widok. Niestety zaakceptowana odpowiedź już nie działa.
1) Elementy o wysokości ustawionej na
100vh
zmianę rozmiaru za każdym razem, gdy zmienia się rozmiar rzutni, w tym w przypadkach, gdy jest to spowodowane (z) wyświetlaniem paska adresu URL.2)
$(window).height()
zwraca wartości, na które ma również wpływ rozmiar paska adresu URL.Jednym z rozwiązań jest „zamrożenie” elementu za pomocą,
transition: height 999999s
jak sugeruje odpowiedź AlexKempton . Wadą jest to, że skutecznie wyłącza adaptację do wszystkich zmian rozmiaru rzutni, w tym tych spowodowanych obrotem ekranu.Więc moim rozwiązaniem jest ręczne zarządzanie zmianami widocznego obszaru za pomocą JavaScript. To pozwala mi zignorować małe zmiany, które mogą być spowodowane przez pasek adresu URL i reagować tylko na duże.
EDYCJA: Właściwie używam tej techniki razem z
height: 100vh
. Strona jest renderowana poprawnie od samego początku, a następnie włącza się javascript i zaczyna ręcznie zarządzać wysokością. W ten sposób nie ma żadnego migotania podczas ładowania strony (a nawet później).źródło
height: 100vh
w początkowym CSS, ustawiam,min-height:100vh
a następnie przy zmianie rozmiaru okna obliczammin-height
i ustawiam go na wysokość portu widoku. Jest to przydatne, gdy witryna jest wyświetlana na małych ekranach, a zawartość jest zbyt duża, aby zmieścić się w widocznym obszarze. Ustawienie debounce / throttle Timeout na zdarzeniu zmiany rozmiaru pomaga poprawić wydajność w niektórych przeglądarkach (zmiana rozmiaru zwykle uruchamia się bardzo często)min-height
zamiast tego, ale potem napotykam problem, gdy musiałem wyśrodkować wewnętrzną zawartość w pionie. W jakiś sposób centrowanie w pionie może być trudne, gdy element zewnętrzny jestheight
ustawiony naauto
. Więc wymyśliłem stałą minimalną wysokość, która powinna wystarczyć do umieszczenia dowolnej możliwej treści i ustawiłem ją w początkowym CSS. Ponieważmin-height
ma wyższy priorytet niżheight
, działa całkiem dobrze.display: table
, a następnie ustawienie pojemnika wewnętrznegodisplay: table-cell
zvertical-align: middle
. Działał jak urok.Rozwiązanie obecnie używam jest do sprawdzenia
userAgent
na$(document).ready
celu sprawdzenia, czy jest to jeden z przestępstwa przeglądarek. Jeśli tak, wykonaj następujące kroki:$(window).resize
, zaktualizuj tylko odpowiednie wartości wysokości, jeśli nowy wymiar poziomej rzutni różni się od jego wartości początkowejOpcjonalnie możesz również przetestować zezwalanie na zmiany rozmiaru w pionie tylko wtedy, gdy są one poza wysokością pasków adresu.
Aha, i pasek adresu ma wpływ
$(window).height
. Zobacz: Zmiana paska adresu przeglądarki Mobile Webkit (chrome) $ (window) .height (); Dokonywanie rozmiaru tła: zmiana skali okładki za każdym razem JS „Okno” szerokość-wysokość a „ekran” szerokość-wysokość?źródło
Znalazłem naprawdę proste rozwiązanie bez użycia Javascript:
Wszystko to opóźnia ruch, tak że jest niewiarygodnie wolny, że nie jest zauważalny.
źródło
100%
,100vh
. IE8 to jedyna duża przeglądarka, która nie obsługuje przejść.Moje rozwiązanie wymagało trochę javascript. Zachowaj 100% lub 100 vh w elemencie div (pozwoli to uniknąć wyświetlania elementu div podczas początkowego ładowania strony). Następnie, gdy strona się załaduje, chwyć wysokość okna i zastosuj ją do danego elementu. Unika skoku, ponieważ teraz masz statyczną wysokość swojego div.
źródło
Stworzyłem waniliowe rozwiązanie javascript do korzystania z jednostek VH. Używanie VH praktycznie wszędzie odbywa się poprzez paski adresu minimalizujące przewijanie. Aby naprawić błąd, który wyświetla się podczas przerysowywania strony, mam tutaj ten plik js, który pobierze wszystkie elementy za pomocą jednostek VH (jeśli nadasz im klasę
.vh-fix
) i nada im wbudowane wysokości pikseli. Zasadniczo zamrażanie ich na żądanej wysokości. Możesz to zrobić podczas obracania lub zmiany rozmiaru widocznego obszaru, aby zachować responsywność.To rozwiązało wszystkie moje przypadki użycia, mam nadzieję, że pomoże.
źródło
to jest moje rozwiązanie, aby rozwiązać ten problem, dodałem komentarze bezpośrednio do kodu. Przetestowałem to rozwiązanie i działa dobrze. Mam nadzieję, że będziemy przydatni, ponieważ każdy ma ten sam problem.
źródło
To najlepsze rozwiązanie (najprostsze) ponad wszystko, czego próbowałem.
... I to nie zachowuje natywnego wyglądu paska adresu !
Możesz na przykład ustawić wysokość w CSS na 100%, a następnie ustawić wysokość na 0,9 * wysokości okna w pikselach za pomocą javascript, kiedy dokument jest ładowany.
Na przykład z jQuery:
$("#element").css("height", 0.9*$(window).height());
)
Niestety nie ma niczego, co działa z czystym CSS: P, ale jest też minimalne
vh
ivw
zawiera błędy na iPhone'ach - użyj procentów.źródło
Ustawiłem element szerokości za pomocą javascript. Po ustawieniu de vh.
html
css
javascript
To działa dla mnie. Nie używam jquery ect. ponieważ chcę, aby ładował się tak szybko, jak to możliwe.
źródło
Zrozumienie wszystkich szczegółów tego problemu i znalezienie najlepszej implementacji zajęło kilka godzin. Okazuje się, że od kwietnia 2016 r. Tylko iOS Chrome ma ten problem. Próbowałem na Androidzie Chrome i iOS Safari - oba były w porządku bez tej poprawki. Więc poprawka dla iOS Chrome, której używam, to:
źródło
Prosta odpowiedź, jeśli pozwala na to twoje tło, dlaczego nie ustawić rozmiaru tła: na coś, co obejmuje tylko szerokość urządzenia za pomocą zapytań o media i użyj obok: po pozycji: naprawiono; siekać tutaj .
IE: background-size: 901px; dla dowolnych ekranów <900px? Nie jest doskonały ani responsywny, ale zadziałał dla mnie urokiem na telefonie komórkowym <480px, ponieważ używam abstrakcyjnego BG.
źródło
Używam tego obejścia: Napraw wysokość bg1 podczas ładowania strony przez:
Następnie dołącz detektor zdarzenia zmiany rozmiaru do okna, który robi to: jeśli różnica wysokości po zmianie rozmiaru jest mniejsza niż 60 pikseli (cokolwiek więcej niż wysokość paska adresu URL), nie rób nic, a jeśli jest większa niż 60 pikseli, ustaw ponownie wysokość bg1 na wysokość jego rodzica! pełny kod:
PS: Ten błąd jest tak irytujący!
źródło
Podobna do odpowiedzi @AlexKempton. (przepraszam, nie mogę komentować)
Używałem długich opóźnień przejścia, aby zapobiec zmianie rozmiaru elementu.
na przykład:
Wadą jest to, że zapobiega zmianie rozmiaru elementu, w tym przy obracaniu urządzenia, jednak możesz użyć niektórych JS do wykrycia
orientationchange
i zresetowania wysokości, jeśli był to problem.źródło
Dla tych, którzy chcieliby posłuchać rzeczywistej wysokości wewnętrznej i przewijania w pionie okna, podczas gdy przeglądarka mobilna Chrome zmienia pasek adresu URL z pokazanego na ukryty i odwrotnie, jedynym rozwiązaniem, które znalazłem, jest ustawienie funkcji interwału i zmierzyć rozbieżność wartości
window.innerHeight
z poprzednią wartością.To wprowadza ten kod:
Mam nadzieję, że to się przyda. Czy ktoś zna lepsze rozwiązanie?
źródło
Rozwiązaniem, które wymyśliłem, mając podobny problem, było ustawienie wysokości elementu przy
window.innerHeight
każdym uruchomieniutouchmove
zdarzenia.To sprawia, że element obejmuje zawsze dokładnie 100% dostępnego ekranu, ni mniej, ni więcej. Nawet podczas ukrywania lub pokazywania paska adresu.
Niemniej jednak szkoda, że musimy wymyślać takie łatki, w których proste
position: fixed
powinny działać.źródło
Dzięki obsłudze niestandardowych właściwości CSS (zmiennych) w iOS możesz je ustawić za pomocą JS i używać ich tylko na iOS.
źródło
Moja odpowiedź jest dla każdego, kto tu przychodzi (tak jak ja), aby znaleźć odpowiedź na błąd spowodowany ukrywaniem adresu gołego / interfejsu przeglądarki.
Ukrywanie paska adresu powoduje wyzwolenie zdarzenia zmiany rozmiaru. Ale inaczej niż w przypadku innych zdarzeń zmiany rozmiaru, takich jak przejście do trybu poziomego, nie zmienia to szerokości okna. Więc moim rozwiązaniem jest podłączenie się do zdarzenia resize i sprawdzenie, czy szerokość jest taka sama.
źródło