web-dev-qa-db-fra.com

Structure d'actif SCSS appropriée dans Rails

J'ai donc une structure de répertoire app/assets/stylesheets/ Qui ressemble à ceci:

   |-dialogs
   |-mixins
   |---buttons
   |---gradients
   |---vendor_support
   |---widgets
   |-pages
   |-structure
   |-ui_elements

Dans chaque répertoire, il y a plusieurs partiels sass (habituellement * .css.scss, mais un ou deux * .css.scss.erb).

Je suppose peut-être beaucoup, mais Rails DEVRAIT compiler automatiquement tous les fichiers de ces répertoires à cause de *= require_tree . Dans application.css, n'est-ce pas?

J'ai récemment essayé de restructurer ces fichiers en supprimant toutes les variables de couleur et en les plaçant dans un fichier du dossier racine app/assets/stylesheets (_Colors.css.scss). J'ai ensuite créé un fichier dans le dossier racine app/assets/stylesheets Appelé master.css.scss qui ressemble à ceci:

// Color Palette 
@import "colors";

// Mixins
@import "mixins/buttons/standard_button";
@import "mixins/gradients/table_header_fade";
@import "mixins/vendor_support/rounded_corners";
@import "mixins/vendor_support/rounded_corners_top";
@import "mixins/vendor_support/box_shadow";
@import "mixins/vendor_support/opacity";

Je ne comprends pas vraiment comment Rails gère l'ordre de compilation des actifs, mais ce n'est évidemment pas en ma faveur. il jette des erreurs et je ne peux pas compiler.

Undefined variable: "$dialog_divider_color".
  (in /home/blah/app/assets/stylesheets/dialogs/dialog.css.scss.erb)

Undefined mixin 'rounded_corners'.
  (in /home/blah/app/assets/stylesheets/widgets.css.scss)

La variable $dialog_divider_color Est clairement définie dans _colors.css.scss, et _master.css.scss Importe les couleurs et tous mes mixins. Mais apparemment Rails n'a pas reçu ce mémo.

Existe-t-il un moyen de corriger ces erreurs ou devrai-je recourir à la réintégration de toutes mes définitions de variables dans chaque fichier, ainsi que toutes les importations mixin?

Malheureusement, ce type ne semble pas penser que c'est possible, mais j'espère qu'il se trompe. Toutes les pensées sont grandement appréciées.

81
David Savage

Le problème avec CSS est que vous ne voulez pas ajouter automatiquement tous les fichiers. L'ordre dans lequel vos feuilles sont chargées et traitées par le navigateur est essentiel. Donc, vous finirez toujours par importer explicitement tous vos css.

Par exemple, disons que vous avez une feuille normalize.css , pour obtenir un aspect par défaut à la place de toutes les horribles mises en œuvre de navigateur. Cela devrait être le premier fichier chargé par le navigateur. Si vous incluez simplement cette feuille de manière aléatoire quelque part dans vos importations css, elle ne remplacera donc pas uniquement les styles par défaut du navigateur, mais également tous les styles définis dans tous les fichiers css chargés auparavant. Cela va de même pour les variables et les mixins.

Après avoir vu une présentation de Roy Tomeij à Euruko2012, j’ai choisi l’approche suivante si vous avez beaucoup de CSS à gérer.

J'utilise généralement cette approche:

  1. Renommez tous les fichiers .css existants en .scss
  2. Supprimer tout le contenu de application.scss

Commencez à ajouter les directives @import à application.scss.

Si vous utilisez des twitters bootstrap et quelques feuilles css de votre choix, vous devez importer bootstrap d'abord car il comporte une feuille pour réinitialiser les styles. Donc vous ajoutez @import "bootstrap/bootstrap.scss"; à votre application.scss.

Le fichier bootstrap.scss se présente comme suit:

// CSS Reset
@import "reset.scss";

// Core
@import "variables.scss";
@import "mixins.scss";

// Grid system and page structure
@import "scaffolding.scss";

// Styled patterns and elements
@import "type.scss";
@import "forms.scss";
@import "tables.scss";
@import "patterns.scss";

Et votre fichier application.scss Ressemble à ceci:

@import "bootstrap/bootstrap.scss";

En raison de l'ordre des importations, vous pouvez maintenant utiliser les variables, chargées avec @import "variables.scss"; Dans tout autre fichier .scss Importé après celle-ci. Ils peuvent donc être utilisés dans type.scss Dans le dossier bootstrap mais également dans my_model.css.scss.

