Das Chrome-Team würde sich freuen, wenn im Web mehr solche Layouts verwendet würden. Wir sind jedoch der Meinung, dass es ein Fehler wäre, sie wie im letzten WebKit-Beitrag vorgeschlagen als Teil der CSS-Grid-Spezifikation zu implementieren. Außerdem sind wir der Meinung, dass im WebKit-Beitrag gegen eine Version von Masonry argumentiert wurde, die niemand vorgeschlagen hat.
In diesem Beitrag möchten wir daher erläutern, warum wir bei Chrome Bedenken hinsichtlich der Implementierung von „Mauerwerk“ als Teil der CSS-Grid-Layout-Spezifikation haben, und genau erklären, was der alternative Vorschlag ermöglicht. Kurzum:
- Das Chrome-Team möchte das Problem mit Masonry so schnell wie möglich beheben, da wir wissen, dass es von Entwicklern gewünscht wird.
- Das Hinzufügen von „Mauerwerk“ zur Rasterspezifikation ist aus anderen Gründen problematisch als der, ob Sie der Meinung sind, dass „Mauerwerk“ ein Raster ist oder nicht.
- Wenn du „Mosaik“ außerhalb der Rasterspezifikation definierst, kannst du trotzdem mehrere Titelgrößen für „Mosaik“ oder Eigenschaften wie Ausrichtung oder Lücken oder andere Funktionen verwenden, die im Rasterlayout verwendet werden.
Sollten Mauerwerke Teil des Rasters sein?
Das Chrome-Team ist der Meinung, dass der „Mauerwerksstil“ eine separate Layoutmethode sein sollte, die mit display: masonry
definiert wird (oder einem anderen Keyword, falls ein besserer Name gefunden wird). Später in diesem Beitrag sehen Sie einige Beispiele dafür, wie das in Code aussehen könnte.
Es gibt zwei ähnliche Gründe, warum wir der Meinung sind, dass das „Mosaik-Layout“ besser außerhalb des Rasterlayouts definiert ist: die potenziellen Probleme mit der Layoutleistung und die Tatsache, dass sowohl das „Mosaik-Layout“ als auch das Rasterlayout Funktionen haben, die in der einen Layoutmethode sinnvoll sind, in der anderen jedoch nicht.
Leistung
Grid und Masonry unterscheiden sich in Bezug auf die Größen- und Platzierungseinstellungen im Browser. Wenn ein Raster angelegt wird, werden alle Elemente vor dem Layout platziert und der Browser weiß genau, was sich in jedem Track befindet. So ist die komplexe intrinsische Größenanpassung möglich, die im Raster so nützlich ist. Bei der „Mauerwerks“-Anordnung werden die Elemente so platziert, wie sie dargestellt sind, und der Browser weiß nicht, wie viele sich in jedem Track befinden. Das ist kein Problem bei allen Tracks mit interner Größe oder bei allen Tracks mit fester Größe, aber bei einer Mischung aus festen und internen Tracks. Um das Problem zu umgehen, muss der Browser vor dem Layout einen Schritt ausführen, bei dem alle Elemente auf jede erdenkliche Weise angeordnet werden, um die Abmessungen zu erhalten. Bei einem großen Raster würde dies zu Problemen mit der Layoutleistung führen.
Wenn Sie also ein Masonry-Layout mit einer Track-Definition von grid-template-columns: 200px auto 200px
haben, was in einem Raster sehr häufig vorkommt, treten Probleme auf. Diese Probleme nehmen exponentiell zu, wenn Sie untergeordnete Raster hinzufügen.
Es wird argumentiert, dass die meisten Nutzer dieses Problem nicht haben werden. Wir wissen jedoch bereits, dass Nutzer sehr große Raster haben. Wir möchten keine Produkte auf den Markt bringen, die in ihrer Verwendung eingeschränkt sind, wenn es eine alternative Lösung gibt.
Was machen wir mit den Dingen, die bei den einzelnen Layoutmethoden keinen Sinn ergeben?
Als Flexbox und Grid Teil von CSS wurden, empfanden Entwickler sie oft als inkonsistent. Die Inkonsistenz war auf lang gehegte Annahmen über die Funktionsweise des Layouts zurückzuführen, die auf dem Blocklayout basierten. Im Laufe der Zeit haben Entwickler begonnen, sich mit Formatierungskontexten vertraut zu machen. Wenn wir in einen Raster- oder Flex-Formatierungskontext wechseln, verhalten sich einige Dinge anders. Sie wissen beispielsweise, dass bei Flexbox nicht alle Ausrichtungsmethoden verfügbar sind, da Flexbox eindimensional ist.
Wenn Sie das „Mosaik“ in ein Raster einbinden, wird diese klare Verknüpfung zwischen Formatierungskontext und Verfügbarkeit von Elementen wie Ausrichtungseigenschaften aufgehoben, die in der Box-Ausrichtungsspezifikation pro Formatierungskontext definiert sind.
Wenn wir uns dazu entschließen, das oben beschriebene Leistungsproblem anzugehen, indem wir gemischte Definitionen von internen und festen Tracks in der Masonry-Ansicht unzulässig machen, müssen Sie bedenken, dass ein sehr gängiges Muster für Rasterlayouts für Masonry nicht funktioniert.
Es gibt auch Muster, die in der Anordnung sinnvoll wären, z. B. grid-template-columns: repeat(auto-fill, max-content)
, da Sie keine Kreuzeinschränkungen haben, aber im Raster ungültig bleiben müssen. Im Folgenden finden Sie eine Liste von Properties, bei denen wir davon ausgehen, dass sie sich anders verhalten oder unterschiedliche gültige Werte haben.
grid-template-areas
: Bei der Verlegeart „Mauerwerk“ können Sie die erste Zeile nur in der Richtung angeben, die nicht der Verlegeart entspricht.grid-template
: Die Kurzfassung muss alle Unterschiede berücksichtigen.- Werte für die Größe von
grid-template-columns
undgrid-template-rows
aufgrund von Unterschieden bei den rechtlichen Werten erfassen grid-auto-flow
gilt nicht für „Mauerwerk“ undmasonry-auto-flow
nicht für „Raster“. Wenn Sie sie zusammenführen, kann es zu Problemen mit Elementen kommen, die aufgrund der verwendeten Layoutmethode ungültig sind.- Für das Raster gibt es vier Placement-Properties (
grid-column-start
usw.), für das „Mosaik“-Layout nur zwei. - Für das Raster können alle sechs
justify-*
- undalign-*
-Eigenschaften verwendet werden, für „Mauerwerk“ jedoch nur ein Teil davon, ähnlich wie bei Flexbox.
Außerdem müssen Sie angeben, was in allen neuen Fehlerfällen passiert, die durch Entwickler verursacht werden, die einen Wert verwenden, der für „grid-with-masonry“ oder „grid-without-masonry“ ungültig ist. Es ist beispielsweise zulässig, grid-template-columns: masonry
oder grid-template-rows: masonry
zu verwenden, aber nicht beides gleichzeitig. Was passiert, wenn ich beide gleichzeitig verwende?
Diese Details müssen so angegeben werden, dass alle Browser dasselbe tun.
Aus Sicht der Spezifikation wird das alles jetzt und in Zukunft kompliziert. Wir müssen dafür sorgen, dass alles für die Darstellung von Kacheln berücksichtigt wird und ob es funktioniert oder nicht. Auch für Entwickler ist das verwirrend. Warum sollten Sie sich merken müssen, dass trotz der Verwendung von display: grid
einige Dinge aufgrund der Verwendung von „Masonry“ nicht funktionieren?
Einen alternativen Vorschlag
Wie bereits erwähnt, möchte das Chrome-Team das „Mauerwerk“ außerhalb der Rasterspezifikation definieren. Das bedeutet nicht, dass es auf eine sehr einfache Layoutmethode mit identischen Spaltengrößen beschränkt wäre. Alle Demos im WebKit-Beitrag wären weiterhin möglich.
Klassisches Layout für Mauerwerk
Wenn die meisten Menschen an „Mauerwerk“ denken, denken sie an ein Layout mit mehreren Spalten gleicher Größe. Dies würde mit dem folgenden CSS definiert, für das weniger Codezeilen erforderlich sind als für die entsprechende kombinierte Version des Rasters.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1rem;
}
Raster-Track-Größe für unterschiedliche Spaltenbreiten verwenden
Abgesehen von dem bereits erwähnten Problem mit der gemischten Größe von intrinsischen und festen Tracks kannst du alle Spurgrößen verwenden, die du vom Raster kennst. Ein Beispiel hierfür ist das Beispiel aus dem WebKit-Blogpost, ein Muster aus sich wiederholenden schmalen und breiteren Spalten.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
gap: 1rem;
}
Zusätzliche Titelgröße für „Mauerwerk“
Es gibt zusätzliche Optionen zur Trackgröße, die im Raster nicht zulässig sind, da es sich um eine zweidimensionale Layoutmethode handelt. Diese wären in der „Mauerwerksansicht“ nützlich, aber es wäre verwirrend, wenn sie dann nicht im Raster funktionierten.
Automatische Ausfüllung von Tracks der Größe max-content
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, max-content);
gap: 1rem;
}
Automatisch erstellte Tracks mit einer Größe von auto
, die automatisch so skaliert werden, dass sie den größten Track aufnehmen können.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
gap: 1rem;
}
Inhalten erlauben, Spalten zu überspannen, und Elemente im „Mosaik-Layout“ platzieren
Es gibt keinen Grund, in einer separaten Masonry-Spezifikation keine Spalten zu überschreiten. Dazu kann das Attribut masonry-track
verwendet werden, das eine Kurzform für masonry-track-start
und masonry-track-end
ist. Da Sie in einem Masonry-Layout nur eine Dimension haben, um Elemente zu überspannen,
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
}
.span-2 {
masonry-track: span 2; /* spans two columns */
}
.placed {
masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}
Untermauerungen oder Unterraster mit Mauerwerkselementen
Dies könnte mit einer separaten Masonry-Spezifikation unterstützt werden, wobei wieder die Einschränkung gilt, dass eine Mischung aus Tracks mit inhärenter und fester Größe nicht zulässig ist. Wie genau das aussehen soll, muss definiert werden. Wir sehen keinen Grund, warum das nicht funktionieren sollte.
Fazit
Wir würden gerne eine Spezifikation entwickeln, die interoperabel bereitgestellt werden kann. Wir möchten dies jedoch auf eine Weise tun, die jetzt und in Zukunft gut funktioniert und auf die Entwickler sich verlassen können. Die einzige Möglichkeit, die beschriebenen Leistungsprobleme zu beheben, wäre, das zweite Problem zu verschlimmern, nämlich dass Teile des Rasters im Mauerwerk unzulässig sind. Wir sind der Meinung, dass das keine gute Lösung ist, vor allem, wenn es möglich ist, alle gewünschten Rasterfunktionen zu haben und gleichzeitig die unterschiedlichen Elemente klar voneinander zu trennen.
Wenn Sie Feedback haben, nehmen Sie an der Diskussion unter Issue 9041 teil.
Vielen Dank an Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick und Chris Harrelson für die Überprüfung dieses Beitrags und die Diskussionen, die zu ihm geführt haben.