Estructura de activos SCSS adecuada en Rails

Entonces, tengo una estructura de directorio de app/assets/stylesheets/ que se parece a esto:

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

En cada directorio, hay varios parciales sass (generalmente * .css.scss, pero uno o dos * .css.scss.erb).

Podría estar asumiendo mucho, pero los Rails DEBERÍAN comstackr automáticamente todos los archivos en esos directorios debido a *= require_tree . en application.css, ¿verdad?

Recientemente, he intentado reestructurar estos archivos eliminando todas las variables de color y colocándolos en un archivo en la carpeta raíz app/assets/stylesheets (_colors.css.scss). Luego creé un archivo en la carpeta raíz de la app/assets/stylesheets llamado master.css.scss que se ve así:

 // 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"; 

Realmente no entiendo cómo maneja Rails el orden de la comstackción de activos, pero obviamente no está a mi favor. Parece que ninguno de los archivos se da cuenta de que tienen variables o mixins importados, por lo que arroja errores y no puedo comstackrlos.

 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á claramente definida en _colors.css.scss, y _master.css.scss está importando colores y todos mis mixins. Pero aparentemente los Rails no recibieron esa nota.

¿Hay alguna manera de solucionar estos errores, o tendré que recurrir a volver a poner todas mis definiciones de variables en cada archivo individual, así como a todas las importaciones de mixin?

Desafortunadamente, este tipo no parece pensar que sea posible, pero espero que esté equivocado. Cualquier idea es grandemente apreciada.

El problema con CSS es que no desea agregar automáticamente todos los archivos. El orden en que el navegador carga y procesa sus hojas es esencial. Así que siempre terminarás importando explícitamente todo tu CSS.

Como ejemplo, digamos que tiene una hoja normalize.css , para obtener un aspecto predeterminado en lugar de todas las implementaciones de navegador horribles diferentes. Este debería ser el primer archivo que carga el navegador. Si solo incluye aleatoriamente esta hoja en algún lugar de sus importaciones de CSS, no solo reemplazará los estilos predeterminados del navegador, sino también cualquier estilo definido en todos los archivos CSS que se cargaron antes. Esto va igual para variables y mixins.

Después de ver una presentación de Roy Tomeij en Euruko2012, decidí por el siguiente enfoque si tienes mucho CSS para administrar.

Generalmente uso este enfoque:

  1. Cambie el nombre de todos los archivos .css existentes a .scss
  2. Eliminar todo el contenido de la aplicación.scss

Comience a agregar directivas @import a application.scss .

Si usa twitters bootstrap y algunas hojas de css propias, primero debe importar bootstrap, porque tiene una hoja para restablecer los estilos. Entonces agrega @import "bootstrap/bootstrap.scss"; a su application.scss .

El archivo bootstrap.scss se ve así:

 // 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"; 

Y su archivo application.scss ve así:

 @import "bootstrap/bootstrap.scss"; 

Debido al orden de las importaciones, ahora puede usar las variables, cargadas con @import "variables.scss"; en cualquier otro archivo .scss importado después de él. Entonces pueden usarse en type.scss en la carpeta bootstrap pero también en my_model.css.scss .

Después de esto, crea una carpeta llamada partials o modules . Este será el lugar de la mayoría de los otros archivos. Simplemente puede agregar la importación al archivo application.scss para que se vea así:

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

Ahora, si hace un poco de CSS para darle estilo a un artículo en su página de inicio. Simplemente crea partials/_article.scss y se agregará a la application.css comstackda.css. Debido al orden de importación también puede usar cualquier mixins de arranque y variables en sus propios archivos scss.

El único inconveniente de este método que encontré hasta ahora es que, a veces, tienes que forzar una recomstackción de los archivos .Sk parcial / * porque los rails no siempre lo hacen por ti.

Crea la siguiente estructura de carpetas:

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

En la base carpeta crea un archivo “globals.css.scss”. En este archivo, declare todas sus importaciones:

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

En su application.css.scss, debería tener:

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

Y como último paso (esto es importante), declare @import 'base/globals' en cada archivo de estilo donde quiera usar variables o mixins. Podría considerar esta sobrecarga, pero en realidad me gusta la idea de que tenga que declarar las dependencias de sus estilos en cada archivo. Por supuesto, es importante que solo importe mixins y variables en globals.css.scss ya que no agregan definiciones de estilo. De lo contrario, las definiciones de estilo se incluirían varias veces en su archivo precomstackdo …

para usar variables y tal en todos los archivos, debe usar la directiva @import. los archivos se importan en orden especificado

luego, use application.css para requerir el archivo que declara las importaciones. esta es la forma de lograr el control que desea.

finalmente, en su archivo layout.erb, puede especificar qué archivo css “maestro” usar

el ejemplo será más útil:

digamos que tiene dos módulos en su aplicación que necesitan diferentes conjuntos de CSS: “aplicación” y “administrador”

Los archivos

 |-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 

así es como se ven los archivos en el interior:

 -------- 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" 

De acuerdo con esta pregunta , SOLAMENTE puede usar application.css.sass para definir importar y compartir variables entre sus plantillas.

=> Parece ser solo una cuestión de nombre.

Otra forma puede ser incluir todo e inhabilitar esta canalización .

Tuve un problema muy similar. Lo que me ayudó fue poner el guión bajo en la statement @import al importar el parcial. Asi que

 @import "_base"; 

en lugar de

 @import "base"; 

Puede ser un error extraño …