Raylarda Uygun SCSS Varlık Yapısı


86

Yani, app/assets/stylesheets/şuna benzeyen bir dizin yapım var:

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

Her dizinde birden çok sass bölümü vardır (genellikle * .css.scss, ancak bir veya iki * .css.scss.erb).

Çok şey varsayıyor olabilirim, ancak uygulama.css'de olduğu için rayların bu dizinlerdeki tüm dosyaları otomatik olarak derlemesi GEREKİR *= require_tree ., değil mi?

Yakın zamanda tüm renk değişkenlerini kaldırıp kök app/assets/stylesheetsklasördeki (_colors.css.scss) bir dosyaya yerleştirerek bu dosyaları yeniden yapılandırmayı denedim . Daha sonra app/assets/stylesheetsmaster.css.scss adlı kök klasörde şuna benzer bir dosya oluşturdum :

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

Rayların varlık derleme sırasını nasıl ele aldığını gerçekten anlamıyorum, ancak bu açıkça benim lehime değil. Görünüşe göre dosyaların hiçbiri içe aktarılmakta olan değişkenleri veya karışımları olduğunu bilmiyor ve bu yüzden hata veriyor ve ben derleyemiyorum.

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)

Değişken $dialog_divider_color, _colors.css.scss'de açıkça tanımlanmıştır ve _master.css.scssrenkleri ve tüm karışımlarımı içe aktarmaktadır. Ama görünüşe göre raylar bu notu almamış.

Bu hataları düzeltmenin bir yolu var mı, yoksa tüm değişken tanımlarımı her bir dosyaya ve tüm mixin içe aktarımlarına geri koymam gerekecek mi?

Maalesef, bu adam bunun mümkün olduğunu düşünmüyor, ama umarım yanılıyordur. Herhangi bir düşünce çok takdir edilmektedir.

Yanıtlar:


126

CSS ile ilgili sorun, tüm dosyaları otomatik olarak eklemek istememenizdir. Sayfalarınızın tarayıcı tarafından yüklenme ve işlenme sırası önemlidir. Böylece her zaman tüm css'lerinizi açıkça içe aktaracaksınız.

Örnek olarak, tüm korkunç farklı tarayıcı uygulamaları yerine varsayılan bir görünüm elde etmek için bir normalize.css sayfanız olduğunu varsayalım. Bu, tarayıcının yüklediği ilk dosya olmalıdır. Bu sayfayı rastgele olarak css içe aktarmalarınızda bir yere eklerseniz, yalnızca tarayıcı varsayılan stillerini değil, aynı zamanda ondan önce yüklenen tüm css dosyalarında tanımlanan stilleri de geçersiz kılar. Bu, değişkenler ve karışımlar için aynıdır.

Euruko2012'de Roy Tomeij'in bir sunumunu gördükten sonra , yönetecek çok fazla CSS'niz varsa aşağıdaki yaklaşıma karar verdim.

Genelde şu yaklaşımı kullanırım:

  1. Mevcut tüm .css dosyalarını .scss olarak yeniden adlandırın
  2. Tüm içeriği application.scss'den kaldırın

@İmport yönergelerini eklemeye başlayın application.scss.

Eğer twitters bootstrap ve birkaç css sayfası kullanıyorsanız, stilleri sıfırlamak için bir sayfası olduğu için önce bootstrap'i içe aktarmanız gerekir. Yani eklemek @import "bootstrap/bootstrap.scss";adresinden Müşteri application.scss.

Bootstrap.scss dosyası şöyle görünür:

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

Ve application.scssdosyan şöyle görünüyor:

@import "bootstrap/bootstrap.scss";

İçe aktarımların sırası nedeniyle, artık, kendisinden sonra içe aktarılan @import "variables.scss";başka herhangi bir .scssdosyaya yüklenen değişkenleri kullanabilirsiniz . Böylece type.scssönyükleme klasöründe kullanılabileceği gibi my_model.css.scss.

Bundan sonra partialsveya adında bir klasör oluşturun modules. Bu, diğer dosyaların çoğunun yeri olacaktır. İçe aktarımı application.scssdosyaya ekleyebilirsiniz, böylece şöyle görünecektir:

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

Şimdi, ana sayfanızdaki bir makaleye stil vermek için biraz css yaparsanız. Sadece oluşturun partials/_article.scssve derlenenlere eklenecektir application.css. İçe aktarma sırası nedeniyle, kendi scss dosyalarınızda herhangi bir önyükleme karışımını ve değişkenini de kullanabilirsiniz.

