Der folgende Beitrag ist ein Gastbeitrag von Agop Shirinian. Agop stieß auf ein interessantes Szenario, bei dem er ein Element benötigte, das in einer Richtung scrollbar sein sollte, während der Überlauf in der anderen Richtung zugelassen werden sollte. Man könnte denken, dafür seien overflow-x und overflow-y da, aber so einfach ist es nicht. Ich überlasse Agop die Erklärung.
Sie haben die Aufgabe, ein scrollbares Menü mit Untermenüs zu erstellen, die beim Überfahren eines übergeordneten Menüpunkts herausspringen.
Einfach!
Erstellen Sie eine Liste für das Menü, fügen Sie einige verschachtelte Listen für die Untermenüs hinzu, positionieren Sie die verschachtelten Listen basierend auf ihren übergeordneten Listenelementen, fertig!
Siehe den Pen Scrollbares Menü mit herausspringenden Untermenüs (kaputt) von Agop (@agop) auf CodePen.
Moment, das stimmt nicht. Oh, natürlich haben wir overflow: auto verwendet – vielleicht, wenn wir overflow-x: visible verwenden, wird der horizontale Überlauf der Untermenüs sichtbar sein?
Siehe den Pen Scrollbares Menü mit herausspringenden Untermenüs (kaputt #2) von Agop (@agop) auf CodePen.
Was ist los? Warum haben wir immer noch Scrollbalken?
Das Problem
Wenn wir uns die W3C-Spezifikation ansehen, finden wir folgende Erklärung:
Die berechneten Werte von 'overflow-x' und 'overflow-y' sind dieselben wie ihre spezifizierten Werte, mit der Ausnahme, dass einige Kombinationen mit 'visible' nicht möglich sind: Wenn einer als 'visible' spezifiziert ist und der andere 'scroll' oder 'auto' ist, dann wird 'visible' auf 'auto' gesetzt.
Im Grunde wird das hier
overflow-x: visible;
overflow-y: auto;
Zu diesem hier
overflow-x: auto;
overflow-y: auto;
Wir können also keinen sichtbaren horizontalen Überlauf haben, wenn der vertikale Überlauf unsichtbar ist, und umgekehrt.
Und wenn wir keinen sichtbaren horizontalen Überlauf haben können, können wir unsere herausspringenden Untermenüs nicht haben!
Die Lösung
Interessanterweise, wenn wir position: relative von den Menüpunkten weglassen, erscheinen die Untermenüs trotzdem, positioniert basierend auf ihrem nächstgelegenen positionierten Vorfahren. In diesem Fall haben sie keinen positionierten Vorfahren, also sind sie relativ zum <body> positioniert
Siehe den Pen Scrollbares Menü mit herausspringenden Untermenüs (Schritt 1) von Agop (@agop) auf CodePen.
Im Grunde muss in einem Element mit overflow: hidden der nächstgelegene positionierte Vorfahre eines absolut positionierten Elements auch ein Vorfahre des Elements mit overflow: hidden sein, damit es außerhalb dessen Grenzen erscheint.
Wenn wir das wissen, können wir einen Wrapper um die Menüs hinzufügen, der als nächstgelegener positionierter Vorfahre für jedes Untermenü fungiert. Dann können wir die Untermenü-Wrapper mit ein wenig JavaScript positionieren, wann immer der Benutzer über einen Menüpunkt fährt.
Siehe den Pen Scrollbares Menü mit herausspringenden Untermenüs von Agop (@agop) auf CodePen.
Und das war's! Da weder die Menüs noch die Menüpunkte positioniert sind, können die Untermenüs aus dem versteckten/scrollbaren Überlauf herausspringen. Jetzt können wir so viele Ebenen verschachtelter Untermenüs haben, wie wir wollen, und wir werden keine unerwünschten Clipping-Effekte haben.
Fazit
Leider ist diese Methode, Elemente anzuzeigen, die sonst verborgen wären, sehr obskur.
Es wäre schön, wenn wir eine Clip-Tiefe angeben könnten, die steuert, welcher Vorfahre in der Hierarchie für das Clipping eines bestimmten Elements verantwortlich wäre.
./* Fair warning: not real code */
.submenu {
/* only an ancestor 2 levels up can clip this element */
clip-depth: 2;
}
Oder, noch besser, vielleicht könnten wir den Clipping-Vorfahren per CSS-Selektor angeben.
/* Fair warning: not real code */
.submenu {
/* only an ancestor that matches the .panel selector can clip this element */
clip-parent: .panel;
}
Danke für den Beitrag. Ich habe gerade vor ein paar Stunden an einem ähnlichen Problem gearbeitet. Ich werde das morgen ausprobieren, um eine Lösung zu finden.
Ich schwöre, die Spezifikationen für overflow-x/y gehören zu den idiotischsten überhaupt. Was ist der unheilige Grund, einfache Kombinationen wie visible/auto zu verbieten?
Erzählen Sie mir nur nicht, dass es daran liegt, dass es kompliziert ist…
Wahrscheinlich, weil die Spezifikation dem vorgegebenen Pfad folgt; sie folgt der ursprünglichen Implementierung von Microsoft in IE 5. Eine Änderung des Verhaltens würde die Legacy-Kompatibilität brechen.
Vielen Dank für die Mühe, es war gut geschrieben.
Der eigentliche „Fazit“ ist, dass wir im Jahr 2014 immer noch keine hochmodernen HTML/CSS-Techniken verwenden können, um Menüs zu erstellen, die 2006 auf dem neuesten Stand der Technik waren.
Wenn wir über 2006 hinausgehen, sieht dieses Beispiel auf einem kleinen Mobilgerät nicht gut aus. Ich erhalte zum Beispiel auf einem modernen iPhone flackernde/blitzende Artefakte.
Ich bin mir der üblichen Ausreden bewusst, Sie müssen sie nicht aufzählen. Dieses Beispiel sollte jedoch nicht ohne Einschränkungen in einer modernen Webanwendung landen ("eine Desktop-bevorzugte Technik, um..."). Wenn ich falsch liege, weisen Sie mich bitte auf eine Live-Produktionsseite, die diese Technik verwendet.
Wir können Mobile im Jahr 2014 nicht unter den Teppich kehren, und es ist nicht klar, wie man Ihren Ansatz auf einem Mobilgerät repariert. Wenn wir nicht über den Elefanten im Raum sprechen können, sollten wir ihn zumindest anerkennen :-)
Nochmal danke!
Sie haben Recht, ich würde diese Technik nicht auf einem Mobilgerät verwenden.
...oder irgendetwas anderes ohne einen anständig großen Bildschirm und einen dauerhaften Cursor, um darüber zu schweben ;)
Diese Technik unterstützt hauptsächlich Desktop-Anwendungen mit langen Menüs und Listen mit Popups, um zusätzliche Informationen zu diesen Elementen anzuzeigen.
standard-body, ich musste diese Technik tatsächlich verwenden, auf die ich für unsere interne Anwendung gestoßen bin.
Ja, das ist eine Desktop-orientierte App und für Mobilgeräte würde ich sie nicht verwenden, hauptsächlich weil die UI/UX für Mobilgeräte andere Anforderungen hat.
Ja, Position ist großartig, außer wenn sie es nicht ist. Kombinieren Sie das mit Sichtbarkeit, und Sie können sich in komplexen Interaktionen die Haare ausreißen.
Tolle Beiträge. Ich stoße heutzutage bei fast jedem Projekt darauf. Das Designmuster für mobile Menüs scheint seine Eigenheiten zu haben, die ausgebügelt werden müssen. Ich werde das bei meinem nächsten Projekt im Hinterkopf behalten, wenn ich zweifellos wieder darauf stoße.
Position: fixed; kann auch jedes Element mit overflow: hidden; verlassen, da es nur relativ zum Viewport positioniert wird und somit nur den Viewport-Überlauf akzeptiert.
Toller Beitrag. Aber overflow funktioniert bei Mobilgeräten nicht gut. Gibt es eine Lösung außer der Verwendung von Drittanbieter-Plugins?
Ich bin mir nicht ganz sicher, ob dieser Ansatz ohnehin ein gutes mobiles Erlebnis bieten würde, daher würden Sie wahrscheinlich kreative progressive Verbesserung betreiben wollen. Mit mehreren Ebenen von herausfliegenden Menüs scheint dies am besten für breitere Bildschirme geeignet zu sein.
Wow, das ist ein guter Beitrag!
Für diejenigen, die wie ich täglich mit IE7 zu kämpfen haben: Wissen Sie was? Es funktioniert sogar in IE7! (JSFiddle)
Vielen Dank für diesen Trick!! :)
Apropos Zufälle! Ich habe gestern genau an diesem Problem für eine mobile Sliding-Navigation gearbeitet, mit der ich beauftragt wurde! Das funktioniert auf allen Geräten perfekt.
Warum haben
.related-articles-title,.comments-title,.comments-titlemargin-bottom: -7px?es war blockiert.
http://codepen.io/davidyarham/pen/sHiGm
Etwas, das ich vor einiger Zeit gemacht habe, das aus einem overflow hidden ausbricht.
Fast vergessen – Sie müssen die Top-Tier-Elemente nicht in den Div-Wrapper einpacken, falls Sie sie inline oder anderweitig positionieren möchten :)
REINE CSS-Lösung!!!
Hallo,
Ich habe die gleiche Lösung mit reinem CSS erreicht – kein Bedarf für JS, um die Subs korrekt zu positionieren :)
Verwenden Sie Folgendes für Ihr CSS – und spielen Sie natürlich damit herum und ändern Sie die Attribute nach Ihren Bedürfnissen.
Prost, WUNDERBAR CODING!
Hallo HueMan, können Sie ein funktionierendes CodePen teilen?
Hover ist tot, Bruder.
Von John Pearse, an mich gesendet, nachdem die Kommentare geschlossen waren.
Ich verstehe, was John meint, wenn er das übergeordnete Menü scrollt und das untergeordnete Menü sich nicht mitbewegt. Die hier vorgestellte Lösung ist bereits eine JS-Lösung, und mehr JS könnte sie beheben (Scroll-Event-Handler, Untermenü neu positionieren).