Der folgende Beitrag stammt von Filip Naumovic von Salsita Software. Filip hat ein Sass-Tool entwickelt, das bei einem Problem hilft, das ich selbst schon oft erlebt habe. Du verschachtelst fröhlich in Sass. Du bist vielleicht ein oder zwei Ebenen tief und musst eine Variation gestalten, die auf einem übergeordneten Selektor basiert. Du musst entweder aus der Verschachtelung ausbrechen und einen neuen Verschachtelungskontext starten oder zu `@at-root` greifen. Ich überlasse es Filip, die Geschichte seines neuen Tools zu erzählen, das das ändert.
Sass hat vielen von uns enorm geholfen, unsere CSS-Codebasen aufzuräumen. Als es auf den Markt kam, entstanden einige äußerst nützliche Muster, die schnell übernommen wurden.
Zum Beispiel ermöglichten die Verwendung von & und die Verschachtelung die Bereinigung von sonst ziemlich unschönen Codeblöcken.
Das hier
.my-app { display: block; }
.my-app .widget { border-radius: 5px; }
.my-app .widget.blue { color: blue; }
.isIE6 .my-app .widget { background-image: url('fake-borders.png'); }
@media (max-width: 768px) { .my-app .widget { float: left; } }
Verwandelt in dies
.my-app {
display: block;
.widget {
border-radius: 5px;
&.blue {
color: blue;
}
.isIE6 & {
background-image: url("fake-borders.png");
}
@media (max-width: 768px) {
float: left;
}
}
}
Was für eine positive Veränderung für unsere geistige Gesundheit!
Alle Stilvariationen des .widget-Elements sind klar unter ihm verschachtelt, wobei die Einrückung sowohl als visueller Hinweis auf die Relevanz als auch als Abfragegenerator dient.
Der aktuelle Selektor (&) bietet in diesem Fall eine Abkürzung für die gängigsten Muster. Das Gestalten der Variation eines Elements, das entweder durch eine Eigenschaft des Elements selbst oder einen vorangestellten übergeordneten Zustand aufgerufen wird.
Verschachtelte Media Queries sind eine neuere Ergänzung, deuten aber darauf hin, dass die Entwicklung hin zu einer eingerückten Syntax für Stile fast zwangsläufig erfolgt. Sie ist leicht zu lesen und zu navigieren, da sie irgendwie die vertraute DOM-Struktur widerspiegelt und alle Stile für ein Element an einem Ort hält, während sie dennoch unsere wertvollen, aber manchmal komplizierten Selektoren erzeugt.
Heute sind Verschachtelungs- und aktuelle Selektorfunktionen in Less, Sass und Stylus vorhanden. Mit etwas Wein könnte man es fast als Standard bezeichnen.
Ein klassischer Fall von „Das kannst du nicht tun.“
Am obigen Codeblock als Beispiel, fügen wir Stile für .my-app.expanded .widget hinzu.
Trotz unserer mächtigen Werkzeuge finden wir uns schnell mit begrenzten Wahlmöglichkeiten wieder
Option 1
Mit der modernen @at-root-Direktive (oder / in Stylus) verlassen wir den aktuellen Geltungsbereich vollständig und wiederholen die vollständige Wurzelabfrage, um die relevanten neuen Stile unter .widget verschachtelt zu halten, da der aktuelle Selektor uns nicht helfen kann, diese Beziehung auszudrücken.
.my-app {
display: block;
.widget {
border-radius: 5px;
&.blue {
color: blue;
}
.isIE6 & {
background-image: url("fake-borders.png");
}
// repeating the root selector here
@at-root .my-app.expanded .widget {
color: red'
}
@media (max-width: 768px) {
float: left;
}
}
}
Dies erzeugt schwerer lesbaren Code mit viel Duplizität, insbesondere wenn die reale Nutzung weit über unser kleines Beispielstück hinausgeht. Aber es hält unser glorreiches Verschachtelungs-Paradigma intakt.
Option 2
Wir erstellen einen neuen Codeblock unter .my-app und verwenden ihn, um alle Kindelemente zu ändern, die für den .expanded-Zustand relevant sind. Das bedeutet, dass unser .widget nun an verschiedenen Stellen gestylt wird, und diese Trennung wächst mit jedem hinzugefügten Zustand in jedem Element der Verschachtelung.
.my-app {
display: block;
.widget {
border-radius: 5px;
&.blue {
color: blue;
}
.isIE6 & {
background-image: url("fake-borders.png");
}
@media (max-width: 768px) {
float: left;
}
}
&.expanded .widget
color: red;
}
}
Obwohl es direkt gegen unseren Traum vom „Verschachteln aller relevanten Stile“ verstößt, ist es die Unvollkommenheit, mit der wir gelernt haben zu leben. Viele von Ihnen würden dieses Muster wahrscheinlich sogar verteidigen, da es seit einiger Zeit so gehandhabt wird.
Wäre es jedoch nicht großartig, für die Wahlfreiheit eine Option 3 zu haben? Eine, die es uns ermöglicht, die einfache Änderung in .my-app.expanded auszudrücken, die unseren .widget beeinflusst, ohne den Kontext verlassen zu müssen?
Diese Idee hat mich eine ganze Weile heimlich beschäftigt, wenn auch nur aus einer gewissen Form von OCD bezüglich meiner eigenen Stylesheets. Ich habe es zu meiner Nebenaufgabe gemacht, dieses fehlende Werkzeug im Werkzeugkasten für Stile zu finden.
Option 3 finden
Bei der Recherche zu diesem Thema habe ich Spinnweben, ewige Diskussionen und wild variierende Vorschläge gefunden, von denen viele eine Ergänzung einer speziellen Syntax für den aktuellen Selektor & vorschlugen. Dies würde Monate des Lernens komplizierter Kernbibliotheken und das Kämpfen mit dem langen Krieg bedeuten, was sich sofort wie eine unerträgliche Last anfühlte.
Zweitens denke ich, dass & gut funktioniert, da es eine klare Darstellung des gesamten Kontexts ist, und aus diesem Grund könnte es problematisch sein, ihm weitere Funktionen hinzuzufügen. Es tut eine Sache und tut sie gut, daher schien es zu diesem Zeitpunkt eine bessere Idee zu sein, einen guten Partner dafür zu schaffen.
Um die einfache Integration zu ermöglichen, habe ich beschlossen, die Idee auf der Ebene der Präprozessorsprache zu implementieren, damit du sie einfach @importieren und sofort verwenden kannst. Präprozessoren sind heutzutage leistungsstarke Frameworks, warum also nicht?
Meine erste Wahl war Stylus, weil es einfach so genial ist. Leider kann, aufgrund von Issue 1703, der Platzhalter für den aktuellen Selektor derzeit nicht innerhalb einer Mixin-Funktion modifiziert werden. Wie ein guter Fanatiker werde ich bis ans Ende der Zeit warten, bis Stylus es behebt, aber ich musste weitersuchen, um etwas zu finden, das ich *jetzt* implementieren konnte.
Man darf den aktuellen Selektor in Less nicht parsen, also fiel das aus.
SassScript hingegen erwies sich als Kraftpaket. Obwohl ihm viele nützliche Abstraktionen für die Manipulation von Strings und Arrays fehlen, ist es sehr gut möglich, solche Funktionen manuell zu erstellen. Viele davon werden bereits von Sass Prince Kitty Giraudel bereitgestellt.
Nach Monaten des kontrollierten String-Terrors…
inStyle für Sass 3.4+ ist geboren!
Kitscher Name, ich weiß. Aber er deutet auf die Funktionalität hin, denn du möchtest, dass dieses Ding im tatsächlichen Code lesbar ist. Mixin-Syntax ist für Präprozessor-Benutzer bereits vertraut, daher klang ein suggestiver Name, um Änderungen *in* den übergeordneten Elementen zu beschreiben, für mich als zusätzliche Hürde gegen Unvertrautheit richtig.
Auf jeden Fall muss all das lesbar bleiben und komplexe Fälle behandeln, sonst verliert es seinen Zweck zugunsten von @at-root-Selektoransätzen oder dem einfachen Verschachteln des Codes an anderer Stelle. Ich habe mich für zwei grundlegende Mechanismen entschieden, von denen ich glaube, dass sie selbst die abscheulichsten Bedürfnisse adressieren und gleichzeitig einen logisch einfachen Parsing-Algorithmus beibehalten.
Verwendung 1) Modifikation
Ergänzungen zu einem zusammengesetzten Element, das im aktuellen Selektor vorhanden ist, handhaben ~80% des realen Codes, genau wie unser erstes Beispiel zu erreichen versucht.
.my-app {
display: block;
.widget {
border-radius: 5px;
&.blue {
color: blue;
}
.isIE6 & {
background-image: url("fake-borders.png");
}
@include in(".my-app.expanded") {
color: red; // .my-app.expanded .widget { };
}
@media (max-width: 768px) {
float: left;
}
}
}
Versuche, das so zu lesen
Gestalten von
.widget*in* dem Zustand.my-app.expanded.
Die Funktion durchsucht die Verschachtelung von unten nach oben nach dem ersten Vorkommen eines .my-app-Elements (wobei das aktuelle Element übersprungen wird) und hängt die Klasse .expanded daran an, wobei ein neuer Selektor zurückgegeben wird.
Was ist mit längeren Abfragen und Kombinationsänderungen?
table {
table-layout: fixed;
thead {
font-weight: normal;
tr {
height: 30px;
td {
background-color: #fafafa;
&.user {
font-weight: bold'
}
@include in('table.one tr.two:hover') {
background-image: url(rainbow.png) // table.one thead tr.two:hover td { };
}
}
}
}
}
Der tr-Elternteil wird gefunden und mit .two:hover modifiziert. Wenn man nach oben geht, wird auch table gefunden und mit .one modifiziert, andere Elemente werden übersprungen.
Irrelevante Multi-Selektoren werden aus dem neuen Selektor entfernt
ul, ol {
list-style: none;
li {
display: inline-block;
a {
text-decoration: underline;
@include in("ol.links") {
color: orange; // ol.links li a { };
}
}
}
}
Unmögliche Fälle und ungültige CSS-Abfragen erzeugen beim Kompilieren einen blockierenden Sass-Fehler
table {
table-layout: fixed;
td {
height: 30px;
@include in("table^s&()#") {
what: the; // ERROR, invalid CSS
}
@include in ("tr.green:hover") {
border-color: green; // ERROR, no tr or tr.green to modify in &
}
}
}
Beim Crash-Testing im Produktionsumfeld (hah!) habe ich einen weiteren sehr praktischen Bedarf festgestellt, den ich nicht nur durch Modifikationen des übergeordneten Baums erfüllen konnte. Tatsächlich löst er das obige Beispiel, da man dies mit tr.green:hover tun können muss. Man muss einfach sagen können, wo.
Verwendung 2) Einfügung
Nehmen wir an, das Folgende
table {
table-layout: fixed;
thead {
font-weight: normal;
}
tr {
height: 30px;
}
td {
background-color: #fafafa;
}
}
Wo würdest du idealerweise einen table thead tr-Selektor verschachteln? Nach dem Dogma musst du ihn scheinbar wie folgt hinzufügen:
table {
table-layout: fixed;
thead {
font-weight: normal;
tr {
height: 50px;
}
tr {
height: 30px;
}
td {
background-color: #fafafa;
}
}
Das betroffene gestylte Element ist jedoch tr und du hast das bereits als generischen Stil, also könnte das Verschachteln darunter als Variante näher daran sein, wie du über die Beziehung denkst, und die Lücken füllen, die der aktuelle Selektor & nicht beschreiben kann.
In diesem Fall bedeutet dies, dass es einen einfachen Weg geben muss, einen Selektor an einer bestimmten Position über dem aktuellen Element einzufügen und gleichzeitig Kombinationen mit zusammengesetzten Modifikationen zu ermöglichen. Ich konnte mir das ohne ein Sonderzeichen nicht vorstellen, daher habe ich mich für das visuell suggestive ^ (Caret) entschieden.
table {
table-layout: fixed;
thead {
font-weight: normal;
}
tr {
height: 30px;
@include in("^thead") {
height: 50px; // table thead tr { };
}
}
td {
background-color: #fafafa;
@include in("table.blue-skin ^tbody") {
background-color: blue; // table.blue-skin tbody td { };
}
}
}
In diesem Fall fügt der Caret thead *eine* Ebene oberhalb des aktuellen oder zuletzt modifizierten Elements ein. Mehr Carets bedeuten höhere Sprünge im aktuellen Selektor
main {
display: flex;
> div {
flex-grow: 1;
span {
display: inline-block;
&.highlight {
outline-style: dashed;
@include in("^^.section.active") {
outline-style: solid; // main .section.active > div span.highlight { };
}
@include in("^^^.section") {
some: thing; // ERROR, inserting too high, it would equal to ".section &"
}
}
}
}
}
Hinweis: &.highlight ist dasselbe Element wie span, daher behandelt die Einfügung es als einen Schritt in der Verschachtelung
Ich denke, inStyle glänzt in den einfachsten Fällen, die auch bei weitem die häufigsten sind. Aber Dinge können bei Bedarf komplexer werden.
Verwendung 3) Fortgeschrittene Kombinationen
Der Matching-Algorithmus erlaubt es Ihnen, noch wilder einzufügen oder mehr zusammengesetzte Teile gleichzeitig zu modifizieren
.my-app {
display: flex;
section {
flex: 1;
header {
width: 100%;
@include in("^^.wrapper ^.dialog)") {
height: 50px; // .my-app .wrapper section .dialog header { };
}
@include in("^.overlay ^.sidebar") {
position: fixed; // .my-app section .overlay .sidebar header { };
}
@include in("^.modifier section.next ^.parent") {
opacity: 0; // .my-app .modifier section.next .parent header { };
}
}
}
}
.dialogwird eine Ebene überheadereingefügt und.wrapperzwei Ebenen darüber..sidebarwird überheadereingefügt und.overlaydirekt darüber.- Verschiebt
.parentüberheader, modifiziertsectionmit.nextund schiebt dann.modifierdarüber.
Das erinnert mich, vielleicht haben Sie Feedback! Ich habe darüber nachgedacht, eine einfachere Syntax zu ermöglichen, wenn Sie mehrere zusammengesetzte Elemente direkt hintereinander einfügen möchten, wie im zweiten Fall, vielleicht etwas wie @include in("^(.overlay .sidebar)") oder den Parser zu verbessern und ein natürlicheres @include in("^.overlay .sidebar") zu ermöglichen. Lassen Sie mich Ihre Meinung wissen!
Nachdem ich es eine Weile benutzt habe, habe ich festgestellt, dass die meisten meiner unbequemen Code-Muster recht einfach gelöst werden können, indem ich hier und da ein Element ändere oder einen neuen Selektor an eine bestimmte Position schiebe und die Dinge an Ort und Stelle halte. Dennoch muss ich ehrlich sein, es ist von Natur aus potenziell ziemlich invasiv für Ihre übliche Code-Organisation.
Ich kann mir vorstellen, dass die Verwendung von inStyle zu hitzigen Diskussionen führen könnte. Meine Kollegen scheinen entweder aufgeschlossen zu sein oder sich nicht zu kümmern, was beides großartig ist.
Wenn Sie es verwenden, hoffe ich, dass die richtige Handhabung wie bei jedem anderen Werkzeug erfolgt: wenn es für den Job geeignet ist. Das Spammen mit komplexen verschachtelten Mixins wird wahrscheinlich nicht mehr Lesbarkeit bieten als das Schreiben der vollständigen Abfrage von Grund auf, aber andererseits kann es die meisten realen Probleme vereinfachen und gleichzeitig einen schlanken Fußabdruck hinterlassen.
In naher Zukunft möchte ich den Stylus-Port zum Laufen bringen und vielleicht ein Atom-Editor-Plugin erstellen, um die resultierende Abfrage als Hinweis im Code anzuzeigen.
Es hat Spaß gemacht, sich an der Lösung von First-World-Problemen von CSS zu versuchen, und ich hoffe, dass Sie das Thema zumindest für diskussionswürdig halten. Das Projekt ist Open Source, also fühlen Sie sich frei, mit Code oder Feedback an Bord zu kommen!
Ob Sie es lieben oder hassen, hier ist es auf GitHub, hier ist eine kleine Microsite und hier ist ein Live-Debugger zur Sicherheit.
Siehe den Pen inStyle Crash Test Dummy von Salsita Software (@salsita) auf CodePen.
Danke fürs Lesen!
Off-Topic: Ist es möglich, die Hervorhebung von Codezeilen so einzustellen, dass sie auf derselben Zeile bleiben, auch wenn man die Schriftgröße der Website ändert? Vielleicht mit em statt px?
Cooler Hater-Kommentar.
Ich wäre hin- und hergerissen zwischen der zusätzlichen Abhängigkeit und der nützlichen Syntax.
Hier ist das #1, was ich daran mag
Dinge auf derselben Ebene verschachtelt zu halten, fühlt sich irgendwie cool an.
Ja, ich war ein Hater. Entschuldigung. Die Ideen im Artikel sind clever und gut umgesetzt. Ich hatte nur in letzter Zeit Probleme mit übermäßig komplexer Sass-Verschachtelung. Ich meine, selbst im allerersten Beispiel dieses Artikels schien das ausführliche CSS dem verschachtelten SASS vorzuziehen zu sein. (Obwohl ich weiß, dass das nicht immer der Fall ist.)
Chris, für mich fühlt sich dein Beispiel sogar noch besser so an:
Knochentrockenes, einfaches CSS für den Sieg.
Ich würde sagen, wenn Sie generell Standard-CSS mit vollständigen Abfragen bevorzugen, wie in Ihrem letzten Beispiel, dann wird diese ganze Idee für Ihre Anwendung etwas bedeutungslos.
Chris, ich glaube, du hast das perfekte Gegenbeispiel geschrieben. Was passiert, wenn du oder jemand anderes die Navigation von einer
olzu eineruländert und vergisst, den Selektor im String zu ändern? :)Hier ist eine viel lesbarere Version ohne
@include in("^headache")Ja, du kannst das immer noch vermasseln, indem du einen der
li-Selektoren änderst, ohne die anderen zu ändern. Aber es ist viel einfacher, alleli-Selektoren hier zu sehen, als den übergeordneten Selektor, der tief verschachtelt und in einem String ist.Im Ernst, was ist diese Besessenheit mit dem Verschachteln? Und Selektoren in Strings zu haben, igitt!
Hallo Agop, ich bin mir nicht sicher, ob es möglich ist, einen Fall zu behandeln, bei dem jemand die HTML-Struktur ändert und die CSS-Struktur nicht.
Filip, meine Anmerkung bezog sich auf den Fall, dass die
olzu einerulsowohl in HTML als auch in (S)CSS geändert wird, aber nicht im@include in("foo")-String. Das ist für einen Entwickler, der nicht sehr vertraut mit der Codebasis ist, sehr unintuitiv. Das Wiederholen des übergeordneten Selektors anstelle des Kindselektors ist meiner Meinung nach ein Rückschritt.Du hast Recht bezüglich dieser Anforderung. Ich habe gedacht, dass das Wiederholen des übergeordneten zusammengesetzten Elements die Lesbarkeit erhöhen würde, aber nach Sergs Bitte weiter unten in den Kommentaren habe ich jetzt eine Möglichkeit hinzugefügt, das übergeordnete Ziel in 1.4.0 zu abstrahieren, damit es nicht wiederholt werden muss. Das Sonderzeichen ist auch konfigurierbar und wird jede Änderung im übergeordneten Element korrekt referenzieren.
Nur zur Information, das Wiederholen des zusammengesetzten Selektors hat einige Vorteile, die man nicht durch Abstraktion mit
<erzielen kann.Du kannst Mehrfachselektoren lösen und trotzdem recht lesbar bleiben, wie im Artikel erwähnt.
Alles klar, gut, das ist viel besser. Jetzt wiederholst du nichts mehr, was großartig ist.
(Bin mir immer noch nicht sicher, ob ich diese Syntax jemals unterstützen werde, aber mehr Macht für diejenigen, die sie mögen.)
Das ist ein sehr cooles Konzept. Ich würde diesen Trick definitiv bei meinem nächsten Projekt anwenden.
Für diejenigen, die sich Sorgen über Konflikte zwischen HTML und CSS beim Ändern von Markup usw. machen, empfehle ich dringend, sich dieses Vortrags über Modular CSS anzusehen: https://www.youtube.com/watch?v=HoQ-QEusyS0
Hey! Ich habe gerade ein POSTCSS-Plugin veröffentlicht, um auf übergeordnete Selektoren in verschachteltem CSS mit einer sehr ähnlichen und konfigurierbaren „^&“-Syntax zu verweisen.
Schau es dir an: postcss-nested-ancestors.
Prost!
Hallo Andrea, das ist großartige Arbeit! Ich schaue mir auch gerade an, inStyle nach PostCSS zu portieren, und du hast mir Mut gemacht :D Wir scheinen ähnliche Methoden zu verwenden, um übergeordnete Elemente zuzuweisen (Aufwärtszählung des aktuellen Elements), obwohl ich beim
&-Gebrauch etwas zwiegespalten bin – ich bin es einfach so gewohnt, dass es sich auf den gesamten String bezieht. So oder so ist es großartig, diese Lösungen auf dem Vormarsch zu sehen, da sie sicher Wert für unsere Codebasen haben.Was ich mir gewünscht hätte, anstatt eines weiteren @include-Operators(selector)-Dings, wäre eine Erweiterung von Stylus
/, die eine „Syntax“ verwendet, die wir alle bereits kennen: Die gute alte../-Pfad-Traversal-Notation.Das würde es leicht ermöglichen, eine Ebene, zwei oder vielleicht drei nach oben zu gehen, so dass die „nukleare“ Option und damit das erneute Durchlaufen des gesamten Selektorpfads nicht mehr notwendig wäre.
(Und das Gegenargument von „aber was, wenn ich noch viel mehr Ebenen hochgehen muss, dann wird das wirklich hässlich und schwer zu lesen“ bedeutet wahrscheinlich nur, dass du deine Selektoren schon zu lang werden lassen hast ;-)
Stylus hat bereits Möglichkeiten, spezifische Elternziele anzusprechen, siehe http://stylus-lang.com/docs/selectors.html#partial-reference. Es ist jedoch in der Praxis etwas enttäuschend und deckt nicht alle möglichen Verwendungszwecke ab, die du davon benötigst.
Brauchen wir das überhaupt, wenn BEM heutzutage der Weg ist (bis CSS Modules oder Shadow DOM voll nutzbar sind)?
Hallo, Autor hier. Ich glaube nicht, dass es irgendeine Verbindung zu BEM gibt, kannst du das näher erläutern?
Mit BEM vermeidet man so viel Verschachtelung wie möglich. Die in diesem Artikel gezeigte Methode scheint stattdessen stark auf Verschachtelung zu setzen, bis zu dem Punkt, dass man einen benutzerdefinierten Mixin benötigt, um Flexibilität für verschachtelte Selektoren zu schaffen.
Ich glaube nicht, dass „Alles verschachteln!“ eine gute Methode ist, um sauberes CSS zu schreiben ... BEM lehrt uns das.
Kannst du den Konflikt mit BEM spezifizieren? Wenn du kurze, extrem spezifische Abfragen meinst, wirst du trotzdem auf dieselben Fälle stoßen wie bei jeder anderen Methodik. Ich denke, InStyle gibt dir lediglich einige Möglichkeiten, diese Fälle bequemer zu beschreiben, wenn du verschachteltes CSS verwendest, stört aber die Methodik selbst nicht.
Vielleicht verpasse ich etwas (sicherlich), aber ...
Was ist der Unterschied zwischen
@include in(".my-app.expanded") {und.my-app.expanded & {?Mit einem BEM-ähnlichen CSS würde ich Folgendes tun:
was die Verschachtelungs-Hölle reduziert.
BEM-Code verwendet den aktuellen Selektor, um das Präfix zu speichern, und nicht viel mehr, was sowohl Vor- als auch Nachteile hat. Es ist eine Art Kompromiss, das Gleiche für BEM mit dem aktuellen inStyle zu erzeugen – du musst das aktuelle Element nicht wiederholen und erhältst variantenreiche Verschachtelung, aber du verlierst die Interpolation von
my-appweiter unten (was du in BEM aber sowieso nicht brauchen wirst, da du die Abfrage kurz halten willst). Das wäre gleichbedeutend mit deinem Code´´´
.my-app
&__widget
color: red
+in(‘.my-app–expanded’)
color: blue
´´´
Ich kann sehen, wie das weiter optimiert werden könnte, vielleicht gibt es einen Fall für eine BEM-freundliche Version
Da BEM feste Syntaxregeln hat, könnten die Zustände automatisch präfixiert werden. Das wäre dann direkt weniger Code, der dasselbe tut, und ich wage zu sagen, mit erhöhter Lesbarkeit. Das ist nicht das, was inStyle im Moment tut, aber es sollte kein Problem sein, es hinzuzufügen. Würdest du das als Verbesserung betrachten?
Meine Präferenz hier
Halte den Code durchsuchbar, indem du den &-Selektor nicht verwendest. Abhängig davon, wie viele andere Eigenschaften hierher gehen müssen, würde ich es so schreiben
Oder einfach so
Entschuldigung für den 3. Kommentar in Folge, aber es ist auch erwähnenswert, dass ein dynamischer Zustand eine separate Klasse wie diese verwenden würde
Hallo Michael, deine Beispiele sind genau das, was ich lösen will. Deine bevorzugte Syntax scheint im Grunde Standard-CSS zu sein, bei dem du eine große Menge von Selektoren wiederholst, ohne wirklich die Vorteile zu nutzen, die die Verschachtelung bieten kann.
Meine Beispiele sind schlecht, ich entschuldige mich. Ich glaube einfach nicht, dass es eine gute Idee ist, einen Klassennamen in zwei Teile im CSS-Quellcode zu teilen – das beeinträchtigt die Code-Durchsuchbarkeit schmerzlich. Zum Thema des Artikels ist dies ein wichtiges Problem, dem ich häufig begegne! Toll, diese experimentelle Funktion zu sehen.
Hallo Michael, ich entschuldige mich für das anfängliche Missverständnis deiner Kommentare – ich sehe jetzt, dass du die Art und Weise in Frage stellst, wie das obige BEM-Beispiel den aktuellen Selektor verwendet. Ich stimme zu, dass das Interpolieren von Selektorabfragen auf diese Weise eher fragwürdig aussieht. Es gibt wahrscheinlich sowohl eine Verschachtelungs-Hölle als auch eine BEM-Hölle, und beides sollte vermieden werden. Ich denke, wenn jemand auf BEM festgelegt ist, gibt es viel Raum, die schlechten Teile innerhalb des Präprozessor-Frameworks zu abstrahieren, aber das ist nicht direkt der Umfang von inStyle.
Danke, die Idee und das Plugin sind gut.
Ich hatte solche Probleme und es wäre für mich super nützlich, wenn
^^.wrapperals.my-app.wrapperinterpretiert würde,aber derzeit ist es
.my-app .wrapper(ein solches Verhalten würde ich von^^ .wrappererwarten)was keine Möglichkeit gibt, mit übergeordneten Elementen zu interagieren, sondern nur Mediatoren hinzuzufügen.
Hallo Serg, danke für das Feedback! Ich habe darüber nachgedacht, eine Kurzschreibweise einzuführen, um die Eltern ohne Wiederholung ihrer zusammengesetzten Selektoren anzusprechen, hatte mich aber entschieden, sie noch nicht zu implementieren, da der vollständige Selektor in der Praxis besser lesbar schien. Gleichzeitig schien das Zeichen
^die Einfügefunktion gut anzudeuten, vielleicht könnten wir also ein alternatives Zeichen finden, um die Zielverbindung anzudeuten. Nummerierung vielleicht? Ich werde zu diesem Thema ein Thema auf Github eröffnen, also fühle dich frei, dich einzubringen! Definitiv kein Problem, es auf die eine oder andere Weise hinzuzufügen.Ich verwende die BEM-Syntax, wie einige der anderen Kommentatoren erwähnt haben. Eine meiner Regeln lautet: „Deklariere einen Modulteil nur einmal.“ Aber du hast Recht, wenn man an einem bestimmten Zustand für das Modul arbeitet, ist es nicht sehr klar, wie die Sass-Organisation gehandhabt werden soll. Ich habe oft beide Methoden 1 & 2 verwendet.
Ich denke, dass mir dieses Plugin, wenn es verantwortungsvoll eingesetzt wird, eine Möglichkeit gibt, meine zustandsspezifischen Modulteil-Stile direkt neben den ursprünglichen Stilen des Moduls zu belassen. Das gefällt mir sehr.
Ich liebe die Idee und die Umsetzung.
Ist es nützlich? Für mich schon. Ich suche seit Monaten nach einer Lösung wie dieser.
Ist es unerlässlich? Aber nein, aber es ist wirklich schön, es in meinem Werkzeugkasten zu haben.
Natürlich kann es knifflig sein und übermäßig verwendet kann zu viel unübersichtlichem Code führen. Aber das Gleiche kann man über viele gängige Präprozessor-Features sagen. Nehmen Sie zum Beispiel ein einfaches SASS @extend. Ich habe viele schreckliche Anwendungen gesehen, aber es ist da, es ist nützlich und ich glaube nicht, dass es ein Problem ist.
Wie bei allen Werkzeugen sollte es vorsichtig und nur dann verwendet werden, wenn es hilft.
Mann, das sieht großartig aus! Ich hatte genau damit auf einem früheren Projekt zu kämpfen. Ich habe verschiedene Ansätze mit Mixins versucht, aber es nie richtig hinbekommen. Ich habe mich für Ansatz 2 entschieden (@at-root sieht für mich einfach zu unübersichtlich aus). Ich werde Ihr Plugin auf jeden Fall bookmarken und es bei meinem nächsten CSS-lastigen Projekt verwenden.
Leute sagen, es kann zu unübersichtlichem Code führen. Sicher, aber dann können Leute jede Art von Zukunft missbrauchen, nicht weniger so in Sass. Ich habe einmal an einem Projekt gearbeitet, bei dem die Leute einfach bananas gingen, indem sie @extend benutzten (ich benutze es nur, wenn ich mit Platzhaltern arbeite, und das ist sehr selten). Ich kann sagen, dass ich diese Dateien wegen des Grades der Komplexität, der durch die Anzahl der Extend-Regeln verursacht wurde, nicht einmal lesen konnte.
Das ist wirklich sehr geschätzt. Danke fürs Teilen!
Wie wäre es damit?
Ich glaube, Ihr Mixin ist im Wesentlichen gleichwertig mit
Nützlich, aber nicht so sehr wie das im Beitrag beschriebene Plugin.