webentwicklung-frage-antwort-db.com.de

Verwenden von Sass-Variablen mit CSS3-Medienabfragen

Ich versuche, die Verwendung einer Sass-Variablen mit @media-Abfragen wie folgt zu kombinieren:

$base_width:1160px;

@media screen and (max-width: 1170px) {$base_width: 960px;}
@media screen and (min-width: 1171px) {$base_width: 1160px;}

$base_width Wird dann an verschiedenen Stellen in den prozentbasierten Messungen der Stylesheet-Breite definiert, um flüssige Layouts zu erstellen.

Wenn ich das mache, scheint die Variable richtig erkannt zu werden, aber die Bedingungen für die Medienabfrage sind nicht. Mit dem obigen Code wird beispielsweise ein 1160-Pixel-Layout unabhängig von der Bildschirmbreite erstellt. Wenn ich die @ media-Anweisungen wie folgt umklappe:

@media screen and (min-width: 1171px) {$base_width: 1160px;}
@media screen and (max-width: 1170px) {$base_width: 960px;}

Es wird unabhängig von der Bildschirmbreite ein 960px-Layout erstellt. Beachten Sie auch, dass, wenn ich die erste Zeile von $base_width: 1160px; Entferne, ein Fehler für eine undefinierte Variable zurückgegeben wird. Irgendwelche Ideen, was mir fehlt?

87
Jeremy S.

Das ist einfach nicht möglich. Da der Trigger @media screen and (max-width: 1170px) auf der Client-Seite passiert.

Das Erreichen des erwarteten Ergebnisses wäre nur möglich, wenn SASS alle Regeln und Eigenschaften in Ihrem Stylesheet mit Ihrer Variablen $base_width Erfasst und entsprechend kopiert/geändert hätte.

Da es nicht automatisch funktioniert, können Sie es von Hand so machen:

@media screen and (max-width: 1170px)
      $base_width: 960px // you need to indent it to (re)set it just within this media-query
      // now you copy all the css rules/properties that contain or are relative to $base_width e.g.
      #wrapper
          width: $base_width
          ...

@media screen and (min-width: 1171px)
    $base_width: 1160px
      #wrapper
          width: $base_width
          ...

Dies ist nicht wirklich DRY aber das Beste, was Sie tun können.

Wenn die Änderungen jedes Mal gleich sind, können Sie auch ein Mixin mit allen sich ändernden Werten vorbereiten, sodass Sie es nicht wiederholen müssen. Zusätzlich können Sie versuchen, das Mixin mit bestimmten Änderungen zu kombinieren. Mögen:

@media screen and (min-width: 1171px)
    +base_width_changes(1160px)
    #width-1171-specific-element // additional specific changes, that aren't in the mixin
        display: block

Und das Mixin würde so aussehen

=base_width_changes($base_width)
    #wrapper
        width: $base_width
80
woerndl

Ähnlich wie bei Philipp Zedler kann man das mit einem Mixin machen. So haben Sie alles in einer einzigen Datei, wenn Sie möchten.

@mixin styling($base-width) {
    // your SCSS here, e.g.
    #Contents {
        width: $base-width;
    }
}

@media screen and (max-width: 1170px) {
    @include styling($base-width: 960px);
}
@media screen and (min-width: 1171px) {
    @include styling($base-width: 1160px);
}
39
ronen

Edit: Bitte verwenden Sie diese Lösung nicht. Die Antwort von Ronen ist viel besser.

Als DRY Lösung können Sie das @import Anweisung innerhalb einer Medienabfrage, z. so was.

@media screen and (max-width: 1170px) {
    $base_width: 960px;
    @import "responsive_elements";
}
@media screen and (min-width: 1171px) {
    $base_width: 1160px;
    @import "responsive_elements";
}

Sie definieren alle ansprechenden Elemente in der enthaltenen Datei mithilfe der in der Medienabfrage definierten Variablen. Alles, was Sie wiederholen müssen, ist die import-Anweisung.

6
Philipp Zedler

Ich hatte das gleiche problem.

Die Variable $menu-width Sollte in der Ansicht mobil@media only screen and (max-width : 768px) 240px und in der Ansicht desktop 340px betragen.

Also habe ich einfach zwei Variablen erstellt:

$menu-width: 340px;
$menu-mobile-width: 240px;

Und so habe ich es benutzt:

.menu {
    width: $menu-width;
    @media only screen and (max-width : 768px) {
      width: $menu-mobile-width;
    }
}
2
Dawid Dyrcz

Dies ist mit SASS nicht möglich, aber mit CSS-Variablen (oder benutzerdefinierte CSS-Eigenschaften ). Der einzige Nachteil ist die Browserunterstützung - aber es gibt tatsächlich ein PostCSS-Plugin - postcss-css-variables - das die Verwendung von CSS-Variablen "vereinfacht" (wodurch Sie auch ältere Browser unterstützen).

Das folgende Beispiel funktioniert hervorragend mit SASS (und mit postcss-css-Variablen werden auch ältere Browser unterstützt).

$mq-laptop: 1440px;
$mq-desktop: 1680px;

:root {
    --font-size-regular: 14px;
    --Gutter: 1rem;
}

// The fact that we have to use a `max-width` media query here, so as to not
// overlap with the next media query, is a quirk of postcss-css-variables
@media (min-width: $mq-laptop) and (max-width: $mq-desktop - 1px) {
    :root {
        --font-size-regular: 16px;
        --Gutter: 1.5rem;
    }
}

@media (min-width: $mq-desktop) {
    :root {
        --font-size-regular: 18px;
        --Gutter: 1.75rem;
    }
}

.my-element {
    font-size: var(--font-size-regular);
    padding: 0 calc(var(--Gutter) / 2);
}

Dies würde zu folgendem CSS führen. Die wiederholten Medienabfragen erhöhen die Dateigröße, aber ich habe festgestellt, dass die Erhöhung normalerweise vernachlässigbar ist, sobald der Webserver gzip anwendet (was normalerweise automatisch geschieht).

.my-element {
  font-size: 14px;
  padding: 0 calc(1rem / 2);
}
@media (min-width: 1680px) {
  .my-element {
  padding: 0 calc(1.75rem / 2);
  }
}
@media (min-width: 1440px) and (max-width: 1679px) {
  .my-element {
  padding: 0 calc(1.5rem / 2);
  }
}
@media (min-width: 1680px) {
  .my-element {
  font-size: 18px;
  }
}
@media (min-width: 1440px) and (max-width: 1679px) {
  .my-element {
  font-size: 16px;
  }
}
2
fredrikekelund

Mit @ ronens großartige Antwort und einer Karte steht einige echte Kraft zur Verfügung:

@mixin styling($map) {
    .myDiv {
        background: map-get($map, 'foo');
        font-size: map-get($map, 'bar');
    }
}

@media (min-height: 500px) {
    @include styling((
        foo: green,
        bar: 50px
    ));
}

@media (min-height: 1000px) {
    @include styling((
        foo: red,
        bar: 100px
    ));
}

Es ist jetzt möglich, viel mehr DRY Media-Abfragen für .myDiv mit ein paar verschiedenen Werten.


Kartendokumente: https://sass-lang.com/documentation/functions/map

Beispiel für die Verwendung einer Karte: https://www.sitepoint.com/using-sass-maps/

1
Ben