SASS - использовать переменные в нескольких файлах

217

Я хотел бы сохранить один центральный файл .scss, в котором хранятся все определения переменных SASS для проекта.

// _master.scss 

$accent: #6D87A7;           
$error: #811702;
$warning: #F9E055;
$valid: #038144;
// etc... 

Проект будет иметь большое количество CSS-файлов, из-за его природы. Важно, чтобы я объявил все переменные стиля проекта в одном месте.

Есть ли способ сделать это в SCSS?

dthree
источник
Я почти уверен, что это невозможно, я пробовал то же самое некоторое время назад и не мог заставить его работать.
DrCord
8
@DrCord, наоборот, является центральным элементом SASS: sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#partials
Ennui
Сладкий! Я думаю, что, возможно, неправильно прочитал это утверждение: «Директивы, которые разрешены только на базовом уровне документа, такие как mixin или charset, недопустимы в файлах, которые импортированы во вложенном контексте». и не правильно читать часть «вложенного контекста».
DrCord

Ответы:

325

Вы можете сделать это так:

У меня есть папка с именем утилиты и внутри нее у меня есть файл с именем _variables.scss

в этом файле я объявляю переменные так:

$black: #000;
$white: #fff;

тогда у меня есть файл style.scss, в который я импортирую все мои другие файлы scss, как это:

// Utilities
@import "utilities/variables";

// Base Rules
@import "base/normalize";
@import "base/global";

затем в любом из импортированных мной файлов я смогу получить доступ к объявленным мной переменным.

Просто убедитесь, что вы импортируете файл переменной, прежде чем любой другой, в котором вы хотели бы использовать его.

Joel
источник
4
Отлично. Как раз то, что я имел в виду и нуждалось. Последний вопрос: все ли импортируемые файлы должны начинаться с подчеркивания? Вы подчеркиваете свое имя файла, но не можете в объявлениях @import.
три
46
эти файлы считаются частичными, и имена должны начинаться с подчеркивания, хотя вы и пропускаете его при импорте. есть действительно хорошая статья, которая подробно объясняет, почему здесь: alistapart.com/article/getting-started-with-sass
Джоэл
7
Обратите внимание , что вы можете объявить по умолчанию в ваших модулях: $black: #000 !default;. !defaultШтучка предотвращает переменную из сбрасывается , если он уже существует.
Андрей Михайлов - lolmaus
2
Почему мы должны записать все переменные в один файл? Разве мы не можем разделить и поместить их в соответствующий файл, который им нужен? Например, переменные, необходимые для модального диалога, не можем ли мы поместить их в _modal.scss?
VJAI
3
Этот ответ больше не является рекомендуемым способом повторного использования переменных в нескольких файлах. Пожалуйста, смотрите stackoverflow.com/a/61500282/7513192
whiscode
82

Этот ответ показывает, как я в конечном итоге воспользовался этим и какими дополнительными ловушками я столкнулся.

Я сделал основной файл SCSS. Этот файл должен иметь подчеркивание в начале, чтобы импортировать его:

// assets/_master.scss 
$accent: #6D87A7;           
$error: #811702;

Затем в заголовке всех других моих файлов .SCSS я импортирую мастер:

// When importing the master, you leave out the underscore, and it
// will look for a file with the underscore. This prevents the SCSS
// compiler from generating a CSS file from it.
@import "assets/master";

// Then do the rest of my CSS afterwards:
.text { color: $accent; }

ВАЖНЫЙ

Не включайте ничего, кроме переменных, объявлений функций и других функций SASS в ваш _master.scssфайл. Если вы включите фактический CSS, он будет дублировать этот CSS во всех файлах, в которые вы импортируете мастер.

dthree
источник
5
Большое спасибо за ваш комментарий о том, что файл должен начинаться с подчеркивания! Я просто потратил около 3 часов, пытаясь выяснить, почему я скучал по куче стилей Foundation. Изменили имя файла моего файла настроек Foundation, чтобы начать с подчеркивания и эй presto! Но теперь, когда я снова изменяю имя файла, оно все еще работает? Что за....? Ну да ладно ... Вздыхает и принимает, что теперь работает
пошагнесси
4
Не меняйте его обратно - он, вероятно, «отрабатывает» некий сгенерированный CSS из вашего файла SCSS, когда он работал. Просто используйте подчеркивание. Но в остальном, здорово, чтобы это заработало!
три
@poshaughnessy это может сработать, потому что sass использует кеш, поэтому его можно кэшировать. Не уверен на 100%.
PeterM
то же самое для дерзких ??
Martian2049
1
Правильно, ты @rinogo.
3
20

