Pracuję z wieloma tabletami - zarówno z systemem Android i iOS. Obecnie mam następujące warianty rozdzielczości dla wszystkich tabletów.
- 1280 x 800
- 1280 x 768
1024 x 768 (oczywiście iPad)- iPad nie ma tego problemu
Najprostszym sposobem zastosowania stylu opartego na orientacji urządzenia jest użycie orientacji zapytania o media przy użyciu następującej składni.
@media all and (orientation:portrait)
{
/* My portrait based CSS here */
}
@media all and (orientation:landscape)
{
/* My landscape based CSS here */
}
Działa to doskonale na wszystkich tabletach. ALE problem polega na tym, że gdy urządzenie jest w trybie portretowym i użytkownik stuka w dowolne pole wejściowe (np. Wyszukiwanie), pojawia się klawiatura ekranowa - co zmniejsza widoczny obszar strony internetowej i zmusza ją do renderowania w css opartym na poziomie. Na tabletach z Androidem zależy to od wysokości klawiatury. Ostatecznie strona wygląda na zepsutą. Dlatego nie mogę użyć zapytania o media w CSS3 do stosowania stylów opartych na orientacji (chyba że istnieje lepsze zapytanie o media do orientacji docelowej). Oto http://jsfiddle.net/hossain/S5nYP/5/ skrzypce, które to emuluje - do testowania urządzeń użyj pełnej strony testowej - http://jsfiddle.net/S5nYP/embedded/result/
Oto zrzut ekranu przedstawiający zachowanie pobrane ze strony demonstracyjnej.
Czy jest więc jakaś alternatywa, aby rozwiązać ten problem, jestem otwarty na rozwiązanie oparte na JavaScript, jeśli natywne rozwiązanie oparte na CSS nie działa.
Znalazłem fragment na http://davidbcalhoun.com/2010/dealing-with-device-orientation, który sugeruje dodanie klasy i celu na tej podstawie. Na przykład:
<html class="landscape">
<body>
<h1 class="landscape-only">Element Heading - Landscape</h1>
<h1 class="portrait-only">Element Heading - Portrait</h1>
<!-- .... more... ->
# CSS
.landscape .landscape-only { display:block; }
.landspace .portrait-only { display:none; }
.portrait .portrait-only { display:block; }
.portrait .landscape-only { display:none; }
Co o tym myślicie? Czy masz lepsze rozwiązanie?
źródło
known limitation
.Odpowiedzi:
Wiem, że to opóźnienie o kilka lat, ale znalazłem świetne rozwiązanie
W przypadku mediów w orientacji poziomej:
@media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */}
A dla mediów portretowych:
@media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */}
Pełne rozwiązanie i dlaczego działa, można znaleźć tutaj Michael Barret - Wyzwania przeglądarki Android
Edycja: ten link wygasł, ale migawkę można znaleźć w archiwum internetowym: Michael Barret - wyzwania przeglądarki Android
źródło
Problem leży w sposobie obliczania orientacji:
http://www.w3.org/TR/css3-mediaqueries/#orientation
Ponieważ wysokość / szerokość jest obliczana dla widocznej rzutni, klawiatura programowa najwyraźniej powoduje zmianę orientacji teraz, gdy szerokość rzutni jest mniejsza niż wysokość. Jednym z rozwiązań byłoby po prostu użycie zapytań o media w oparciu o to samo
width
. To sprawia, że jest bardziej elastyczny w różnych urządzeniach, niezależnie od orientacji, nie wspominając o szerokości / wysokości jest bardziej obsługiwana niż orientacja.Jeśli chcesz wziąć pod uwagę szerokość zamiast orientacji, użyję iPhone'a jako przykładu:
@media screen and (max-width: 320px) { /* rules applying to portrait */ } @media screen and (max-width: 480px) { /* rules applying to landscape */ }
Takie podejście jest bardziej elastyczne niż orientacja, ponieważ zapytania nie ograniczają się do urządzeń / klientów użytkownika obsługujących orientację, nie wspominając o tym, że orientacja mówi niewiele w porównaniu z szerokością.
Oczywiście, jeśli naprawdę potrzebujesz znać orientację, wydaje się, że początkowo ustawiasz klasę i po prostu użyj tego, co może być najlepszą opcją.
źródło
@media all and (max-device-wdith:NNNpx){}
lub@media all and (min-device-wdith:NNNpx){}
lub@media all and (device-wdith:NNNpx){}
and (orientation:portrait)
i po prostu stosując maksymalną i minimalną szerokość, rozwiązało mój problem. !!!Alternatywą może być użycie
device-aspect-ratio
, które pozostaje niezmienione. Jednak w Webkicie obracanie urządzenia nie powoduje aktualizacji reguł CSS przy użyciu tego zapytania, mimo że testy JavaScript zwracają wartość true dla nowego współczynnika proporcji. Najwyraźniej jest to spowodowane błędem , ale nie mogę znaleźć raportu o błędzie. Używanie kombinacjiorientation
i{min,max}-device-aspect-ratio
wydaje się działać dobrze:@media screen and (max-device-aspect-ratio: 1/1) and (orientation: portrait) @media screen and (min-device-aspect-ratio: 1/1) and (orientation: landscape)
Użycie
orientation
wyzwalaczy aktualizuje się zgodnie z oczekiwaniami, a użyciedevice-aspect-ratio
ograniczeń zaktualizowano zgodnie z rzeczywistymi zmianami orientacji.źródło
Przerobiłem opcje wymienione powyżej i żadna z nich nie rozwiązała problemów. Przerzuciłem się na używanie screen.availHeight, ponieważ daje spójne wyniki wysokości, unikając problemu z wyświetlaniem klawiatury.
// Avoiding the keyboard in Android causing the portrait orientation to change to landscape. // Not an issue in IOS. Can use window.orientation. var currentOrientation = function() { // Use screen.availHeight as screen height doesn't change when keyboard displays. if(screen.availHeight > screen.availWidth){ $("html").addClass('portrait').removeClass('landscape'); } else { $("html").addClass('landscape').removeClass('portrait'); } } // Set orientation on initiliasation currentOrientation(); // Reset orientation each time window is resized. Keyboard opening, or change in orientation triggers this. $(window).on("resize", currentOrientation);
źródło
Dla mnie to załatwiło sprawę:
@media screen and (max-device-aspect-ratio: 1/1), (max-aspect-ratio: 1/1){ /*Portrait Mode*/ };
Chociaż
max-aspect-ratio
dba o uruchomienie trybu portretowego po prostu przez zmianę rozmiaru okna (przydatne w przypadku komputerów PC i innych urządzeń tylko wmax-device-aspect-ratio
orientacji poziomej ), pomaga w przypadku smartfonów lub innych urządzeń o zmiennej orientacji. A ponieważ nie deklaruję konkretnych ustawień trybu poziomego, nawet jeślimax-aspect-ratio
zgłaszam systemowi> 1, tryb portretowy nadal będzie uruchamiany przezmax-device-aspect-ratio
jeśli urządzenie z Androidem jest zorientowane w ten sposób.1/1
Część w zasadzie oznacza, że jeśli stosunek wynosi <= 1, to idzie do wykonywania portretów, w przeciwnym razie przechodzi do trybu poziomego.źródło
(max-aspect-ratio: 1/1)
. Wygląda na to, że potrzebujemy tylko tego kawałka, aby wykryć portret na pulpicie?Przejrzałem kilka powyższych odpowiedzi i żadna z nich nie zrobiła dokładnie tego, czego chciałem, czyli jak najdokładniej naśladować funkcjonalność iPhone'a. Oto, co teraz pracuje dla mnie w produkcji.
Działa poprzez przypisanie szerokości i wysokości okna urządzenia do atrybutu danych w celu późniejszego sprawdzenia. Ponieważ telefony nie zmieniają rozmiaru podczas podnoszenia klawiatury, tylko wysokość, sprawdzenie proporcji ORAZ szerokość w stosunku do oryginalnej szerokości może powiedzieć, czy klawiatura jest podniesiona. Nie znalazłem jeszcze przypadku użycia, który się nie powiódł, ale jestem pewien, że tak. Jeśli wszyscy znajdziecie, dajcie mi znać.
Używam niektórych globali, takich jak InitialRun i MobileOrientation, które są używane do przełączania js, używam również atrybutów danych html5 do przechowywania informacji w DOM do manipulacji css.
var InitialRun = true; // After the initial bootstrapping, this is set to false; var MobileOrientation = 'desktop'; function checkOrientation(winW, winH){ // winW and winH are the window's width and hieght, respectively if (InitialRun){ if (winW > winH){ $('body').attr('data-height',winW); $('body').attr('data-width',winH); MobileOrientation = 'landscape'; $('body').attr('data-orientation','landscape'); } else{ $('body').attr('data-height',winH); $('body').attr('data-width',winW); MobileOrientation = 'portrait'; $('body').attr('data-orientation','portrait'); } } else{ if (winW > winH && winW != $('body').data('width')){ MobileOrientation = 'landscape'; $('body').hdata('orientation','landscape'); //TODO:uncomment $('body, #wrapper').css({'height':"100%",'overflow-y':'hidden'}); //$('body').attr('data-orientation','portrait'); } else{ MobileOrientation = 'portrait'; $('body').attr('data-orientation','portrait'); $('body, #wrapper').css({'height':$('body').data('height'),'overflow-y':'auto'}); } } }
źródło
Użyłem prostej sztuczki, aby rozwiązać ten problem
@media (max-width: 896px) and (min-aspect-ratio: 13/9){/* Landscape content*/}
Odkryłem, że max-width: 896px może być używane na wszystkich urządzeniach mobilnych. wypróbuj to rozwiązanie działa!
źródło
Spójrz na ten link: http://www.alistapart.com/articles/a-pixel-identity-crisis/
Polegaj nie tylko na orientacji, ale także na
max-device-height
lubdevice-pixel-ratio
może pomóc. Zresztą nie testowałem tego, więc nie jestem pewien, czy to pomoże.źródło
Pomysł: usuń parametr portretu z zapytania o media i pozostaw go tylko z minimalną szerokością. Wykonaj swój normalny styl dla trybu pionowego w zapytaniu o media. Następnie utwórz kolejne zapytanie o media dla trybu poziomego z minimalną wysokością na tyle wysoką, aby przeglądarka nie używała tego zapytania, gdy pojawi się klawiatura. Musiałbyś poeksperymentować z tym, czym jest ta `` wystarczająco wysoka minimalna wysokość '', ale nie powinno to być zbyt trudne, ponieważ większość (jeśli nie wszystkie) trybów poziomych ma wysokość większą niż w przypadku wyskakiwania klawiatury. Dodatkowo możesz dodać „minimalną szerokość” do zapytania poziomego, która jest większa niż większość smartfonów w widoku pionowym (tj. Około ~ 400 pikseli), aby ograniczyć zakres zapytania.
Oto alternatywne (i wątłe) rozwiązanie: - Dodaj pusty dowolny element do swojego html, który będzie miał „display: none” w trybie innym niż portret. - Utwórz odbiornik jquery lub javascript do wprowadzania danych: fokus. Po kliknięciu wejścia, twój javascript sprawdza właściwość display dowolnego elementu. Jeśli zwróci „blok” lub cokolwiek ustawisz w trybie portretu, możesz nadpisać swój styl za pomocą JS do zapytań w trybie portretowym. I odwrotnie, miałbyś detektor input: blur, aby wyczyścić właściwości style.cssText elementów zakodowanych na stałe.
Sam eksperymentuję z tym teraz - wyślę kod tego, co działa, gdy dostanę coś solidnego i łatwego do zarządzania. (Moje pierwsze rozwiązanie wydaje się najbardziej rozsądne).
źródło
U mnie to działa niezawodnie. Używam http://detectmobilebrowsers.com/ dla rozszerzenia jQuery do wykrywania pliku $ .browser.mobile.
if ($.browser.mobile) { var newOrientationPortrait = true; //Set orientation based on height/width by default if ($(window).width() < $(window).height()) newOrientationPortrait = true; else newOrientationPortrait = false; //Overwrite orientation if mobile browser supports window.orientation if (window.orientation != null) if (window.orientation === 0) newOrientationPortrait = true; else newOrientationPortrait = false;
Oto mój kod służący do modyfikowania rzutni na podstawie orientacji. Ta funkcja jest wywoływana tylko w przypadku urządzeń mobilnych, nawet tabletów. To pozwala mi łatwo pisać CSS dla 400px i 800px (portret vs krajobraz).
_onOrientationChange = function() { if (_orientationPortrait) $("meta[name=viewport]").attr("content", "width=400,user-scalable=no"); else $("meta[name=viewport]").attr("content", "width=800"); }
Ze względu na charakter moich wymagań nie byłem w stanie tego zrobić w samych zapytaniach CSS Media, ponieważ sam DOM musiał się zmieniać w zależności od orientacji. Niestety w mojej pracy ludzie biznesu piszą wymagania dotyczące oprogramowania bez wcześniejszej konsultacji z programistami.
źródło
Z tym samym problemem spotkałem się na iPadzie.
to znaczy; gdy klawiatura ekranowa pojawia się w trybie pionowym, urządzenie jest wykrywane w orientacji poziomej, a na ekranie stosowane są style krajobrazu, co powoduje pomieszanie widoku.
Specyfikacja urządzenia
niestety u mnie to rozwiązanie nie zadziałało.
@media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */} @media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */}
Tak więc napisałem zapytanie o media, takie jak ten, dla mojego trybu portretowego.
@media only screen and (min-width : 300px) and (max-width : 768px) and (orientation : landscape) { /* portrait styles, when softkeyboard appears, goes here */ }
to znaczy; kiedy pojawia się miękka klawiatura, wysokość ekranu zmniejsza się, ale szerokość ekranu pozostaje do 768 pikseli, co spowodowało wykrycie ekranu w orientacji poziomej przez zapytanie o media. Stąd obejście podane powyżej.
źródło
Ponieważ iPhone 11 Pro Max Viewport ma 414 x 896 PX - powinno wystarczyć do uzyskania orientacji: pozioma z min-width: 500px
źródło