Après cela, créez un dossier nommé partials ou modules. Ce sera la place de la plupart des autres fichiers. Vous pouvez simplement ajouter l'importation dans le fichier application.scss Pour qu'il ressemble à ceci:

@import "bootstrap/bootstrap.scss";
@import "partials/*";

Maintenant, si vous faites un peu de css pour styler un article sur votre page d'accueil. Créez simplement partials/_article.scss Et il sera ajouté à la compilation application.css. En raison de l'ordre d'importation, vous pouvez également utiliser n'importe quel bootstrap) mixins et variables dans vos propres fichiers scss.

Le seul inconvénient de cette méthode que j’ai trouvée jusqu’à présent est qu’il faut parfois forcer une recompilation des fichiers partiels/*. Scss car Rails ne le fera pas toujours pour vous.

123

Créez la structure de dossiers suivante:

+ assets
|
--+ base
| |
| --+ mixins (with subfolders as noted in your question)
|
--+ styles
  |
  --+ ...

Dans le dossier base créez un fichier "globals.css.scss". Dans ce fichier, déclarez toutes vos importations:

@import 'base/colors';
@import 'base/mixins/...';
@import 'base/mixins/...';

Dans votre application.css.scss, vous devriez alors avoir:

*= require_self
*= depends_on ./base/globals.css.scss
*= require_tree ./styles

Et comme dernière étape (c'est important), déclarez @import 'base/globals' dans chaque fichier de style dans lequel vous souhaitez utiliser des variables ou des mixins. Vous pouvez envisager cette surcharge, mais j'aime bien l'idée de devoir déclarer les dépendances de vos styles dans chaque fichier. Bien sûr, il est important que vous importiez uniquement des mixins et des variables dans le fichier globals.css.scss car ils n’ajoutent pas de définitions de style. Sinon, les définitions de style seraient incluses plusieurs fois dans votre fichier précompilé ...

7
emrass

pour utiliser des variables, entre autres, vous devez utiliser la directive @import. les fichiers sont importés dans l'ordre spécifié.

ensuite, utilisez application.css pour exiger le fichier qui déclare les importations. C'est le moyen d'obtenir le contrôle que vous voulez.

enfin, dans votre fichier layout.erb, vous pouvez spécifier quel fichier css "maître" utiliser

exemple sera plus utile:

disons que vous avez deux modules dans votre application qui nécessitent différents ensembles de CSS: "application" et "admin"

les fichiers

|-app/
|-- assets/
|--- stylesheets/
|     // the "master" files that will be called by the layout
|---- application.css
|---- application_admin.css
|
|     // the files that contain styles
|---- config.scss
|---- styles.scss
|---- admin_styles.scss
|
|     // the files that define the imports
|---- app_imports.scss
|---- admin_imports.scss
|
|
|-- views/
|--- layouts/
|---- admin.html.haml
|---- application.html.haml

voici à quoi ressemblent les fichiers à l'intérieur:

-------- THE STYLES

-- config.scss
// declare variables and mixins
$font-size: 20px;

--  app_imports.scss
// using imports lets you use variables from `config` in `styles`
@import 'config'
@import 'styles'

-- admin_imports.scss
// for admin module, we import an additional stylesheet
@import 'config'
@import 'styles'
@import 'admin_styles'

-- application.css
// in the master application file, we require the imports
*= require app_imports
*= require some_other_stylesheet_like_a_plugin
*= require_self

-- application_admin.css
// in the master admin file, we require the admin imports
*= require admin_imports
*= require some_other_stylesheet_like_a_plugin
*= require_self


-------- THE LAYOUTS

-- application.html.haml
// in the application layout, we call the master css file
= stylesheet_link_tag "application", media: "all"

--  admin.html.haml
// in the admin layout, we call the admin master css file
= stylesheet_link_tag "application_admin", media: "all"
7
Doug Lee

Selon cette question , vous pouvez [~ # ~] seulement [~ # ~] utiliser application.css.sass afin de définir les variables d'importation et de partage entre vos modèles.

=> Cela ne semble être qu'une question de nom.

Un autre moyen peut être de tout inclure et désactiver ce pipeline .

3
Coren

J'ai eu un problème très similaire. Ce qui m'a aidé, c’est de souligner le caractère souligné de la déclaration @import lors de l’importation du partiel. Alors

@import "_base";

au lieu de

@import "base";

Cela pourrait être un bug étrange ...

1
Bernát