Этот вопрос задавался очень давно, поэтому я решил опубликовать обновленный ответ.

Теперь вы должны избегать использования @import. Взято из документов:

Sass постепенно прекратит его использование в течение следующих нескольких лет и в конечном итоге полностью удалит его из языка. Вместо этого предпочитайте правило @use.

Полный список причин можно найти здесь

Вы должны теперь использовать @use как показано ниже:

_variables.scss

$text-colour: #262626;

_otherFile.scss

@use 'variables'; // Path to _variables.scss Notice how we don't include the underscore or file extension

body {
  // namespace.$variable-name
  // namespace is just the last component of its URL without a file extension
  color: variables.$text-colour;
}

Вы также можете создать псевдоним для пространства имен:

_otherFile.scss

@use 'variables' as v;

body {
  // alias.$variable-name
  color: v.$text-colour;
}
whiscode
источник
1
Теперь это должен быть выбранный ответ, так как «импорт» помечен как устаревший и будет удален в будущем.
TyrionGraphiste
Это нужно больше upvotes
Людовико
3

Создайте index.scss и там вы сможете импортировать всю имеющуюся у вас структуру файла. Я вставлю вам свой индекс из корпоративного проекта, может быть, он поможет другим, как структурировать файлы в CSS:

@import 'base/_reset';

@import 'helpers/_variables';
@import 'helpers/_mixins';
@import 'helpers/_functions';
@import 'helpers/_helpers';
@import 'helpers/_placeholders';

@import 'base/_typography';

@import 'pages/_versions';
@import 'pages/_recording';
@import 'pages/_lists';
@import 'pages/_global';

@import 'forms/_buttons';
@import 'forms/_inputs';
@import 'forms/_validators';
@import 'forms/_fieldsets';

@import 'sections/_header';
@import 'sections/_navigation';
@import 'sections/_sidebar-a';
@import 'sections/_sidebar-b';
@import 'sections/_footer';

@import 'vendors/_ui-grid';

@import 'components/_modals';
@import 'components/_tooltip';
@import 'components/_tables';
@import 'components/_datepickers';

И вы можете смотреть их с gulp / grunt / webpack и т. Д., Например:

gulpfile.js

// Задача SASS

var gulp = require('gulp');
var sass = require('gulp-sass');
//var concat = require('gulp-concat');
var uglifycss = require('gulp-uglifycss');
var sourcemaps = require('gulp-sourcemaps');

gulp.task('styles', function(){
    return gulp
            .src('sass/**/*.scss')
            .pipe(sourcemaps.init())
            .pipe(sass().on('error', sass.logError))
            .pipe(concat('styles.css'))
            .pipe(uglifycss({
                "maxLineLen": 80,
                "uglyComments": true
            }))
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest('./build/css/'));
});

gulp.task('watch', function () {
    gulp.watch('sass/**/*.scss', ['styles']);
});

gulp.task('default', ['watch']);
Карнару Валентин
источник
1
Разве вы не должны опускать подчеркивание в выражениях @import?
Quantum7
1
Sass @import работает в любом случае. Вы можете написать URI с подчеркиванием или без него. также с или без окончания .scss.
Пони
1

Как насчет записи некоторого цветового класса в глобальный файл sass, поэтому нам не нужно заботиться о том, где находятся переменные. Так же, как следующее:

// base.scss 
@import "./_variables.scss";

.background-color{
    background: $bg-color;
}

и тогда мы можем использовать background-colorкласс в любом файле. Я хочу variable.scssсказать, что мне не нужно импортировать файлы, просто используйте их.

Гари Гао
источник
Очевидно, что это плохая идея, у вас может быть много переменных, и он более чист, чтобы вести индекс только с импортом, и каждый файл, который нужно иметь, является собственным предложением.
Карнару Валентин