Autoprefixer ist jetzt bei Version 9.3.1 angekommen und seit ich die ursprüngliche dreiteilige CSS Grid in IE-Reihe geschrieben habe, gab es eine Menge an Updates – das wichtigste Update davon ist das neue grid-areas System. Das ist hauptsächlich Bogdan Dolin zu verdanken, der wie verrückt daran gearbeitet hat, viele Autoprefixer-Probleme zu beheben. Die Grid-Übersetzungen von Autoprefixer waren schon vorher leistungsstark, aber jetzt sind sie weitaus leistungsstärker geworden!
Artikelserie
- Entlarvung gängiger IE Grid-Missverständnisse
- CSS Grid und der neue Autoprefixer
- Ein Auto-Placement-Grid mit Lücken vortäuschen
- Duplikate Bereichsnamen jetzt unterstützt! (Dieser Beitrag)
Wie Autoprefixer duplikate Bereichsnamen unterstützt
In Teil 2 der Reihe habe ich darauf hingewiesen, warum Autoprefixer keine duplizierten Bereichsnamen verarbeiten konnte, die über mehrere Selektoren hinweg verwendet wurden.
Zusammenfassend lässt sich sagen, dass dies das Beispiel ist, das ich in dem Artikel gegeben habe
.grid-alpha {
grid-template-areas: "delta echo";
}
.grid-beta {
grid-template-areas: "echo delta";
}
.grid-cell {
/* What column does .grid-cell go in? */
-ms-grid-column: ???;
grid-area: echo;
}
Wir dachten, da Autoprefixer keinen Zugriff auf das DOM hatte, gab es keine Möglichkeit zu wissen, zu welchem Grid die Grid-Zelle gehörte und somit in welche Spalte die Grid-Zelle gehen sollte.
Ich habe jedoch etwas erkannt. Grid-Zellen werden immer nur von ihrem direkten Elternelement beeinflusst (display: contents ignoriert). Das bedeutete, wenn die Grid-Zelle existiert, wird sie immer ein direktes Kind des Grid-Template-Elements sein. Das gab mir eine Idee, wie wir den Grid-Area-Namenskonflikt lösen können! 😁
.grid-alpha {
grid-template-areas: "delta echo";
}
.grid-beta {
/* Uh oh, duplicate area names! */
grid-template-areas: "echo delta";
}
.grid-cell {
/* We will use the first occurrence by default */
-ms-grid-column: 2;
grid-area: echo;
}
/*
We have detected a conflict!
Prefix the class with the parent selector.
*/
.grid-beta > .grid-cell {
/* NO MORE CONFLICT! */
-ms-grid-column: 1;
}
Das gesamte grid-areas System musste neu geschrieben werden, um dies zu erreichen, aber es war die Mühe absolut wert.
Die Funktionsweise dieses neuen Systems ist, dass .grid-cell standardmäßig die erste grid-template-areas Eigenschaft verwendet, auf die es trifft. Wenn es auf ein widersprüchliches Grid-Template stößt, wird eine neue Regel erstellt, die den Elternelementselektor vor den Kindselektor stellt, wie hier:
[full parent selector] > [direct child selector]
Das ist, was wir allein aus dem Betrachten des CSS und dem Wissen, wie CSS Grid funktioniert, wissen
- Eine Grid-Zelle muss ein direktes Nachfahre des übergeordneten Grid-Containers sein, damit CSS Grid funktioniert (vorausgesetzt,
display: contentswird nicht verwendet). grid-beta > .grid-cellfunktioniert nur auf.grid-cellElemente, die direkt in ein.grid-betaElement platziert wurden..grid-beta > .grid-cellhat keine Auswirkungen auf.grid-cellElemente, die direkt in.grid-alphaElemente platziert wurden..grid-beta > .grid-cellhat keine Auswirkungen auf.grid-cellElemente, die tief in.grid-betaElementen verschachtelt sind..grid-beta > .grid-cellüberschreibt die Stilistik der einsamen.grid-cellCSS-Regel sowohl aufgrund der Regelreihenfolge als auch der Spezifität.
Aus diesen Gründen kann Autoprefixer diese Konflikte ziemlich sicher lösen, ohne Zugriff auf das DOM zu haben.
Der letzte Punkt in der Liste kann ein wenig gefährlich sein. Er erhöht die Spezifität, was bedeutet, dass einige IE-Stile auf eine Weise überschrieben werden könnten, die sich von der Funktionsweise moderner Überschreibungen unterscheidet. Da die generierten Regeln nur IE-spezifische Grid-Stile enthalten und nur unter sehr spezifischen Umständen angewendet werden, ist es unwahrscheinlich, dass dies in 99,999% der Fälle ein Problem darstellt. Es gibt jedoch immer noch Potenzial für Ausnahmefälle.
Wenn Sie jemals die Notwendigkeit verspüren, die Spezifität des Grid-Zellenselektors zu erhöhen, hier ist, wie Sie vorgehen können.
Anstatt dies zu schreiben
.grid {
grid-template-areas: "area-name";
}
.grid-cell {
grid-area: area-name;
}
…schreiben wir die Regel so
.grid {
grid-template-areas: "area-name";
}
.grid > .grid-cell {
grid-area: area-name;
}
Autoprefixer behält den Selektor bei und gibt etwas wie das hier aus
.grid {
grid-template-areas: "area-name";
}
.grid > .grid-cell {
-ms-grid-column: 1;
-ms-grid-row: 1;
grid-area: area-name;
}
Die spannenden neuen Möglichkeiten!
Warum ist die Unterstützung für duplizierte Bereichsnamen so spannend?
Nun, zum einen war es einfach ärgerlich, wenn man in älteren Versionen von Autoprefixer versehentlich einen duplizierten Bereichsnamen verwendet hat. Es brach in IE und in älteren Versionen von Autoprefixer schlug es still und heimlich fehl.
Der Hauptgrund, warum es spannend ist, ist jedoch, dass es eine ganz neue Welt von IE-freundlichen CSS Grid-Möglichkeiten eröffnet!
Modifikator-Klassen verwenden, um ein Grid-Template anzupassen
Dies war der Anwendungsfall, der mich wirklich dazu brachte, Unterstützung für duplizierte Bereichsnamen in Autoprefixer zu bekommen. Denken Sie darüber nach. Sie haben eine typische Website mit einem Header, einem Footer, einem Hauptbereich und einer Seitenleiste auf beiden Seiten.
Siehe den Pen Basic website layout von Daniel Tonon (@daniel-tonon) auf CodePen.
Manchmal wollen wir beide Seitenleisten, manchmal eine Seitenleiste und manchmal keine Seitenleisten. Das war früher, als Autoprefixer keine duplizierten Bereichsnamen unterstützte, sehr schwer zu handhaben, da wir keine Bereichsnamen über mehrere Grid-Templates hinweg teilen konnten. Wir mussten etwas wie das tun, damit es funktioniert
/*
Before Duplicate area names were supported
- n = no side-bars
- f = first sidebar only
- s = second sidebar only
- fs = first and second sidebars
*/
.main-area {
display: grid;
grid-template:
"content-n" /
1fr;
}
.main-area.has-first-sidebar {
grid-template:
"first-sb-f content-f" /
300px 1fr;
}
.main-area.has-second-sidebar {
grid-template:
"content-s second-sb-s" /
1fr 300px;
}
.main-area.has-first-sidebar.has-second-sidebar {
grid-template:
"first-sb-fs content-fs second-sb-fs" /
200px 1fr 200px;
}
.main-area > .content {
grid-area: content-n; /* no side-bars */
}
.main-area > .sidebar.first {
grid-area: first-sb-f; /* first sidebar only */
}
.main-area > .sidebar.second {
grid-area: second-sb-s; /* second sidebar only */
}
.main-area.has-first-sidebar > .content {
grid-area: content-f; /* first sidebar only */
}
.main-area.has-second-sidebar > .content {
grid-area: content-s; /* second sidebar only */
}
.main-area.has-first-sidebar.has-second-sidebar > .content {
grid-area: content-fs; /* first and second sidebars */
}
.main-area.has-first-sidebar.has-second-sidebar > .sidebar.first {
grid-area: first-sb-fs; /* first and second sidebars */
}
.main-area.has-first-sidebar.has-second-sidebar > .sidebar.second {
grid-area: second-sb-fs; /* first and second sidebars */
}
Autoprefixer-Übersetzung
/*
Before Duplicate area names were supported
- n = no sidebars
- f = first sidebar only
- s = second sidebar only
- fs = first and second sidebars
*/
.main-area {
display: -ms-grid;
display: grid;
-ms-grid-rows: auto;
-ms-grid-columns: 1fr;
grid-template:
"content-n" /
1fr;
}
.main-area.has-first-sidebar {
-ms-grid-rows: auto;
-ms-grid-columns: 300px 1fr;
grid-template:
"first-sb-f content-f" /
300px 1fr;
}
.main-area.has-second-sidebar {
-ms-grid-rows: auto;
-ms-grid-columns: 1fr 300px;
grid-template:
"content-s second-sb-s" /
1fr 300px;
}
.main-area.has-first-sidebar.has-second-sidebar {
-ms-grid-rows: auto;
-ms-grid-columns: 200px 1fr 200px;
grid-template:
"first-sb-fs content-fs second-sb-fs" /
200px 1fr 200px;
}
.main-area > .content {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: content-n; /* no side-bars */
}
.main-area > .sidebar.first {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: first-sb-f; /* first sidebar only */
}
.main-area > .sidebar.second {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: second-sb-s; /* second sidebar only */
}
.main-area.has-first-sidebar > .content {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: content-f; /* first sidebar only */
}
.main-area.has-second-sidebar > .content {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: content-s; /* second sidebar only */
}
.main-area.has-first-sidebar.has-second-sidebar > .content {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: content-fs; /* first and second sidebars */
}
.main-area.has-first-sidebar.has-second-sidebar > .sidebar.first {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: first-sb-fs; /* first and second sidebars */
}
.main-area.has-first-sidebar.has-second-sidebar > .sidebar.second {
-ms-grid-row: 1;
-ms-grid-column: 3;
grid-area: second-sb-fs; /* first and second sidebars */
}
🤢 Oh ja, und vergessen Sie nicht die Media Queries! 🤮
Dieses Beispiel basierte auf tatsächlichem Code, den ich für ein echtes Projekt schreiben musste… also ja, ich wollte wirklich Unterstützung für duplizierte Bereichsnamen in Autoprefixer bekommen.
Jetzt, da wir die Unterstützung für duplizierte Bereichsnamen haben, können wir diesen Code zu etwas viel Schönem vereinfachen 😊
/*
Duplicate area names now supported!
This code will work perfectly in IE with Autoprefixer 9.3.1
*/
.main-area {
display: grid;
grid-template:
"content" /
1fr;
}
.main-area.has-first-sidebar {
grid-template:
"first-sb content" /
300px 1fr;
}
.main-area.has-second-sidebar {
grid-template:
"content second-sb" /
1fr 300px;
}
.main-area.has-first-sidebar.has-second-sidebar {
grid-template:
"first-sb content second-sb" /
200px 1fr 200px;
}
.content {
grid-area: content;
}
.sidebar.first {
grid-area: first-sb;
}
.sidebar.second {
grid-area: second-sb;
}
Autoprefixer-Übersetzung
.main-area {
display: -ms-grid;
display: grid;
-ms-grid-rows: auto;
-ms-grid-columns: 1fr;
grid-template:
"content" /
1fr;
}
.main-area.has-first-sidebar {
-ms-grid-rows: auto;
-ms-grid-columns: 300px 1fr;
grid-template:
"first-sb content" /
300px 1fr;
}
.main-area.has-second-sidebar {
-ms-grid-rows: auto;
-ms-grid-columns: 1fr 300px;
grid-template:
"content second-sb" /
1fr 300px;
}
.main-area.has-first-sidebar.has-second-sidebar {
-ms-grid-rows: auto;
-ms-grid-columns: 200px 1fr 200px;
grid-template:
"first-sb content second-sb" /
200px 1fr 200px;
}
.content {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: content;
}
.main-area.has-first-sidebar > .content {
-ms-grid-row: 1;
-ms-grid-column: 2;
}
.main-area.has-second-sidebar > .content {
-ms-grid-row: 1;
-ms-grid-column: 1;
}
.main-area.has-first-sidebar.has-second-sidebar > .content {
-ms-grid-row: 1;
-ms-grid-column: 2;
}
.sidebar.first {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: first-sb;
}
.main-area.has-first-sidebar.has-second-sidebar > .sidebar.first {
-ms-grid-row: 1;
-ms-grid-column: 1;
}
.sidebar.second {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: second-sb;
}
.main-area.has-first-sidebar.has-second-sidebar > .sidebar.second {
-ms-grid-row: 1;
-ms-grid-column: 3;
}
Mit diesem CSS können wir jetzt die Klassen has-first-sidebar und has-second-sidebar auf dem Grid-Element verwenden, um zu modifizieren, welches Grid-Template der Browser verwendet. Wir müssen uns nicht mehr darum kümmern, genau zu definieren, wo die Grid-Zellen platziert werden.
Komponenten wiederverwendbare Bereichsnamen zuweisen
Eine der Einschränkungen, die sich aus der Notwendigkeit ergab, eindeutige Bereichsnamen zu verwenden, war, dass Komponenten keinen einzelnen, konsistenten, wiederverwendbaren Bereichsnamen erhalten konnten. Wir waren gezwungen, für jedes Grid eindeutige Bereichsnamen zu finden.
Da Autoprefixer nun Unterstützung für duplizierte Bereichsnamen bietet, ist diese Einschränkung beseitigt. Wir können jeder Komponente einen einzelnen Bereichsnamen geben, der auf ihrem Komponentennamen basiert. Wir können dann diesen einen Bereichsnamen referenzieren, wann immer wir diese Komponente in ein Grid-Layout einfügen möchten.
/* header.scss */
.header {
grid-area: header;
}
/* nav.scss */
.nav {
grid-area: nav;
}
/* sidebar.scss */
.sidebar {
grid-area: sidebar;
}
/* content.scss */
.content {
grid-area: content;
}
/* subscribe.scss */
.subscribe {
grid-area: subscribe;
}
/* footer.scss */
.footer {
grid-area: footer;
}
/* layout.scss */
.single-sidebar-layout {
display: grid;
grid-template-areas:
"header header"
"nav content"
"subscribe content"
"footer footer";
}
.double-sidebar-layout {
display: grid;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav subscribe sidebar"
"footer footer footer";
}
Autoprefixer-Übersetzung
/* header.scss */
.header {
-ms-grid-row: 1;
-ms-grid-column: 1;
-ms-grid-column-span: 2;
grid-area: header;
}
.double-sidebar-layout > .header {
-ms-grid-row: 1;
-ms-grid-column: 1;
-ms-grid-column-span: 3;
}
/* nav.scss */
.nav {
-ms-grid-row: 2;
-ms-grid-column: 1;
grid-area: nav;
}
.double-sidebar-layout > .nav {
-ms-grid-row: 2;
-ms-grid-row-span: 2;
-ms-grid-column: 1;
}
/* sidebar.scss */
.sidebar {
-ms-grid-row: 2;
-ms-grid-row-span: 2;
-ms-grid-column: 3;
grid-area: sidebar;
}
/* content.scss */
.content {
-ms-grid-row: 2;
-ms-grid-row-span: 2;
-ms-grid-column: 2;
grid-area: content;
}
.double-sidebar-layout > .content {
-ms-grid-row: 2;
-ms-grid-column: 2;
}
/* subscribe.scss */
.subscribe {
-ms-grid-row: 3;
-ms-grid-column: 1;
grid-area: subscribe;
}
.double-sidebar-layout > .subscribe {
-ms-grid-row: 3;
-ms-grid-column: 2;
}
/* footer.scss */
.footer {
-ms-grid-row: 4;
-ms-grid-column: 1;
-ms-grid-column-span: 2;
grid-area: footer;
}
.double-sidebar-layout > .footer {
-ms-grid-row: 4;
-ms-grid-column: 1;
-ms-grid-column-span: 3;
}
/* layout.scss */
.single-sidebar-layout {
display: -ms-grid;
display: grid;
grid-template-areas:
"header header"
"nav content"
"subscribe content"
"footer footer";
}
.double-sidebar-layout {
display: -ms-grid;
display: grid;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav subscribe sidebar"
"footer footer footer";
}
Hier ist, was wir haben. Beachten Sie, dass dies in IE betrachtet werden sollte.
Siehe den Pen component-area-name technique von Daniel Tonon (@daniel-tonon) auf CodePen.
Einschränkung duplizierter Bereichsnamen
Es gibt einen ziemlich häufigen Anwendungsfall, den Autoprefixer derzeit noch nicht bewältigen kann. Wenn der übergeordnete Selektor der Grid-Zelle nicht mit dem Grid-Template-Selektor übereinstimmt, versucht er, einen duplizierten Bereichsnamen aufzulösen
.grand-parent .mother {
grid-template-areas: "child";
}
.grand-parent .father {
grid-template-areas: "child child";
}
/* This will work */
.grand-parent .mother .child {
grid-area: child;
}
/*
This does not work because:
- ".uncle" != ".grand-parent .mother"
- ".uncle" != ".grand-parent .father"
- "child" is a duplicate area name
*/
.uncle .child {
grid-area: child;
}
Hier ist ein realistischeres Szenario der aktuellen Einschränkung im Algorithmus von Autoprefixer
.component .grid {
display: grid;
grid-template-areas: "one two";
grid-template-columns: 1fr 1fr;
}
/* This rule triggers duplicate area name conflicts. */
.component.modifier .grid {
grid-template-areas: "one ... two";
grid-template-columns: 1fr 1fr 1fr;
}
/*
This does not work because:
- ".component" != ".component .grid"
- ".component" != ".component.modifier .grid"
- area names "one" and "two" both have duplicate area name conflicts
*/
.component .cell-one {
grid-area: one;
}
.component .cell-two {
grid-area: two;
}
Derzeit gibt es eigentlich nur drei Möglichkeiten, diesen Konflikt zu lösen.
Option 1: Entfernen Sie den übergeordneten Selektor aus Kindelementen
Ohne Schutzmaßnahmen für die Beschränkung von Stilen auf eine bestimmte Komponente ist dies bei weitem die gefährlichste Methode zur Lösung des Problems. Ich empfehle sie nicht.
.component .grid {
display: grid;
grid-template-areas: "one two";
grid-template-columns: 1fr 1fr;
}
.component.modifier .grid {
grid-template-areas: "one ... two";
grid-template-columns: 1fr 1fr 1fr;
}
.cell-one {
grid-area: one;
}
.cell-two {
grid-area: two;
}
Autoprefixer-Übersetzung
.component .grid {
display: -ms-grid;
display: grid;
grid-template-areas: "one two";
-ms-grid-columns: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.component.modifier .grid {
grid-template-areas: "one ... two";
-ms-grid-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}
.cell-one {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: one;
}
.component.modifier .grid > .cell-one {
-ms-grid-row: 1;
-ms-grid-column: 1;
}
.cell-two {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: two;
}
.component.modifier .grid > .cell-two {
-ms-grid-row: 1;
-ms-grid-column: 3;
}
Option 2: Zurück zu eindeutigen Bereichsnamen wechseln
Diese Lösung ist ziemlich hässlich, aber wenn Sie keine Kontrolle über das HTML haben, ist dies wahrscheinlich der beste Weg, das Problem zu lösen.
.component .grid {
display: grid;
grid-template-areas: "one two";
grid-template-columns: 1fr 1fr;
}
.component .cell-one {
grid-area: one;
}
.component .cell-two {
grid-area: two;
}
.component.modifier .grid {
grid-template-areas: "modifier_one ... modifier_two";
grid-template-columns: 1fr 1fr 1fr;
}
.component.modifier .cell-one {
grid-area: modifier_one;
}
.component.modifier .cell-two {
grid-area: modifier_two;
}
Autoprefixer-Übersetzung
.component .grid {
display: -ms-grid;
display: grid;
grid-template-areas: "one two";
-ms-grid-columns: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.component .cell-one {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: one;
}
.component .cell-two {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: two;
}
.component.modifier .grid {
grid-template-areas: "modifier_one ... modifier_two";
-ms-grid-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}
.component.modifier .cell-one {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: modifier_one;
}
.component.modifier .cell-two {
-ms-grid-row: 1;
-ms-grid-column: 3;
grid-area: modifier_two;
}
Option 3: Verwenden Sie eine BEM-artige Namenskonvention
Ja, wenn Sie die BEM-Namenskonvention (oder etwas Ähnliches) verwenden, wird dies praktisch nie ein Problem für Sie sein. Dies ist bei weitem der bevorzugte Weg, um das Problem anzugehen, wenn es eine Option ist.
.component__grid {
display: grid;
grid-template-areas: "one two";
grid-template-columns: 1fr 1fr;
}
.component__grid--modifier {
grid-template-areas: "one ... two";
grid-template-columns: 1fr 1fr 1fr;
}
.component__cell-one {
grid-area: one;
}
.component__cell-two {
grid-area: two;
}
Autoprefixer-Übersetzung
.component__grid {
display: -ms-grid;
display: grid;
grid-template-areas: "one two";
-ms-grid-columns: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.component__grid--modifier {
grid-template-areas: "one ... two";
-ms-grid-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}
.component__cell-one {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: one;
}
.component__grid--modifier > .component__cell-one {
-ms-grid-row: 1;
-ms-grid-column: 1;
}
.component__cell-two {
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: two;
}
.component__grid--modifier > .component__cell-two {
-ms-grid-row: 1;
-ms-grid-column: 3;
}
Ich habe einige Probleme mit BEM, aber mit ein paar Anpassungen der Syntax kann es ein wirklich großartiger Weg sein, die CSS-Spezifität und das Scoping zu kontrollieren.
Andere Autoprefixer-Updates
Während ich hier bin, gebe ich Ihnen ein Update zu ein paar anderen Entwicklungen, die in Autoprefixer stattgefunden haben, seit ich die ursprüngliche CSS Grid in IE-Reihe geschrieben habe.
Bevor wir eintauchen, hier ist, wie Sie Dinge in CodePen einrichten, falls Sie mit Ihren eigenen Experimenten Schritt halten möchten.
Autoprefixer Grid-Übersetzungen in CodePen verwenden
CodePen hat bereits auf Version 9.3.1 von Autoprefixer aktualisiert. Sie können jetzt ganz einfach IE-freundliche CSS Grid-Stile in Ihre Pens integrieren. Stellen Sie zunächst sicher, dass Autoprefixer in den CodePen-Einstellungen aktiviert ist (Settings > CSS > [Vendor Prefixing] > Autoprefixer).

Fügen Sie dann den brandneuen Kommentar /* autoprefixer grid: on */ am Anfang des CSS-Panels hinzu. Ich werde später auf dieses großartige neue Feature näher eingehen.

Update: CodePen unterstützt jetzt auch den neueren Kommentar /* autoprefixer grid: autoplace */. Das bedeutet, dass Sie jetzt CodePen verwenden können, um mit der Autoplacement-Funktionalität von Autoprefixer zu experimentieren. 😃
Sie können jetzt modernen, IE-freundlichen CSS Grid-Code schreiben und CodePen fügt automatisch alle IE-Präfixe hinzu.


Um Ihre Pens tatsächlich in IE zu testen, müssen Sie den Pen jedoch im „Debug Mode“ anzeigen (Change View > Debug Mode). Der Pen muss gespeichert werden, bevor Sie Zugriff auf diese Ansicht haben.

Wenn Sie ein Tool ausprobieren möchten, das Ihnen die Autoprefixer-Ausgabe in Echtzeit anzeigt, probieren Sie das Online-Tool genau dafür aus. Geben Sie CSS auf der linken Seite ein. Es gibt das übersetzte CSS von Autoprefixer rechts aus, während Sie tippen.

Neue Autoprefixer-Kontrollkommentare
Wir haben nicht immer die Möglichkeit, die Autoprefixer-Konfigurationseinstellungen zu ändern. Wenn Sie jemals versucht haben, in der Vergangenheit einige IE-freundliche CSS Grid-Experimente in CodePen durchzuführen, wissen Sie, wie schmerzhaft es ist, keinen direkten Zugriff auf die Autoprefixer-Einstellungen zu haben. Es gibt auch einige Frameworks wie Create React App und Angular, die es Benutzern nicht erlauben, die Autoprefixer-Einstellungen zu ändern. Es gab auch eine gewisse Hürde, die einige Benutzer daran hinderte, Grid zu verwenden, da sie unsicher waren, wie sie Grid-Übersetzungen aktivieren sollten.
Diese Einschränkung verursachte bei vielen Benutzern Probleme, aber dann reichte Andrey Alexandrov einen Pull Request ein, der einen neuen Kontrollkommentar einführte. Dieser neue Kontrollkommentar gab Benutzern die Möglichkeit, Grid-Übersetzungen einfach innerhalb der CSS-Datei ein- und auszuschalten. Das war weitaus einfacher als die Konfigurationseinstellungen. Es war auch für alle Benutzer zugänglich, unabhängig davon, wie sie ihr CSS kompilieren.
Das Hinzufügen von /* autoprefixer grid: autoplace */ aktiviert Grid-Übersetzungen für den gesamten Block, während /* autoprefixer grid: off */ Grid-Übersetzungen für diesen Block deaktiviert. Nur der erste Grid-Kontrollkommentar in einem Block wird angewendet.
/* Globally enable grid prefixes */
/* autoprefixer grid: autoplace */
.grid {
display: grid;
}
.non-ie .grid {
/* Turn off grid prefixes but only for this block */
/* autoprefixer grid: off */
display: grid;
/*
Grid control comments affect the whole block.
This control comment is ignored
*/
/* autoprefixer grid: autoplace */
grid-column: 1;
}
Der obige Code übersetzt sich in Folgendes (ich habe die Erklärkommentare herausgefiltert)
/* autoprefixer grid: autoplace */
.grid {
display: -ms-grid;
display: grid;
}
.non-ie .grid {
/* autoprefixer grid: off */
display: grid;
/* autoprefixer grid: autoplace */
grid-column: 1;
}
@supports können Grid-Übersetzungen deaktivieren
Die neuen Kontrollkommentare sind nicht die einzige Möglichkeit, Autoprefixer selektiv daran zu hindern, Grid-Übersetzungscode auszugeben.
Autoprefixer wird implizites Grid-Autoplacement nie unterstützen können. Wenn Sie eine @supports-Anweisung verwenden, die nach etwas wie grid-auto-rows: 0 sucht, gibt Autoprefixer keinen Grid-Code innerhalb dieser Anweisung aus.
.prefixed .grid {
display: -ms-grid;
display: grid;
}
/* Checking grid-auto-* support prevents prefixes */
@supports (grid-auto-rows: 0) {
.modern .grid {
display: grid;
}
}
/* Checking basic grid support still outputs prefixes */
@supports (display: grid) {
.still-prefixed .grid {
display: -ms-grid;
display: grid;
}
}
Um IE zu unterstützen, kann Autoprefixer manchmal etwa 50 Zeilen zusätzlichen CSS generieren. Wenn Sie Grid-Code innerhalb einer @supports-Anweisung schreiben, möchten Sie, dass die IE-Übersetzungen deaktiviert sind, um das Gewicht Ihres CSS zu reduzieren. Wenn Sie @supports (grid-auto-rows: 0) nicht verwenden möchten, können Sie stattdessen einen Kontrollkommentar innerhalb der @supports-Anweisung verwenden.
@supports (display: grid) {
.prefixed .grid {
display: -ms-grid;
display: grid;
}
}
@supports (display: grid) {
/* autoprefixer grid: off */
.modern .grid {
display: grid;
}
}
Autoprefixer erbt jetzt Grid-Gaps
Im ursprünglichen Artikel habe ich gesagt, dass Autoprefixer keine grid-gap-Werte erben konnte. In Version 9.1.1 konnten grid-gap-Werte über Media Queries weitergegeben werden. In Version 9.3.1 sind sie auch über spezifischere Selektoren erblich geworden.
.grid {
display: grid;
grid-gap: 20px; /* grid-gap is stated here */
grid-template:
"one two" /
1fr 1fr;
}
@media (max-width: 600px) {
.grid {
/* grid-gap is now inhereited here */
grid-template:
"one"
"two" /
1fr;
}
}
.grid.modifier {
/* grid-gap is now inhereited here as well */
grid-template:
"one"
"two" /
1fr;
}
.one { grid-area: one; }
.two { grid-area: two; }
Autoprefixer-Übersetzung
.grid {
display: -ms-grid;
display: grid;
grid-gap: 20px; /* grid-gap is stated here */
-ms-grid-rows: auto;
-ms-grid-columns: 1fr 20px 1fr;
grid-template:
"one two" /
1fr 1fr;
}
@media (max-width: 600px) {
.grid {
/* grid-gap is now inhereited here */
-ms-grid-rows: auto 20px auto;
-ms-grid-columns: 1fr;
grid-template:
"one"
"two" /
1fr;
}
}
.grid.modifier {
/* grid-gap is now inherited here as well */
-ms-grid-rows: auto 20px auto;
-ms-grid-columns: 1fr;
grid-template:
"one"
"two" /
1fr;
}
.one {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: one;
}
.grid.modifier > .one {
-ms-grid-row: 1;
-ms-grid-column: 1;
}
.two {
-ms-grid-row: 1;
-ms-grid-column: 3;
grid-area: two;
}
.grid.modifier > .two {
-ms-grid-row: 3;
-ms-grid-column: 1;
}
@media (max-width: 600px) {
.one {
-ms-grid-row: 1;
-ms-grid-column: 1;
}
.two {
-ms-grid-row: 3;
-ms-grid-column: 1;
}
}
grid-template: span X; funktioniert jetzt
In Teil 2 dieser Reihe habe ich erwähnt, dass die folgende Syntax nicht funktioniert
.grid-cell {
grid-column: span 2;
}
Dies wurde in Version 9.1.1 behoben. Es wird nun in Folgendes übersetzt
.grid-cell {
-ms-grid-column-span: 2;
grid-column: span 2;
}
Neue Warnung für die Mischung von manueller und bereichsbasierter Platzierung
Ein Benutzer beschwerte sich, dass Autoprefixer Grid-Bereiche nicht korrekt handhabte. Nach weiterer Untersuchung stellten wir fest, dass er sowohl eine grid-area als auch eine grid-column Einstellung innerhalb derselben CSS-Regel anwendete.
.grid {
display: grid;
grid-template-areas: "a b";
}
/* This doesn't work very well */
.grid-cell {
grid-column: 2;
grid-area: a;
}
Verwenden Sie entweder nur grid-area oder verwenden Sie grid-column & grid-row. Verwenden Sie niemals beides gleichzeitig.
Wenn Sie neugierig sind, hier ist, was Autoprefixer für den obigen Code ausgibt
.grid {
display: -ms-grid;
display: grid;
grid-template-areas: "a b";
}
/* This doesn't work very well */
.grid-cell {
-ms-grid-row: 1;
-ms-grid-column: 1;
-ms-grid-column: 2;
grid-column: 2;
grid-area: a;
}
Es gibt eine Ausnahme hierzu. Möglicherweise müssen sich Grid-Zellen in Ihrem Design mit anderen Grid-Zellen überschneiden. Sie möchten grid-template-areas für die Platzierung Ihrer Grid-Zellen verwenden, da Autoprefixer die allgemeine Zellplatzierung erheblich vereinfacht. Sie können jedoch keine Zellüberschneidungen mit grid-template-areas erstellen. Um diese Überschneidung zu erstellen, können Sie grid-[column/row]-end: span X; nach der grid-area Deklaration verwenden, um die Überschneidung zu erzwingen.
.grid {
display: grid;
grid-template-areas:
"a . ."
"a b b"
"a . .";
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
.grid-cell-a {
grid-area: a;
/* place cell span after the grid-area to force an overlap */
grid-column-end: span 2;
}
Siehe den Pen column-span + grid-area experiment von Daniel Tonon (@daniel-tonon) auf CodePen.
Wenn Sie jedoch Grid-Abstände in Ihrem Grid deklariert haben, müssen Sie die Spalten-/Zeilen-Span-Präfixe manuell schreiben und dabei die zusätzlichen Spalten/Zeilen berücksichtigen, die von Autoprefixer generiert werden (IE unterstützt grid-gap nicht). Dafür gibt es ein Problem auf GitHub.
.grid {
display: grid;
grid-template-areas:
"a . ."
"a b c"
"a . .";
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 10px;
}
.grid-cell-a {
grid-area: a;
/* IE column span added manually */
-ms-grid-column-span: 3; /* IE spans 2 columns + the gap */
grid-column-end: span 2; /* Modern browsers only span 2 columns */
}
Siehe den Pen column-span + grid-area experiment 2 von Daniel Tonon (@daniel-tonon) auf CodePen.
Diese Technik erzeugt derzeit eine Warnmeldung in Autoprefixer, die nicht einfach ausgeblendet werden kann. Ein Problem dafür ist auf GitHub.
Neue Warnung bei Verwendung von [align/justify/place]-[content/items]
Leider kann IE Grid-Zellen nicht vom übergeordneten Container aus ausrichten. Die einzige Möglichkeit, Grid-Zellen in IE auszurichten, ist die Verwendung der Eigenschaften -ms-grid-row-align und -ms-grid-column-align. Diese werden in der modernen Grid-Syntax zu align-self und justify-self.
Die folgenden Eigenschaften lösen eine Warnung in Autoprefixer aus, wenn sie in Verbindung mit einer CSS Grid-Eigenschaft verwendet werden
align-itemsalign-contentjustify-itemsjustify-contentplace-itemsplace-content
Die Eigenschaften align-content, justify-content und place-content sind in IE praktisch unmöglich zu replizieren. Die Eigenschaften align-items, justify-items und place-items sind hingegen recht einfach mit ihren self-Entsprechungen auf den Kindelementen zu replizieren (place-self-Unterstützung wurde in 9.3.0 hinzugefügt).
/* [align/justify/place]-items is *NOT* IE friendly */
.align-justify-items {
display: grid;
align-items: start;
justify-items: end;
}
.place-items {
display: grid;
place-items: start end;
}
/*[align/justify/place]-self *IS* IE friendly */
.align-justify-grid { display: grid; }
.align-justify-grid > * {
align-self: start;
justify-self: end;
}
.place-grid { display: grid; }
.place-grid > * {
place-self: start end;
}
Autoprefixer-Übersetzung
/* [align/justify/place]-items is *NOT* IE friendly */
.align-justify-items {
display: -ms-grid;
display: grid;
align-items: start;
justify-items: end;
}
.place-items {
display: -ms-grid;
display: grid;
place-items: start end;
}
/*[align/justify/place]-self *IS* IE friendly */
.align-justify-grid { display: -ms-grid; display: grid; }
.align-justify-grid > * {
-ms-grid-row-align: start;
align-self: start;
-ms-grid-column-align: end;
justify-self: end;
}
.place-grid { display: -ms-grid; display: grid; }
.place-grid > * {
-ms-grid-row-align: start;
-ms-grid-column-align: end;
place-self: start end;
}
.grid { [align/justify/place]-items } und .grid > * { [align/justify/place]-self } sind im Allgemeinen recht austauschbar. Diese Ersetzung funktioniert nicht immer, aber in den meisten Fällen verhalten sich die beiden Methoden tendenziell ähnlich.
Unten sehen Sie einen Pen, der den Unterschied zwischen der IE-freundlichen und der IE-unfreundlichen Ausrichtungsmethode zeigt. In modernen Browsern sehen sie identisch aus, aber in IE sieht eine gleich aus wie in modernen Browsern und eine nicht.
Siehe den Pen place-items experiment von Daniel Tonon (@daniel-tonon) auf CodePen.
Das war's, Leute
Ich hoffe, Sie haben das Lesen über die großartigen neuen Verbesserungen genossen, die die Autoprefixer-Community in den letzten Monaten am Projekt vorgenommen hat. Die neuen Kontrollkommentare machen das Aktivieren und Deaktivieren von Grid-Übersetzungen zum Kinderspiel. Das neue grid-areas System ist ebenfalls spannend. Ich liebe all die neuen IE-freundlichen CSS Grid-Optionen, die das neue Areas-System eröffnet, und ich denke, Sie werden das auch. 🙂
Artikelserie
- Entlarvung gängiger IE Grid-Missverständnisse
- CSS Grid und der neue Autoprefixer
- Ein Auto-Placement-Grid mit Lücken vortäuschen
- Duplikate Bereichsnamen jetzt unterstützt! (Dieser Beitrag)