Sass macht die Arbeit mit Media Queries ziemlich ausgezeichnet. Sie können diese direkt innerhalb anderer CSS-Blöcke verschachteln, was die geänderten Eigenschaften und Werte nebeneinander platziert. Das schafft eine offensichtliche Verbindung zwischen ihnen, was ein wesentlich besseres Autoring-Erlebnis ist, als zu versuchen, diese Änderungen, getrennt durch viel anderen Code oder in einer anderen Datei, zu verwalten. Wir haben das schon einmal behandelt. Es war neu in Sass 3.2.
.column-1-3 {
width: 33.3333%;
@media (max-width: 600px) {
width: 100%;
}
}
Da wir dies wahrscheinlich immer wieder tun werden, sollten wir diese Media Query wie jede andere Variable abstrahieren.
$bp-babybear: "(max-width: 600px)";
.column-1-3 {
width: 33.33%;
@media #{$bp-babybear} {
width: 100%;
}
}
Üblicher ist jedoch die Verwendung von @mixin in Verbindung mit Sass @content-Blöcken. Dies haben wir im Artikel Benennung von Media Queries behandelt.
@mixin bp($point) {
@if $point == papa-bear {
@media (max-width: 1600px) { @content; }
}
@else if $point == mama-bear {
@media (max-width: 1250px) { @content; }
}
@else if $point == baby-bear {
@media (max-width: 600px) { @content; }
}
}
Welches Sie so verwenden
.sidebar {
width: 33.33%;
@include bp(baby-bear) {
width: 100%;
}
}
Und es gibt keinen Grund, warum Sie nicht beides tun können, indem Sie die Media Queries in Variablen abstrahieren, wenn Sie die Optik davon bevorzugen
@mixin bp($point) {
$bp-babybear: "(max-width: 600px)";
$bp-mamabear: "(max-width: 1250px)";
$bp-papabear: "(max-width: 1600px)";
@if $point == papa-bear {
@media #{$bp-papabear} { @content; }
}
@else if $point == mama-bear {
@media #{$bp-mamabear} { @content; }
}
@else if $point == baby-bear {
@media #{$bp-babybear} { @content; }
}
}
Was die exakt gleiche Verwendung hat.
Nebenbei bemerkt, mag ich "bp" als Namen, da es etwas ist, das man immer wieder tippen muss und es kurz und bündig ist.
Auf den ersten Blick scheint der @mixin-Ansatz einen begrenzten Wert zu haben. Die Verwendung einer Variable ist weniger ausführlich und ergibt genauso viel Sinn. Mit dem @mixin erhalten wir jedoch zusätzliche Kräfte!
Vielleicht möchten wir eine Version eines Stylesheets erstellen, das überhaupt keine Media Queries enthält. Das ist unter bestimmten Umständen absolut sinnvoll. Vielleicht möchten wir ein Stylesheet für IE 8 und darunter erstellen. Nicolas Gallagher spielte vor Jahren mit der Verwendung von Sass dafür, aber das ist etwas anders. IE 8 und darunter unterstützen von Haus aus keine Media Queries, also entscheiden wir uns vielleicht dafür, ihnen ein gestrafftes Stylesheet zur Verfügung zu stellen, das sie überhaupt nicht enthält. Alte Browser wie dieser sind sowieso langsamer, also bestrafen wir sie nicht mit zusätzlichem Code, den sie nicht verwenden können, sondern helfen ihnen, indem wir ihnen weniger zur Verfügung stellen. Eine Art Universal IE 6 Stylesheet-Idee.
Wir können eine Kombination von bedingten Kommentaren verwenden, um das zu tun.
<!--[if !IE 8]><!-->
<link rel="stylesheet" href="style.css">
<!--<![endif]-->
<!--[if gte IE 9]>
<link rel="stylesheet" href="style.css">
<![endif]-->
<!--[if lte IE 8]>
<link rel="stylesheet" href="style-NoMQs.css">
<![endif]-->
Ein weiterer sinnvoller und realweltlicher Grund, ein Stylesheet ohne Media Queries bereitzustellen, ist, wenn einige Seiten Ihrer Website responsives Design verwenden und einige Seiten Ihrer Website eine mobil-spezifische Version haben. Ich halte das für vernünftig. Die Seiten, die eine mobil-spezifische Version haben, benötigen diese Media Queries eigentlich nicht.
Wie erstellen wir also sowohl ein style.css als auch ein style-NoMQs.css aus demselben Quell-Sass? Wir nutzen die Kraft unseres @mixin.
Wir verwenden eine Logikbedingung innerhalb des bp @mixin, die entweder fortfährt und die Media Query ausgibt oder nichts ausgibt.
$MQs: true;
@mixin bp($point) {
@if ($MQs) {
$bp-babybear: "(max-width: 600px)";
$bp-mamabear: "(max-width: 1250px)";
$bp-papabear: "(max-width: 1600px)";
@if $point == papa-bear {
@media #{$bp-papabear} { @content; }
}
@else if $point == mama-bear {
@media #{$bp-mamabear} { @content; }
}
@else if $point == baby-bear {
@media #{$bp-babybear} { @content; }
}
}
}
Sie würden diese Variable jedoch nicht direkt außerhalb des @mixin deklarieren. Sie würden sie aus Ihrer "Master"-Datei deklarieren, die alle Teil-Dateien importiert. Ihre style.scss-Datei könnte also so aussehen
$MQs: true;
@import "variables";
@import "colors";
@import "global";
/* etc. */
Und Sie erstellen die "Keine Media Queries"-Version (style-NoMQs.css), indem Sie eine style-NoMQs.scss erstellen
$MQs: false;
@import "variables";
@import "colors";
@import "global";
/* etc. */
Ändern Sie diese Variable einfach auf false, und die Ausgabe-CSS enthält überhaupt keine Media Queries.
Großen Dank an Cat Farman, die über dieselbe Idee in ihrem Cognition-Artikel Fall Back to the Cascade schrieb, mit der leichten Abwandlung, die Support-Variable an das @mixin selbst zu übergeben. (Ist das sicherer?)
Und als letzter Hinweis: Ich weiß, viele Leute mögen es nicht, wie Sass repetitive Media Queries in der endgültigen Ausgabe erzeugt und die Media Query nur so weit nach oben "blubbert" wie bis zum Ende der Verschachtelung. Das ist notwendig, um die Quellreihenfolge-Spezifität des Selektors zu berücksichtigen (soweit ich das verstehe). Ich persönlich habe mich nie darum gekümmert, da ich immer Assets mit aktiviertem GZip ausliefert, und GZip isst repetitive Texte zum Frühstück, es ändert die Dateigröße nicht wesentlich. Ganz zu schweigen davon, dass Browser problemlos durch diese Regeln zoomen und sie anwenden können. Wenn Ihnen das aber immer noch nicht gefällt (oder ich falsch liege), gibt es ein Grunt-Plugin dafür.
Andere Ansätze
- Die Technik von Dmitry Sheiko, die größere und kleinere Breakpoints ermöglicht.
- Breakpoint-sass
Super Tipp. Ich wünschte nur, es gäbe eine Möglichkeit, Inline-MQs in SASS zu machen und sie später trotzdem zu kombinieren.
Hallo Chris, das ist großartig, es ist eine großartige Lösung, um immer noch "mobile-first"-Websites bauen zu können, aber trotzdem die "Desktop"-Version in IE8 anzeigen zu können.
Vor ein paar Monaten habe ich eine sehr ähnliche Lösung gefunden, ich würde mich freuen, wenn Sie sehen könnten, was Sie davon halten: https://github.com/peduarte/mobile-first-sass
Beste Grüße
Ich mag die Art, wie Sie @media print am Leben erhalten!
Wenn Sie Ihre eigenen Mixins nicht pflegen möchten, gibt es eine Compass-Erweiterung, die dies (und vieles mehr!) automatisch handhabt, namens Breakpoint.
Ich habe andere Funktionen bereits in den Kommentaren von CSS Tricks behandelt, aber die No Query Fallbacks von Breakpoint könnten für Leute, die diesen Artikel lesen, von Interesse sein.
Es hat mehrere Ausgabe-Modi: separates Stylesheet (wie von Chris Coyier in diesem Beitrag beschrieben) und auch eine bedingte Klassen-Ausgabemethode im selben Stylesheet, falls Sie keinen separaten CSS-Download für die bereits langsamen, älteren IEs wünschen.
Zum Beispiel schreiben Sie etwas Sass
Generiert dieses CSS
Ich stimme http://www.breakpoint-sass.com.. zu. Wahnsinnig nützlich und einfach zu warten.
Wir verwenden diesen Ansatz ebenfalls (aber mit separaten Stylesheets für MQ & Nicht-MQ-Browser unter Verwendung von bedingten Kommentaren, wie gezeigt).
Es ist großartig, weil Sie Stile fortschreitend hinzufügen können, wenn die Bildschirmbreite zunimmt, und Nicht-MQ-Browser die gleichen Ergebnisse erhalten.
Vor ein paar Monaten, bevor ich ein Codepen-Konto hatte :'( , habe ich mit der Idee gespielt, eine ideale Bildschirmgröße für alte IEs festzulegen, anstatt ihnen die mobile oder die vollständige Desktop-Version anzubieten. Dies kann sowohl für Breiten als auch für Höhen geschehen. Schnelles Pen
http://codepen.io/thomasdobber/pen/oLvCq
Dies ist genau das, was das Guardian-Team mit ihrem neu veröffentlichten sass-mq Mixin tut. Die Theorie wird in der README und in diesem Artikel beschrieben. Es ist eine clevere Lösung und leicht verständlich.
Ich habe an einer kleinen Ergänzung gearbeitet, um einen Ziel- statischen Breakpoint festzulegen, sodass die statische/rasterisierte Ausgabe nur Stile enthält, die für eine bestimmte Bildschirmgröße gelten, und vermeidet es, z. B. Widescreen-Stile an IE8 und ähnliche auszuliefern.
Vielen Dank fürs Teilen!
Ich verfolge einen ähnlichen Ansatz für die mobile-first-Entwicklung, aber da ich mit .less-Dateien arbeite, habe ich keinen Zugriff auf @content-Blöcke (zumindest soweit ich weiß). Also musste ich eine Lösung finden, die auf in Variablen gespeicherten Media Queries basiert. Das könnten Sie sicherlich auch in SASS implementieren.
In meiner Master-Datei werden mehrere .less-Dateien importiert.
@import “variables.less”;
@import “mixins.less”;
@import “reset.less”;
@import “base.less”;
@import “layout.less”;
@import “modules.less”;
Die Media-Query-Variablen werden in der Datei variables.less gespeichert und ungefähr so gelesen
@mq-medium-and-up: ~”only screen and (min-width: @{breakpoint-medium})”;
@mq-large-and-up: ~”only screen and (min-width: @{breakpoint-large})”;
Und hier ist ein Beispiel (zugegebenermaßen etwas konstruiert) für die Verwendung einer dieser Variablen
Körper {
background: yellow;
@media @mq-medium-and-up {
background: red;
}
}
Ich führe auch eine separate Master-Datei für IE <= 8, die etwa so aussieht
@import “variables.less”;
@mq-medium-and-up: ~”all”;
@mq-large-and-up: ~”all”;
@import “mixins.less”;
@import “reset.less”;
@import “base.less”;
@import “layout.less”;
@import “modules.less”;
Was oben passiert ist, dass nach dem Import der Datei variables.less die Media Query-Variablen sofort überschrieben und neu definiert werden. Wenn wir diese Variablen nun in unseren Stylesheets verwenden, werden sie in Media-Regeln kompiliert, die von älteren Versionen von Internet Explorer verstanden werden (bei IE < 7 bin ich mir nicht sicher).
Körper {
background: yellow;
@media all {
background: red;
}
}
Im Grunde erhalten diese älteren Browser die Desktop-Erfahrung, was eine gute Alternative dazu sein kann, sie mit nur der Basis-Erfahrung zurückzulassen. Das sollte offensichtlich eine Fall-zu-Fall-Entscheidung sein. Irgendwelche Gedanken zu dieser Lösung?
Großartige Lösung: Ich habe sie kürzlich in einigen ziemlich großen Projekten verwendet und die Arbeit mit alten IE war ein Kinderspiel. Jake Archibald kam vor etwa einem Jahr auf fast genau dasselbe: http://jakearchibald.github.io/sass-ie/
Sie können Ihre Variablen auch in eine Liste einfügen, durch die das Mixin iteriert. Ursprünglich habe ich das getan, um zu vermeiden, das Mixin für jeden Breakpoint neu schreiben zu müssen, und es scheint ziemlich gut zu funktionieren. Ich benutze normalerweise nicht die 3 Bären-Analogie, aber ich habe sie geändert, um mit diesem Artikel konsistent zu sein.
Um auch ein separates altes IE-Stylesheet zu erstellen, können Sie das folgende Mixin verwenden
Dann können Sie die folgende Variable am Anfang Ihrer "oldie.scss"-Datei hinzufügen
Und verknüpfen Sie Ihre Stylesheets mit Ihrem HTML wie folgt
Und schreiben Sie Ihre Sass wie gewohnt
Was in Ihrer normalen "style.css"-Datei so gerendert wird
Und automatisch in Ihre "oldie.css"-Datei ohne die Media Queries gerendert, nur mit den definierten "oldie breakpoints" (babybear und mamabear) aus dem Mixin als
Puh, das war lang, aber es ist zu cool, um es nicht auszuprobieren, wenn Sie immer noch Legacy IE-Browser unterstützen möchten. Persönlich versuche ich, IE8+ offiziell zu unterstützen, aber ich möchte, dass es in IE6/7 so gut wie möglich aussieht, ohne zu viel Zeit mit Hacking zu verbringen.
Eine weitere Sache, die Sie mit der $oldie-Variable tun können, ist etwa so
Was in die normale "style.css"-Datei so gerendert wird
und in die "oldie.css"-Datei als
Was automatisch alle IE-Hacks in die "oldie.css"-Datei einfügt und die "style.css"-Datei sauber hält. Ok, ich bin fertig!
Ich wollte gerade dasselbe schreiben – eine viel bessere Methode!
Dies ist ein cooler, optimierter Ansatz. Das Einzige, was ich daran hasse, ist, dass Ihre Stylesheets mit doppelten
@media()-Deklarationen übersät sind.Es wäre schön, wenn SASS intelligent genug wäre, um dieselben Media Queries wie folgt zu gruppieren
Stattdessen werden
@media(max-width:767px)...-Blöcke zweimal erstellt. Zumindest ist es schlau genug, die Media Query aus der Style-Definition herauszuziehen. Wenn Sie also ein großes Stylesheet mit Hunderten von Elementen haben, die unterschiedliche Werte für mehrere verschiedene Breakpoints haben, erhalten Sie am Ende buchstäblich Tausende von@media()-Blöcken, die Ihrem Stylesheet hinzugefügt werden.Ich habe mit dem Hinzufügen von Breakpoint-Werten zu SASS-Listen über den append()-Befehl experimentiert und dann durch die Listen iteriert und Ihre Media Queries alle gruppiert generiert, aber verschachtelte Selektoren machen es schnell unübersichtlich. Suche immer noch nach einer Lösung dafür.
Dafür gibt es eine Lösung: http://www.building-blocks.com/thinking/combine-matching-media-queries-with-grunt
@Jake zu 110% einverstanden. +1.
@Paul Was, wenn wir Grunt nicht benutzen...?
Ich sehe keinen soliden Grund, sich mit einem weiteren Puzzleteil in einem bereits komplexen und gesättigten Entwicklungs-Workflow auseinandersetzen zu müssen, nur um Sass die Media Queries auf offensichtliche Weise kompilieren zu lassen: am Ende von CSS.
DRY (Don't Repeat Yourself) fliegt hier aus dem Fenster.
Was Chris am Ende über GZipping und die Browser sagt, hilft sicherlich, das Problem zu "akzeptieren", hinterlässt aber einen leicht bitteren Nachgeschmack.
Hey @jake und @Ricardo
Kimberly Blessing hat eine großartige Präsentation gehalten, wie das, worüber Sie sich Sorgen machen, absolut keine Rolle spielt. Egal, ob Sie alle MQ's zusammenführen oder sie über die Seite verteilen, es gibt keinen nennenswerten Unterschied zwischen beiden Methoden.
Kimberly Blessing: Optimizing Media Queries
Fühlen Sie sich also frei, den bitteren Nachgeschmack aus Ihrem Mund zu wischen :)
Das ultimative Ziel ist es, Ihr SASS einfacher zu lesen und zu verstehen zu machen, nicht Ihr CSS. Und in diesem Fall sehen Sie jede MQ, die auf jedes Element angewendet wird, anstatt überall auf der Seite suchen zu müssen, warum es 300px statt 500px ist...
PS: Grunt ist wirklich einfach zu bedienen, und wenn Sie es noch nicht verwendet haben, werden Sie es nie wieder zurückgeben, wenn Sie es einmal benutzt haben :) <3
@Eric, vielen Dank für diesen Artikel, sehr informativ.
Beeindruckt zu sehen, dass IE10 Chrome schlägt und auch, wie alle IE8, IE9 und IE10 Chrome in den Microsoft.com-Tests schlagen. Ehrlich gesagt, die Auswahl von Microsoft.com als eine der Testseiten scheint eine sehr seltsame Wahl zu sein… IE8 und IE9 schlagen Chrome? Komm schon :p
Aber zurück zum Thema, meine persönliche Unzufriedenheit mit dieser ganzen "repetitiven Media Queries in der endgültigen Ausgabe"-Seifenoper ist nicht wirklich Performance, das wusste ich irgendwie schon (und die Zahlen in diesem Artikel bestätigen das). Es geht mehr um die Ästhetik der endgültigen CSS-Datei, besonders wenn ich an Studenten und andere Webdesigner/Frontend-Entwickler denke, die in diesem Geschäft anfangen, da sie meine hübsche SCSS-Datei(en) nicht sehen können, sondern nur die endgültige CSS-Datei. Ich denke, es ist einfach schwer zu verstehen, was dort wirklich vor sich geht. Es mag für Sie und mich offensichtlich sein, aber nicht unbedingt für Neulinge.
Außerdem mag ich es irgendwie nicht, mich an die Meinung von Sass halten zu müssen, wie ich meine SCSS kompilieren soll (ich weiß, wir haben verschiedene Ausgabe-Stile: verschachtelt, erweitert, kompakt und komprimiert, aber das ist ein anderes Thema). Es sollte eine Möglichkeit geben, so wie bei den von mir erwähnten Stilen, zu entscheiden, wie die Media Queries nach der Kompilierung in der endgültigen CSS-Datei erscheinen sollen.
Wenn ich ein Programmierer mit Rails-Kenntnissen wäre, würde ich das schon längst herausfinden. Aber das bin ich nicht. Pech gehabt.
Was Grunt betrifft, wurde mir das schon vorher gesagt und ich bin sicher, dass das der Fall ist, aber ich habe kein einfaches, "drittklässler-typisches" Tutorial gefunden, wie man es ausführt. Ich habe mehrmals versucht, es zum Laufen zu bringen, aber glauben Sie mir, die Tutorials, die ich gesehen habe, setzen voraus, dass Sie bereits viele andere Dinge/Konzepte kennen und verstehen, und da versagt Grunt.
Ich hatte vor einiger Zeit ein ähnliches Gefühl bei Sass, bis ich es selbst herausfinden konnte, aber es hat eine Weile gedauert. Dasselbe ist mir vor kurzem mit dem neuen Browser-Sync-Tool passiert, bis ich selbst herausfinden konnte, wie ich es installiere, während die Installationsanweisungen nicht klar waren und davon ausgingen: "Diese Anleitung setzt voraus, dass Sie Grunt bereits in einem Projekt installiert haben und wissen, wie man es benutzt." Ernsthaft. lol.
Und nein, ich habe es nicht mit Grunt installiert, da es das nicht braucht ¬¬
Schöner Beitrag Chris, ich lese deine Blog-Posts schon seit einiger Zeit – jedes Mal tolle Arbeit.
Ich habe gerade angefangen, mit der Methode von Nicolas Gallagher herumzuspielen. Es ist ie8/mobile-first. Nur 1 Stylesheet wird jemals vom Browser heruntergeladen. Es ist super, schau es dir an!
nicolasgallagher.com/mobile-first-css-sass-and-ie/
Ich liebe die Verwendung von SASS, es wird so viel Zeit sparen!
Sehr gut. SASS ist so praktisch und macht Spaß zu benutzen.
Toller Beitrag, Chris, wie immer. Ich habe etwas ziemlich Ähnliches gemacht. Ich habe eine verlinkte Liste für die Abfragen verwendet (werde dies wahrscheinlich irgendwann auf Standard- $variablen zurücksetzen) und auch Optionen zur Festlegung einer Standardansicht für Nicht-MQ-Geräte und eine Option zum Ein- / Ausschließen bestimmter Inhalte enthalten.
Dieser Artikel und einige der anderen Kommentare haben mir ein paar Ideen gegeben, die ich vielleicht untersuchen werde, um das Konzept weiter auszubauen, insbesondere in Bezug auf die modularen Media Queries und MQ-Pufferung.
Diese Technik funktioniert auch sehr gut für Retina.
Nur ein kleiner schneller Tipp ;-)
Ich lasse das hier mal stehen
http://breakpoint-sass.com/
https://github.com/lolmaus/breakpoint-slicer/
Der Weg der bedingten Kommentare ist der am häufigsten verwendete Weg, um mit IE's "schlechtem Ruf" umzugehen.
Wie viele gehen den Weg "Paul Irish's bedingte Kommentare im
<html>-Tag" (PICCHTW)?Hand gehoben! Ich bin noch nicht sehr erfahren mit Sass, daher bin ich mir nicht sicher, wie ich die HTML-Tag-Klassen in diesem Setup nutzen kann. Ich nehme an, etwas wie Chris Ruppels Lösung könnte für so etwas verwendet werden? So?
Um dies zu erhalten
Es erlaubt Ihnen nicht, Stile aus Media Queries selektiv anzuwenden, aber es würde Ihnen erlauben, einer bestimmten Version von IE alle Stile aus einer bestimmten Media Query zuzuführen, so dass sie mehr als nur die mobilen Stile erhält.
Aber wie gesagt, ich bin noch nicht sehr erfahren mit Sass, also sagen Sie mir bitte, ob das furchtbar oder einfach nur falsch geschriebenes Sass ist. :-)
@Zoe ja :)
Ich wollte IE nicht speziell in meinem Beispiel hervorheben, aber meistens ist meine
.no-mq-Klasse tatsächlich eine spezifische bedingte Klasse wie.lte-ie8@Zoe Ich denke tatsächlich, dass Chris Ruppels Mixin eine Möglichkeit ist, Stile sehr selektiv anzuwenden :) – Übrigens, ich sehe nichts Furchtbares oder Falsches an Ihrer Einschätzung, nur einen anderen Standpunkt.
Ich ziehe es vor, den "Pikachu"-Weg (PICCHTW) mit bedingten Klassen zu gehen, anstatt zusätzliche Dateien für IE zu verwenden (und zu verwalten). Und Chris Ruppels Mixin ist einfach FTW.
Vielleicht bin ich der Einzige, aber ich bevorzuge es stark, eine zentrale Sammlung von Media Queries zu haben, die jeweils ihre Breakpoint-spezifische SCSS-Datei laden. Der zusätzliche Vorteil ist, dass im mobilen-First-Setup das Erstellen für IE8 einfach das kumulative Ergebnis aller Stile ist. Jedem das Seine, würde ich sagen.
Mischen und Variablen für die Arbeit mit Media Queries
mediaquery.scss
Super funktioniert :)
Ich habe das in Index eingefügt
¨
und in style.css
@media screen and (min-width: 980px)
{
body{
height:100%;
}
}
Ich bin vielleicht etwas spät dran, aber beim Coden im Mobile-First-Ansatz UND bei der Unterstützung von ie8 war eine sehr einfache Lösung für mich
Mixin
Sass
Ausgabe CSS
Dies ist nur ein schnelles Beispiel, aber wie Sie sehen, wird, wenn Sie die Variable $ie8-support auf TRUE setzen, die zusätzliche Klasse .ie8 zur Desktop-Media-Query hinzugefügt. Wenn Sie sie auf FALSE setzen, fügt sie nichts hinzu. Funktioniert gut.
Codepen-Beispiel
http://codepen.io/thelifemgmt/pen/bKrdq?editors=010
Die Idee, 2 separate Stylesheets nur zur Unterstützung von IE8 zu haben, ergibt für mich keinen Sinn.
Auf jeden Fall… nur meine 2 Cents.