vars - ¿Hay una manera de importar variables de javascript a sass o viceversa?
como usar variables en css3 (7)
Estoy haciendo un sistema de css grid que se basa en el concepto de bloques. Así que tengo un archivo base como:
$max-columns: 4;
$block-width: 220px;
$block-height: 150px;
$block-margin: 10px;
Y es usado por 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;
}
Pero también me gustaría que javascript tenga acceso a las variables en el archivo base. Estaba pensando que podría hacer un div invisible, y darle los atributos $ block-width, $ block-height y $ block-margin y sacar los valores de allí. Pero max-column, no se asigna a nada directamente, por lo que tendría que encontrar una forma pirata de convertirlo en un div. ¿Hay una forma más limpia de compartir valores de sass / css a javascript o viceversa?
Considero que mi solución es bastante aburrida; pero funciona ...
En mi _base.scss
tengo algunas variables definidas:
$menu_bg: rgb(45, 45, 45);
$menu_hover: rgb(0, 0, 0);
En un menu.scss
tengo:
@import "base";
#jquery_vars {
.menu_bg {
background-color: $menu_bg;
}
.menu_hover {
background-color: $menu_hover;
}
}
Y en una útil plantilla de página:
<span class="is_hidden" id="jquery_vars">
<span class="is_hidden menu_bg"></span>
<span class="is_hidden menu_hover"></span>
</span>
Finalmente esto permite en un script jQuery cercano:
var menu_bg = $(''#jquery_vars .menu_bg'').css("background-color");
var menu_hover = $(''#jquery_vars .menu_hover'').css("background-color");
Esto es tan feo que mi papá lleva una bolsa en la cabeza.
jQuery puede extraer valores CSS arbitrarios de los elementos de la página; Pero esos elementos tienen que existir. Intenté extraer algunos de estos valores de CSS en bruto sin crear los tramos en el HTML y jQuery apareció undefined
. Obviamente, si estas variables se asignan a objetos "reales" en su página, realmente no necesita el elemento arbitrario #jquery_vars
. Al mismo tiempo, uno podría olvidar que .sidebar-left nice-menu li
es el elemento vital que se utiliza para alimentar variables a jQuery.
Si alguien tiene algo más, tiene que ser más limpio que esto ...
Esto se puede hacer usando gulp-sass-vars-to-js . Genera un archivo .js a partir de su archivo .scss. El archivo .js contiene todas las variables declaradas en su archivo .scss. Luego puedes ''requerir'' este js generado en tu .js
Me gustaría agregar que ahora hay varias formas de compartir datos entre Sass y JavaScript usando JSON. Aquí hay algunos enlaces a artículos que detallan varias técnicas:
- Haciendo que Sass hable a JavaScript con JSON
- SassyJSON: habla con el navegador
- Compartir datos entre Sass y JavaScript con JSON
Probablemente sea solo una cuestión de tiempo hasta que la importación JSON se admita de forma nativa en Sass.
Otra forma podría ser usar gulp-template para que pueda generar cualquier estructura que desee para su JavaScript.
Compartir variables entre Javascript y Sass usando Gulp con gulp-template https://youtu.be/UVeUq8gMYco
Se ha creado desde cero para que la gente pueda verlo desde cero y hay un git repo con el resultado final:
https://github.com/PocketNinjaCoUk/shared-js-sass-vars-using-gulp/tree/master/dev
Básicamente tienes tu objeto de configuración.
guardado en ./dev/config.js
module.exports = {
defaults: {
colours: {
primary: ''#fc0''
},
sizes: {
small: ''100px'',
medium: ''500px'',
large: ''1000px''
},
zIndex: {
model: 100,
dropdown: 50,
header: 10
}
}
}
Luego tienes ambas plantillas para Sass y Javascript, o menos o lo que quieras.
Plantilla de subrayado Sass
guardado en ./dev/templates/sass-config.txt
<% _.each(defaults, function(category, key) { %>
// Var <%= key %>
<% _.each(category, function(value, key) { %>
$<%= key %>: <%= value %>;
<% }) %>
<% }) %>
Plantilla de subrayado de Javascript
guardado en ./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++ %>
<% }); %>
};
<% }) %>
Luego el trago para compilarlo.
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''));
});
Puede leer el archivo sass con una secuencia de comandos del lado del servidor, "analizar" y hacer eco de los valores que necesita para JavaScript.
Recomendaría ver sass-extract que usa las características nativas de sass para extraer los valores de las variables computadas en JSON.
Además, si está utilizando el paquete web, sass-extract-loader hará que sea muy fácil solo requerir / importar los archivos sass como en const variables = require(''sass-extract-loader!./variables.scss'');
y tener sus variables sass en un objeto JSON agradable.
Como también es compatible con las declaraciones de @import
, aún puede separar sus variables en diferentes archivos, y no es necesario agregar preprocesamiento adicional o archivos json separados con variables.
Hay muchas formas alternativas de lograr esto, como se menciona en otras respuestas, y la que elija dependerá de su caso de uso y entorno.
Descargo de responsabilidad, soy el autor de las dos bibliotecas mencionadas.
Si usa un paquete web, puede usar sass-loader para exportar variables como:
$animation-length-ms: $animation-length + 0ms;
:export {
animationMillis: $animation-length-ms;
}
e importarlos como
import styles from ''../styles/animation.scss''
const millis = parseInt(styles.animationMillis)