Şimdiye kadar bulduğum bu yöntemin tek dezavantajı, bazen kısmi / *. Scss dosyalarını yeniden derlemeye zorlamanız gerekiyor çünkü raylar bunu her zaman sizin için yapmayacak.


4
Teşekkürler, benim sonunda benimsediğim yaklaşım bu. Bu çözümden nefret ediyorum çünkü her bir dosya oluşturduğunuzda dahil ettiğiniz her dosyayı manuel olarak eklemeniz gerekiyor, ancak CSS dahil olduğunda sıra önemli gibi görünüyor. Normalde bunun kötü CSS yazımı olduğunu söyleyebilirim, ancak sağlayıcı tarafından sağlanan şeyleri kullanıyorsanız (örn. Yukarıda belirttiğiniz gibi önyükleme), bir şeylerin üzerine yazmak istersiniz, bu yüzden bunun doğru yaklaşım olduğuna gönülsüzce katılıyorum.
David Savage

1
Teşekkürler! Çok güzel bir yaklaşım ve güzel bir açıklama! Bahsetmeye değer bir proje: Bu FireBug eklentisi, FireSass , derlenen application.css satırı yerine my_model.css.sass satır numarasını gösteriyor.
BBQ Chef

Bu yaklaşımla, tüm bölümlerime uygulanan varsayılan bağlantı rengimi kırmızıya değiştirmek istersem, bunu nasıl yaparsınız? Nereye koymak istiyorsunuz?
chh

1
Bu yaklaşımın Asset Pipeline Rails Guide'da da önerildiğini unutmayın . "Birden fazla Sass dosyası kullanmak istiyorsanız" araması yapın.
ybakos

1
@Lykos evet, içindeki her şeyi kaldırıp application.cssadını olarak yeniden adlandırıyorsunuz application.scss. Çünkü require_treesadece her şeyi içerir ve genellikle düzeni kontrol etmek istersiniz
Benjamin Udink on Cate

8

değişkenleri ve benzerlerini dosyalarda kullanmak için @import yönergesini kullanmanız gerekir. dosyalar belirtilen sırayla içe aktarılır.

daha sonra, içe aktarmaları bildiren dosyayı zorunlu kılmak için application.css'yi kullanın. İstediğiniz kontrolü elde etmenin yolu budur.

son olarak, layout.erb dosyanızda hangi "ana" css dosyasının kullanılacağını belirtebilirsiniz

örnek daha faydalı olacaktır:

uygulamanızda farklı css kümelerine ihtiyaç duyan iki modülünüz olduğunu varsayalım: "uygulama" ve "yönetici"

dosyalar

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

İşte dosyaların içinde nasıl göründüğü:

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

Aşağıdaki klasör yapısını oluşturun:

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

Klasörde basebir "globals.css.scss" dosyası oluşturun. Bu dosyada, tüm ithalatlarınızı belirtin:

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

Application.css.scss dosyanızda, şunlara sahip olmalısınız:

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

Ve son adım olarak (bu önemlidir), @import 'base/globals'değişkenleri veya karışımları kullanmak istediğiniz her stil dosyasında beyan edin . Bu ek yükü düşünebilirsiniz, ancak aslında stillerinizin bağımlılıklarını her dosyada beyan etmeniz gerektiği fikrini seviyorum. Elbette, stil tanımları eklemedikleri için sadece globals.css.scss'deki mixin ve değişkenleri içe aktarmanız önemlidir. Aksi takdirde stil tanımları önceden derlenmiş dosyanıza birden çok kez dahil edilirdi ...


Bunu denedim ama asla düzgün çalışmasını sağlayamadım (hala değişken hataları eksik oluyordu). Belki bir şeyi doğru yapmadım, ancak sonunda her dosyayı manuel olarak listeleme yaklaşımının doğru yol olduğunu düşünüyorum, çünkü CSS sıralaması önemlidir.
David Savage

Hala bu yaklaşımı kullanabilirsiniz: "require_tree ..." yerine her bir dosya için bir satır eklemeniz yeterlidir. Bu, SASS'nin dosyaları doğru sırada içe aktarmasını sağlayacaktır. Şu anda kullandığınız çözümle ilgili olarak, lütfen az önce bulduğum şu gönderiye bir göz atın: stackoverflow.com/questions/7046495/… reliv_on direktifini application.css dosyanıza dahil ettiğinizden emin olun.
emrass


1

Çok benzer bir sorun yaşadım. Bana yardımcı olan şey, parçayı içe aktarırken @import ifadesinin altını çizmek oldu. Yani

@import "_base";

onun yerine

@import "base";

Garip bir böcek olabilir ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.