web-dev-qa-db-fra.com

Est-il possible d'importer des variables de javascript vers sass ou inversement?

Je crée un système de grille css qui repose sur le concept de blocs. J'ai donc un fichier de base comme:

$max-columns: 4;
$block-width: 220px;
$block-height: 150px;
$block-margin: 10px;

Et il est utilisé par un mixin:

@mixin block ($rows, $columns, $max-columns) {
  display: block;
  float: left;
  margin: $block-margin 0 0 $block-margin;
  box-sizing: border-box;
  width: ($block-width * $columns) - $block-margin;
}

Mais j'aimerais aussi que javascript ait accès aux variables du fichier de base. Je pensais pouvoir créer un div invisible et lui attribuer les attributs $ block-width, $ block-height et $ block-margin et en extraire les valeurs. Mais max-columns, ne mappe rien directement, il faudrait donc que je trouve un moyen hacky de le rendre en div. Existe-t-il un moyen plus simple de partager les valeurs de sass/css vers javascript ou vice versa?

20
Jeremy Smith

Vous pouvez lire le fichier sass avec un script côté serveur, le "analyser" et faire écho aux valeurs que vous devez javascript.

6
Corubba

Je considère ma solution assez hokey; Mais, il fonctionne...

Dans mon _base.scss, certaines variables sont définies:

$menu_bg: rgb(45, 45, 45);
$menu_hover: rgb(0, 0, 0);

Dans un menu.scss j'ai:

@import "base";

#jquery_vars {
  .menu_bg {
    background-color: $menu_bg;
  }
  .menu_hover {
    background-color: $menu_hover;
  }
}

Et dans un modèle de page pratique:

<span class="is_hidden" id="jquery_vars">
  <span class="is_hidden menu_bg"></span>
  <span class="is_hidden menu_hover"></span>
</span>

Enfin, cela permet dans un script jQuery proche:

var menu_bg = $('#jquery_vars .menu_bg').css("background-color");
var menu_hover = $('#jquery_vars .menu_hover').css("background-color");

C'est si moche que mon père porte un sac sur la tête.

jQuery peut extraire des valeurs CSS arbitraires à partir d'éléments de page; mais ces éléments doivent exister. J'ai essayé d'extraire certaines de ces valeurs du CSS brut sans créer les étendues dans le code HTML et jQuery a créé undefined. Évidemment, si ces variables sont affectées à des objets "réels" sur votre page, vous n'avez pas vraiment besoin de l'élément #jquery_vars arbitraire. En même temps, on peut oublier que .sidebar-left Nice-menu li est l’élément vital utilisé pour alimenter des variables en jQuery.

Si quelqu'un a autre chose, il doit être plus propre que ça ...

10
ericx

Je recommanderais de regarder sass-extract qui utilise les fonctionnalités sass natives afin d’extraire les valeurs des variables calculées en JSON.

De même, si vous utilisez Webpack, le fichier sass-extract-loader facilitera l'import/importation des fichiers sass comme dans const variables = require('sass-extract-loader!./variables.scss'); et que vos variables sass se trouvent dans un objet JSON de Nice.

Etant donné qu’il prend également en charge les instructions @import, vous pouvez toujours séparer vos variables dans des fichiers différents, sans avoir à ajouter de prétraitement supplémentaire ni à séparer les fichiers json avec les variables.

Comme indiqué dans d’autres réponses, il existe de nombreuses manières d’y parvenir, et celle que vous choisirez dépendra de votre cas d'utilisation et de votre environnement.

Déni de responsabilité, je suis l'auteur des deux bibliothèques mentionnées.

4
jgranstrom

Je voudrais ajouter qu'il existe maintenant plusieurs façons de partager des données entre Sass et JavaScript à l'aide de JSON. Voici quelques liens vers des articles détaillant diverses techniques:

Ce n'est probablement qu'une question de temps avant que l'importation JSON soit prise en charge de manière native dans Sass.

4
Teo Dragovic

Si vous utilisez webpack, vous pouvez utiliser sass-loader pour exporter des variables telles que:

$animation-length-ms: $animation-length + 0ms;

:export {
  animationMillis: $animation-length-ms;
}

et les importer comme

import styles from '../styles/animation.scss'    
const millis = parseInt(styles.animationMillis)

https://blog.bluematador.com/posts/how-to-share-variables-between-js-and-sass/

2
velop

Une autre solution consiste à utiliser gulp-template afin de générer la structure de votre choix pour JavaScript.

Partage de variables entre Javascript et Sass à l'aide de Gulp avec gulp-template https://youtu.be/UVeUq8gMYco

Il a été créé à partir de zéro pour que les gens puissent le voir de fond en comble et il existe un dépôt git avec le résultat final:

https://github.com/PocketNinjaCoUk/shared-js-sass-vars-using-gulp/tree/master/dev

Vous avez essentiellement votre objet de configuration

enregistré à ./dev/config.js

module.exports = {
  defaults: {
    colours: {
      primary: '#fc0'
    },
    sizes: {
      small: '100px',
      medium: '500px',
      large: '1000px'
    },
    zIndex: {
      model: 100,
      dropdown: 50,
      header: 10
    }
  }
}

Ensuite, vous avez vos deux modèles pour Sass et Javascript, ou moins ou ce que vous voulez.

Modèle de soulignement Sass

enregistré à ./dev/templates/sass-config.txt

<% _.each(defaults, function(category, key) { %>
  // Var <%= key %>
  <% _.each(category, function(value, key) { %>
    $<%= key %>: <%= value %>;
  <% }) %>
<% }) %>

Modèle de soulignement Javascript

enregistré à ./dev/templates/js-config.txt

namespace.config = {};

<% _.each(defaults, function(monkey, key) { %>
  namespace.config.<%= key %> = {
  <% i = 1 %>
  <% _.each(monkey, function(value, key) { %>
    <% comma = (Object.keys(monkey).length === i) ? '': ',' %>
    <% if(typeof value === 'string') {%>
      <%= key %>: '<%= value %>'<%= comma %>
    <%} else { %>
      <%= key %> : <%= value %><%= comma %>
    <% } %>
    <% i++ %>
  <% }); %>
  };
<% }) %>

Puis la bouchée pour le compiler

var gulp = require('gulp');
var template = require('gulp-template');
var rename = require('gulp-rename');
var removeEmptyLines  = require('gulp-remove-empty-lines');

var sharedVars = require('./dev/config');

gulp.task('compile', function() {
  gulp.src('./dev/templates/sass-config.txt')
    .pipe(template(sharedVars))
    .pipe(rename('_sass-config.scss'))
    .pipe(removeEmptyLines())
    .pipe(gulp.dest('./dev/sass'));

  gulp.src('./dev/templates/js-config.txt')
    .pipe(template(sharedVars))
    .pipe(rename('js-config.js'))
    .pipe(removeEmptyLines())
    .pipe(gulp.dest('./dev/js'));
});
1
Pocketninja

Cela peut être fait en utilisant gulp-sass-vars-to-js . Il génère un fichier .js à partir de votre fichier .scss. Le fichier .js contient toutes les variables déclarées dans votre fichier .scss. Vous pouvez ensuite "exiger" ce js généré dans votre fichier .js

0
user2486738