讓 JavaScript 與 CSS 和 Sass 對話

做者:Marko Ilic

翻譯:瘋狂的技術宅javascript

原文:https://css-tricks.com/gettin...css

未經容許嚴禁轉載前端

JavaScript 和 CSS 已經並存超過了 20 年。可是在它們之間共享數據很是困難。固然也有大量的嘗試。可是我所想到的是一些簡單而直觀的內容——不涉及結構更改,而是使用 CSS 自定義屬性甚至 Sass 變量。java

CSS 自定義屬性和 JavaScript

自定義屬性在這裏應該不會使人感到驚訝。自瀏覽器提供支持以來​​,他們一直在作的一件事就是與 JavaScript 協同工做以設置和操做值webpack

不過具體來講,咱們能夠經過幾種方式使 JavaScript 與自定義屬性一塊兒工做。可使用 setProperty 設置自定義屬性的值:程序員

document.documentElement.style.setProperty("--padding", 124 + "px"); // 124px

咱們還能夠用 JavaScript 中的 getComputedStyle 來檢索 CSS 變量。其背後的邏輯很是簡單:自定義屬性是樣式的一部分,所以它們是計算樣式的一部分。web

getComputedStyle(document.documentElement).getPropertyValue('--padding') // 124px

getPropertyValue 同樣。這樣咱們就能夠從 HTML 標記的內聯樣式中得到自定義屬性值。面試

document.documentElement.style.getPropertyValue("--padding'"); // 124px

請注意,自定義屬性是有做用域的。這意味着咱們須要從特定元素獲取計算樣式。正如咱們以前在:root 中定義變量同樣,咱們將它們放在 HTML 元素上。json

Sass 變量和 JavaScript

Sass 是一種預處理語言,這意味着它在成爲網站的一部分以前就已經變成了 CSS。因此沒法用與 CSS 自定義屬性相同的方式從 JavaScript 訪問它們(能夠在 DOM 中以計算樣式訪問它們)。segmentfault

咱們須要經過修改本身的構建過程來改變這一點。我懷疑在大多數狀況下並不須要作太多,由於裝載程序一般已是構建過程的一部分。可是若是你的項目並不是如此,則咱們須要三個模塊,這些模塊可以導入和翻譯 Sass 模塊。

在 Webpack 配置中看上去是這樣:

module.exports = {
 // ...
 module: {
  rules: [
   {
    test: /\.scss$/,
    use: ["style-loader", "css-loader", "sass-loader"]
   },
   // ...
  ]
 }
};

爲了使 Sass(或者在這種狀況下,具體來講是 SCSS)變量可用於 JavaScript,咱們須要 「export」 它們。

// variables.scss
$primary-color: #fe4e5e;
$background-color: #fefefe;
$padding: 124px;

:export {
  primaryColor: $primary-color;
  backgroundColor: $background-color;
  padding: $padding;
}

:export 塊是 webpack 用來導入變量的。這種方法的好處是,咱們能夠用 camelCase 語法重命名變量,而後選擇要公開的內容。

而後,把 Sass 文件(variables.scss)導入 JavaScript,從而能夠訪問文件中定義的變量。

import variables from './variables.scss';

/*
 {
  primaryColor: "#fe4e5e"
  backgroundColor: "#fefefe"
  padding: "124px"
 }
*/

document.getElementById("app").style.padding = variables.padding;

值得一提的是對 :export 語法的一些限制:

  • 它必須在頂層,但能夠在文件中的任何位置。
  • 若是文件中有多個,則將 key 和 value 組合在一塊兒一併導出。
  • 若是特定的 exportedKey 被複制,則最後一個(按源順序)優先。
  • exportedValue 能夠含有在 CSS 聲明值中任何有效的字符(包括空格)。
  • exportedValue 不須要被引用,由於它已經被看成文本字符串了。

有不少方法能夠方便地訪問 JavaScript 中的 Sass 變量。我傾向於使用這種共享斷點的方法。下面是個人breakpoints.scs 文件,後來我將其導入 JavaScript 中,這樣我能夠用 matchMedia()方法獲得一致的斷點。

// Sass variables that define breakpoint values
$breakpoints: (
  mobile: 375px,
  tablet: 768px,
  // etc.
);

// Sass variables for writing out media queries
$media: (
  mobile: '(max-width: #{map-get($breakpoints, mobile)})',
  tablet: '(max-width: #{map-get($breakpoints, tablet)})',
  // etc.
);

// The export module that makes Sass variables accessible in JavaScript
:export {
  breakpointMobile: unquote(map-get($media, mobile));
  breakpointTablet: unquote(map-get($media, tablet));
  // etc.
}

動畫是另外一個用例。動畫的持續時間一般存儲在 CSS 中,可是須要 JavaScript 的幫助才能完成更復雜的動畫。

// animation.scss
$global-animation-duration: 300ms;
$global-animation-easing: ease-in-out;

:export {
  animationDuration: strip-unit($global-animation-duration);
  animationEasing: $global-animation-easing;
}

請注意,在導出變量時,我用了自定義 strip-unit 函數。這使我能夠輕鬆地在 JavaScript 中解析內容。

// main.js
document.getElementById('image').animate([
  { transform: 'scale(1)', opacity: 1, offset: 0 },
  { transform: 'scale(.6)', opacity: .6, offset: 1 }
], {
  duration: Number(variables.animationDuration),
  easing: variables.animationEasing,
});


這樣就能輕鬆地在CSS、Sass 和 JavaScript 之間交換數據。共享這樣的變量使代碼簡單而不囉嗦。

固然還有多種方法能夠實現相同的目的。 Les James 分享了一種有趣的方法,該方法容許 Sass 和 JavaScript 經過 JSON 進行交互。我對此可能存有偏見,可是我發如今這裏介紹的方法是最簡單、最直觀的。無需對你已經在使用和正在編寫的 CSS 和 JavaScript 進行瘋狂的修改。


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索