Ich entwickle derzeit eine reaktionsfähige Website mit Twitter Bootstrap.
Die Site verfügt über ein Hintergrundbild im Vollbildmodus für Mobilgeräte / Tablets / Desktops. Diese Bilder drehen und verblassen jeweils mit zwei Divs.
Es ist fast perfekt, bis auf ein Problem. Bei Verwendung von iOS Safari, Android Browser oder Chrome unter Android springt der Hintergrund leicht, wenn ein Benutzer einen Bildlauf auf der Seite durchführt und die Adressleiste ausgeblendet wird.
Die Seite ist hier: http://lt2.daveclarke.me/
Besuchen Sie es auf einem mobilen Gerät und scrollen Sie nach unten. Das Bild sollte in der Größe geändert / verschoben werden.
Der Code, den ich für das Hintergrund-DIV verwende, lautet wie folgt:
#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;
}
Alle Vorschläge sind willkommen - das hat mir schon eine Weile den Kopf zerbrochen !!
position: fixed
.Antworten:
Dieses Problem wird dadurch verursacht, dass die URL-Balken verkleinern / aus dem Weg rutschen und die Größe der Divs # bg1 und # bg2 ändern, da sie 100% hoch und "fest" sind. Da das Hintergrundbild auf "Abdeckung" eingestellt ist, wird die Bildgröße / -position angepasst, wenn der enthaltende Bereich größer ist.
Basierend auf der Reaktionsfähigkeit der Site muss der Hintergrund skaliert werden. Ich unterhalte zwei mögliche Lösungen:
1) Stellen Sie die Höhe # bg1, # bg2 auf 100vh ein. Theoretisch ist dies eine elegante Lösung. IOS hat jedoch einen vh-Fehler ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ). Ich habe versucht, eine maximale Höhe zu verwenden, um das Problem zu verhindern, aber es blieb bestehen.
2) Die von Javascript bestimmte Größe des Ansichtsfensters wird von der URL-Leiste nicht beeinflusst. Daher kann Javascript verwendet werden, um eine statische Höhe für # bg1 und # bg2 basierend auf der Größe des Ansichtsfensters festzulegen. Dies ist nicht die beste Lösung, da es sich nicht um reines CSS handelt und beim Laden der Seite ein leichter Bildsprung auftritt. Es ist jedoch die einzige praktikable Lösung, die ich unter Berücksichtigung der "vh" -Fehler von iOS sehe (die in iOS 7 nicht behoben zu sein scheinen).
Nebenbei bemerkt, ich habe so viele Probleme mit diesen Größenänderungs-URL-Leisten in iOS und Android gesehen. Ich verstehe den Zweck, aber sie müssen wirklich über die seltsame Funktionalität und das Chaos nachdenken, das sie auf Websites verursachen. Die letzte Änderung ist, dass Sie die URL-Leiste beim Laden von Seiten unter iOS oder Chrome nicht mehr mithilfe von Bildlauftricks "ausblenden" können.
BEARBEITEN: Während das obige Skript perfekt funktioniert, um die Größenänderung des Hintergrunds zu verhindern, verursacht es eine merkliche Lücke, wenn Benutzer nach unten scrollen. Dies liegt daran, dass der Hintergrund auf 100% der Bildschirmhöhe abzüglich der URL-Leiste verkleinert wird. Wenn wir die Höhe um 60 Pixel erhöhen, wie es die Schweiz vorschlägt, verschwindet dieses Problem. Es bedeutet, dass wir die unteren 60 Pixel des Hintergrundbilds nicht sehen können, wenn die URL-Leiste vorhanden ist, aber es verhindert, dass Benutzer jemals eine Lücke sehen.
quelle
bg.height(jQuery(window).height() + 60);
was auf allen meinen Geräten wunderbar funktioniert! Danke :)vh
Einheiten und ist natürlich100vh
größer, wenn die Adressleiste ausgeblendet ist. Es ist dumm, dass dieser Sprung auftritt, nachdem das Scrollen aufgehört hat. Es sieht einfach fehlerhaft aus. Am Ende habe ich den Übergang auf der Höhe verwendet, um ihn absichtlich erscheinen zu lassen.body
in einen Wrapper<div>
verschob, der den gesamten Inhalt der Seite umhüllte. Keine springenden Hintergründe auf iOS oder Android!Ich stellte fest, dass Jasons Antwort für mich nicht ganz funktionierte und ich immer noch einen Sprung bekam. Das Javascript stellte sicher, dass oben auf der Seite keine Lücke vorhanden war, aber der Hintergrund sprang immer noch, wenn die Adressleiste verschwand / wieder auftauchte. Also habe ich mich neben dem Javascript-Fix auch
transition: height 999999s
für das div beworben . Dies erzeugt einen Übergang mit einer Dauer, die so lang ist, dass das Element praktisch eingefroren wird.quelle
vw
odervh
festlegen.Ich habe ein ähnliches Problem in einem Header unserer Website.
Dies führt zu einem nervösen Bildlauf auf Android Chrome, da der .header-Container neu skaliert wird, nachdem sich die URL-Leiste versteckt und der Finger vom Bildschirm entfernt wurde.
CSS-Lösung:
Durch Hinzufügen der folgenden zwei Zeilen wird verhindert, dass die URL-Leiste ausgeblendet wird und vertikales Scrollen weiterhin möglich ist:
quelle
Das Problem kann mit einer Medienabfrage und etwas Mathematik gelöst werden. Hier ist eine Lösung für eine Portait-Orientierung:
Da sich vh ändert, wenn die URL-Leiste verschwindet, müssen Sie die Höhe auf andere Weise bestimmen. Zum Glück ist die Breite des Ansichtsfensters konstant und mobile Geräte haben nur wenige unterschiedliche Seitenverhältnisse. Wenn Sie die Breite und das Seitenverhältnis bestimmen können, erhalten Sie mit ein wenig Mathematik die Höhe des Ansichtsfensters genau so, wie vh funktionieren sollte . Hier ist der Prozess
1) Erstellen Sie eine Reihe von Medienabfragen für Seitenverhältnisse, auf die Sie abzielen möchten.
Verwenden Sie das Geräte-Seitenverhältnis anstelle des Seitenverhältnisses, da letztere die Größe ändern, wenn die URL-Leiste verschwindet
Ich habe dem Geräte-Seitenverhältnis 'max' hinzugefügt, um alle Seitenverhältnisse zu bestimmen, die zufällig zwischen den beliebtesten folgen. Sie werden nicht so präzise sein, aber sie werden nur für eine Minderheit von Benutzern sein und werden immer noch ziemlich nah an der richtigen vh sein.
Denken Sie an die Medienabfrage mit horizontal / vertikal. Für Portait müssen Sie also die Zahlen umdrehen
2) Multiplizieren Sie für jede Medienabfrage den Prozentsatz der vertikalen Höhe, in dem sich das Element in vw befinden soll, mit der Umkehrung des Seitenverhältnisses.
3) Sie müssen die Höhe der URL-Leiste bestimmen und diese dann von der Höhe abziehen. Ich habe keine genauen Messungen gefunden, aber ich verwende 9% für mobile Geräte im Querformat und das scheint ziemlich gut zu funktionieren.
Dies ist keine sehr elegante Lösung, aber die anderen Optionen sind auch nicht sehr gut, wenn man bedenkt:
Wenn Ihre Website für den Benutzer fehlerhaft erscheint,
Elemente mit falscher Größe haben oder
Verwenden von Javascript für einige grundlegende Stile,
Der Nachteil ist, dass einige Geräte möglicherweise andere URL-Balkenhöhen oder Seitenverhältnisse aufweisen als die beliebtesten. Wenn ich diese Methode jedoch verwende, wenn nur eine kleine Anzahl von Geräten einige Pixel addiert / subtrahiert, scheint mir dies viel besser zu sein als jeder, der beim Wischen die Größe einer Website ändert.
Zur Vereinfachung habe ich auch ein SASS-Mixin erstellt:
quelle
@mixin vh-fix($vh: 100)
=>height: calc(100vw * (1.333 * $vh / 100) - 9%)
height: calc(100vw * (1.333 * #{$vh} / 100) - 9%)
-9%
.Alle Antworten hier verwenden die
window
Höhe, die von der URL-Leiste beeinflusst wird. Hat jeder diescreen
Größe vergessen ?Hier ist meine jQuery-Lösung:
Durch Hinzufügen des
.css()
Teils wird das zwangsläufig oben ausgerichtete absolut positionierte Element in unten ausgerichtet geändert, sodass überhaupt kein Sprung erfolgt. Ich nehme jedoch an, dass es keinen Grund gibt, dies nicht direkt zum normalen CSS hinzuzufügen.Wir brauchen den User Agent Sniffer, da die Bildschirmhöhe auf Desktops nicht hilfreich wäre.
Auch dies alles setzt voraus
#background
es sich um ein Element mit fester Position handelt, das das Fenster ausfüllt.Für die JavaScript-Puristen (Warnung - ungetestet):
BEARBEITEN: Entschuldigung, dass dies Ihr spezifisches Problem mit mehr als einem Hintergrund nicht direkt beantwortet. Dies ist jedoch eines der ersten Ergebnisse bei der Suche nach diesem Problem, dass feste Hintergründe auf Mobilgeräten springen.
quelle
Ich bin auch auf dieses Problem gestoßen, als ich versucht habe, einen Eingangsbildschirm zu erstellen, der das gesamte Ansichtsfenster abdeckt. Leider funktioniert die akzeptierte Antwort nicht mehr.
1) Elemente mit der Höhe eingestellt auf
100vh
dass sie bei jeder Änderung der Größe des Ansichtsfensters in der Größe geändert werden, einschließlich der Fälle, in denen dies durch eine (nicht) angezeigte URL-Leiste verursacht wird.2)
$(window).height()
gibt Werte zurück, die auch von der Größe der URL-Leiste beeinflusst werden.Eine Lösung besteht darin, das Element
transition: height 999999s
wie in der Antwort von AlexKempton vorgeschlagen "einzufrieren" . Der Nachteil besteht darin, dass dadurch die Anpassung an alle Änderungen der Ansichtsfenstergröße, einschließlich der durch die Bildschirmdrehung verursachten, effektiv deaktiviert wird.Meine Lösung besteht also darin, Änderungen am Ansichtsfenster manuell mit JavaScript zu verwalten. Dadurch kann ich die kleinen Änderungen, die wahrscheinlich durch die URL-Leiste verursacht werden, ignorieren und nur auf die großen reagieren.
EDIT: Ich benutze diese Technik tatsächlich zusammen mit
height: 100vh
. Die Seite wird von Anfang an korrekt gerendert, und dann wird das Javascript aktiviert und die Höhe manuell verwaltet. Auf diese Weise gibt es überhaupt kein Flackern, während die Seite geladen wird (oder sogar danach).quelle
height: 100vh
im anfänglichen CSS festzulegen, habe ich es festgelegtmin-height:100vh
und dann beim Ändern der Fenstergröße das berechnetmin-height
und es auf die Höhe des Ansichtsfensters eingestellt. Dies ist praktisch, wenn Ihre Website auf kleinen Bildschirmen angezeigt wird und der Inhalt zu groß ist, um in das Ansichtsfenster zu passen. Ein Debounce / Throttle-SetTimeout für das Größenänderungsereignis hilft bei einigen Browsern, die Leistung zu verbessern (Größenänderung wird häufig ausgelöst)min-height
stattdessen zu verwenden, aber dann stoße ich auf ein Problem, wenn ich den inneren Inhalt vertikal zentrieren musste. Irgendwie kann die vertikale Zentrierung schwierig werden, wenn das äußere Elementheight
eingestellt istauto
. Also habe ich mir eine feste Mindesthöhe ausgedacht, die ausreichen sollte, um alle möglichen Inhalte zu enthalten, und diese im anfänglichen CSS festgelegt. Damin-height
hat eine höhere Priorität alsheight
, funktioniert es ziemlich gut.display: table
und dann den internen Container aufdisplay: table-cell
mit gesetzt habevertical-align: middle
. Lief wie am Schnürchen.Die Lösung , die ich zur Zeit bin mit dem zu überprüfen ,
userAgent
auf ,$(document).ready
um zu sehen , ob es eine des säumigen Browser ist. Wenn dies der Fall ist, führen Sie die folgenden Schritte aus:$(window).resize
, nur aktualisiert die entsprechenden Höhenwerte , wenn die neue horizontale Bildfenster Dimension von seinem Anfangswert abweichtOptional können Sie auch testen, ob vertikale Größenänderungen nur zulässig sind, wenn sie über der Höhe der Adressleiste (n) liegen.
Oh, und die Adressleiste wirkt sich aus
$(window).height
. Siehe: Adressleiste des Mobile Webkit-Browsers (Chrome) ändert $ (Fenster) .height (); Hintergrundgröße festlegen: Cover jedes Mal neu skalieren, wenn JS "Fenster" Breite-Höhe vs "Bildschirm" Breite-Höhe?quelle
Ich habe eine wirklich einfache Lösung ohne die Verwendung von Javascript gefunden:
Dies verzögert lediglich die Bewegung, so dass es unglaublich langsam ist, dass es nicht wahrnehmbar ist.
quelle
100%
,100vh
. IE8 ist der einzige große Browser, der keine Übergänge unterstützt.Meine Lösung beinhaltete ein bisschen Javascript. Behalten Sie 100% oder 100vh auf dem div bei (dies verhindert, dass das div beim ersten Laden der Seite nicht angezeigt wird). Wenn die Seite geladen wird, nehmen Sie die Fensterhöhe und wenden Sie sie auf das betreffende Element an. Vermeidet den Sprung, da Sie jetzt eine statische Höhe auf Ihrem Div haben.
quelle
Ich habe eine Vanille-Javascript-Lösung für die Verwendung von VH-Einheiten erstellt. Die Verwendung von VH wird praktisch überall durch Adressleisten bewirkt, die das Scrollen minimieren. Um den Ruck zu beheben, der beim erneuten Zeichnen der Seite angezeigt wird, habe ich diesen Js hier, der alle Ihre Elemente mit VH-Einheiten erfasst (wenn Sie ihnen die Klasse geben
.vh-fix
) und ihnen inline Pixelhöhen gibt. Im Wesentlichen einfrieren in der Höhe, die wir wollen. Sie können dies bei Drehung oder bei Änderung der Größe des Ansichtsfensters tun, um reaktionsschnell zu bleiben.Dies hat alle meine Anwendungsfälle gelöst, hoffe es hilft.
quelle
Dies ist meine Lösung, um dieses Problem zu beheben. Ich habe Kommentare direkt zum Code hinzugefügt. Ich habe diese Lösung getestet und funktioniert einwandfrei. Ich hoffe, wir sind nützlich für alle, die das gleiche Problem haben.
quelle
Dies ist die beste (einfachste) Lösung vor allem, was ich versucht habe.
... und dies behält nicht die native Erfahrung der Adressleiste bei !
Sie können die Höhe beispielsweise mit CSS auf 100% und dann beim Laden des Dokuments mit Javascript auf 0,9 * der Fensterhöhe in px festlegen.
Zum Beispiel mit jQuery:
$("#element").css("height", 0.9*$(window).height());
)
Leider gibt es nichts, was mit reinem CSS: P funktioniert, aber seien Sie auch so klein
vh
und fehlerhaftvw
auf iPhones - verwenden Sie Prozentsätze.quelle
Ich setze mein width-Element mit Javascript. Nachdem ich das de vh eingestellt habe.
html
CSS
Javascript
Das funktioniert bei mir. Ich benutze kein jquery ect. weil ich möchte, dass es so schnell wie möglich geladen wird.
quelle
Es dauerte einige Stunden, um alle Details dieses Problems zu verstehen und die beste Implementierung herauszufinden. Es stellt sich heraus, dass ab April 2016 nur iOS Chrome dieses Problem hat. Ich habe Android Chrome und iOS Safari ausprobiert - beide waren ohne dieses Update in Ordnung. Das Update für iOS Chrome, das ich verwende, lautet also:
quelle
Einfache Antwort, wenn Ihr Hintergrund es zulässt, warum nicht die Hintergrundgröße einstellen: auf etwas, das nur die Gerätebreite mit Medienabfragen abdeckt und neben der: After-Position: fest verwendet; hier hacken .
IE: Hintergrundgröße: 901px; für irgendwelche Bildschirme <900px? Nicht perfekt oder reaktionsschnell, aber auf Mobilgeräten <480px hat es mir sehr gut gefallen, da ich einen abstrakten Hintergrund verwende.
quelle
Ich verwende diese Problemumgehung: Korrigieren Sie die Höhe von bg1 beim Laden der Seite durch:
Fügen Sie dann einen Listener für Größenänderungsereignisse an Window hinzu, der Folgendes ausführt: Wenn der Höhenunterschied nach der Größenänderung weniger als 60 Pixel (mehr als die Höhe des URL-Balkens) beträgt, tun Sie nichts, und wenn er größer als 60 Pixel ist, setzen Sie die Höhe von bg1 erneut auf die Höhe des übergeordneten Elements! vollständiger Code:
PS: Dieser Fehler ist so irritierend!
quelle
Ähnlich wie bei @AlexKempton Antwort. (konnte leider keinen Kommentar abgeben)
Ich habe lange Übergangsverzögerungen verwendet, um die Größenänderung des Elements zu verhindern.
z.B:
Der Nachteil dabei ist, dass verhindert wird, dass die Größe des Elements geändert wird, auch wenn sich das Gerät dreht. Sie können jedoch JS verwenden, um
orientationchange
die Höhe zu erkennen und zurückzusetzen, wenn dies ein Problem darstellt.quelle
Für diejenigen, die die tatsächliche innere Höhe und den vertikalen Bildlauf des Fensters hören möchten, während der mobile Chrome-Browser die URL-Leiste von "Gezeigt" in "Ausgeblendet" und umgekehrt umwandelt, ist die einzige Lösung, die ich gefunden habe, das Festlegen einer Intervallfunktion und Messen Sie die Diskrepanz von
window.innerHeight
mit dem vorherigen Wert.Dies führt diesen Code ein:
Ich hoffe, dass dies praktisch sein wird. Kennt jemand eine bessere Lösung?
quelle
Die Lösung, die ich bei einem ähnlichen Problem gefunden habe, bestand darin, die Höhe des Elements auf
window.innerHeight
jedes Mal einzustellen, wenn eintouchmove
Ereignis ausgelöst wurde.Dadurch überspannt das Element jederzeit genau 100% des verfügbaren Bildschirms, nicht mehr und nicht weniger. Auch während der Adressleiste versteckt oder angezeigt.
Trotzdem ist es schade, dass wir uns solche Patches einfallen lassen müssen, bei denen einfach
position: fixed
funktionieren sollte.quelle
Mit der Unterstützung von benutzerdefinierten CSS-Eigenschaften (Variablen) in iOS können Sie diese mit JS festlegen und nur unter iOS verwenden.
quelle
Meine Antwort ist, dass jeder, der hierher kommt (wie ich), eine Antwort auf einen Fehler findet, der durch die blanke / Browser-Oberfläche der versteckten Adresse verursacht wird.
Die ausgeblendete Adressleiste löst das Größenänderungsereignis aus. Anders als bei anderen Größenänderungsereignissen wie dem Umschalten in den Querformatmodus ändert dies jedoch nichts an der Breite des Fensters. Meine Lösung besteht also darin, sich in das Größenänderungsereignis einzuhängen und zu überprüfen, ob die Breite gleich ist.
quelle