Rails의 적절한 SCSS 자산 구조


86

따라서 app/assets/stylesheets/다음과 같은 디렉토리 구조가 있습니다.

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

각 디렉토리에는 여러 개의 sass 부분 (일반적으로 * .css.scss이지만 * .css.scss.erb 하나 또는 두 개)이 있습니다.

나는 많은 것을 가정 할 수 있지만, rails는 *= require_tree .application.css에 있기 때문에 해당 디렉토리의 모든 파일을 자동으로 컴파일해야합니다 . 맞습니까?

최근에 모든 색상 변수를 제거하고 루트 app/assets/stylesheets폴더 (_colors.css.scss) 의 파일에 배치하여 이러한 파일을 재구성 해 보았습니다 . 그런 다음 app/assets/stylesheetsmaster.css.scss라는 루트 폴더에 다음과 같은 파일을 만들었습니다 .

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

레일이 애셋 컴파일 순서를 처리하는 방법을 이해하지 못하지만 분명히 내 편이 아닙니다. 어떤 파일도 변수 나 믹스 인을 가져 오는 것을 인식하지 못하는 것 같아서 오류가 발생하고 컴파일 할 수 없습니다.

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)

변수 $dialog_divider_color는 _colors.css.scss에 명확하게 정의되어 있으며 _master.css.scss색상과 모든 믹스 인을 가져 옵니다 . 그러나 분명히 레일은 그 메모를 얻지 못했습니다.

이러한 오류를 수정할 수있는 방법이 있습니까? 아니면 모든 변수 정의를 각 개별 파일과 모든 mixin 가져 오기에 다시 넣어야합니까?

불행히도, 이 사람 은 그것이 가능하다고 생각하지 않는 것 같지만, 그가 틀렸기를 바라고 있습니다. 어떤 생각이라도 대단히 감사합니다.

답변:


126

CSS의 문제는 모든 파일을 자동으로 추가하고 싶지 않다는 것입니다. 브라우저에서 시트를로드하고 처리하는 순서는 필수적입니다. 따라서 항상 모든 CSS를 명시 적으로 가져 오게됩니다.

예를 들어, 모든 끔찍한 브라우저 구현 대신 기본 모양을 얻기 위해 normalize.css 시트 가 있다고 가정 해 보겠습니다. 브라우저가로드하는 첫 번째 파일이어야합니다. CSS 가져 오기의 어딘가에이 시트를 임의로 포함하면 브라우저 기본 스타일뿐만 아니라 이전에로드 된 모든 CSS 파일에 정의 된 모든 스타일도 재정의됩니다. 이것은 변수와 믹스 인에 대해서도 동일합니다.

Euruko2012 에서 Roy Tomeij 의 프레젠테이션을보고 관리 할 CSS가 많으면 다음과 같은 접근 방식을 결정했습니다.

나는 일반적으로 다음 접근 방식을 사용합니다.

  1. 모든 기존 .css 파일의 이름을 .scss로 바꿉니다.
  2. application.scss에서 모든 내용을 제거합니다.

@import 지시문을 application.scss.

twitters 부트 스트랩과 몇 개의 CSS 시트를 사용하는 경우 스타일을 재설정 할 시트가 있으므로 먼저 부트 스트랩을 가져와야합니다. 그래서 당신 @import "bootstrap/bootstrap.scss";은 당신의 application.scss.

bootstrap.scss 파일은 다음과 같습니다.

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

그리고 application.scss파일은 다음과 같습니다.

@import "bootstrap/bootstrap.scss";

가져 오기 순서 때문에 이제 가져온 @import "variables.scss";다른 .scss파일 에 로드 된 변수를 사용할 수 있습니다 . 따라서 type.scss부트 스트랩 폴더뿐만 아니라 my_model.css.scss.

그런 다음 이름이 지정된 폴더를 만듭니다. partials 또는modules . 이것은 대부분의 다른 파일의 위치가됩니다. application.scss다음과 같이 파일에 가져 오기를 추가 할 수 있습니다 .

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

이제 홈페이지에서 기사 스타일을 지정하기 위해 약간의 CSS를 작성하면됩니다. 만들기 만하면 partials/_article.scss컴파일 된 application.css. 가져 오기 순서로 인해 자체 scss 파일에서 부트 스트랩 믹스 인 및 변수를 사용할 수도 있습니다.

내가 지금까지 발견 한이 방법의 유일한 단점은 레일이 항상 당신을 위해 그것을하지 않을 것이기 때문에 부분 /*.scss 파일을 강제로 재 컴파일해야한다는 것입니다.


4
감사합니다. 이것이 제가 사용한 접근 방식입니다. 이 솔루션을 만들 때마다 포함하는 모든 파일을 수동으로 추가해야하기 때문에이 솔루션이 싫지만 CSS가 관련되면 순서가 중요해 보입니다. 일반적으로 CSS 작성이 좋지 않다고 말하고 싶지만, 벤더가 제공하는 것 (즉, 위에서 언급 한 부트 스트랩)을 사용하는 경우 덮어 쓰는 경향이 있으므로 이것이 올바른 접근 방식이라는 데 마지 못해 동의합니다.
David Savage

1
감사! 아주 좋은 접근 방식과 좋은 설명! 언급 할만한 한 가지 프로젝트 :이 FireBug 플러그인 인 FireSass 는 컴파일 된 application.css의 줄 대신 my_model.css.sass의 줄 번호를 보여줍니다.
BBQ Chef

이 방법을 사용하면 모든 부분에 적용되는 기본 링크 색상을 빨간색으로 변경하려면 어떻게해야합니까? 어디에 두시겠습니까?
chh

1
이 접근 방식은 The Asset Pipeline Rails Guide 에서도 권장됩니다 . "여러 Sass 파일을 사용하려는 경우"를 검색합니다.
ybakos 2014

1
@Lykos 예,에서 모든 것을 제거 application.css하고 이름을 application.scss. 때문에 require_tree단지 모든 것을 포함하고 당신은 일반적으로 순서 제어 할
벤자민 Udink 열 케이트

8

파일간에 변수 등을 사용하려면 @import 지시문을 사용해야합니다. 지정된 순서대로 파일을 가져옵니다.

그런 다음 application.css를 사용하여 가져 오기를 선언하는 파일을 요구하십시오. 이것이 원하는 제어를 달성하는 방법입니다.

마지막으로 layout.erb 파일에서 사용할 "마스터"css 파일을 지정할 수 있습니다.

예가 더 도움이 될 것입니다.

다른 CSS 세트가 필요한 앱에 "application"과 "admin"이라는 두 개의 모듈이 있다고 가정 해 보겠습니다.

파일

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

내부 파일은 다음과 같습니다.

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

다음 폴더 구조를 만듭니다.

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

폴더에서 base"globals.css.scss"파일을 만듭니다. 이 파일에서 모든 가져 오기를 선언하십시오.

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

application.css.scss에 다음이 있어야합니다.

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

그리고 마지막 단계 (중요)로 @import 'base/globals'변수 나 믹스 인을 사용하려는 모든 스타일 파일에서 선언 하십시오. 이 오버 헤드를 고려할 수 있지만 실제로 모든 파일에서 스타일의 종속성을 선언해야한다는 생각이 마음에 듭니다. 물론 스타일 정의를 추가하지 않으므로 globals.css.scss의 믹스 인과 변수 만 가져 오는 것이 중요합니다. 그렇지 않으면 스타일 정의가 미리 컴파일 된 파일에 여러 번 포함됩니다.


나는 이것을 시도했지만 제대로 작동하지 못했습니다 (여전히 변수 오류가 누락되었습니다). 내가 제대로하지 않았을 수도 있지만 결국에는 CSS 순서가 중요하기 때문에 각 파일을 수동으로 나열하는 방식이 올바른 방법이라고 생각합니다.
David Savage

이 방법을 계속 사용할 수 있습니다. "require_tree ..."대신 각 개별 파일에 대한 행을 추가하십시오. 이렇게하면 SASS가 올바른 순서로 파일을 가져옵니다. 지금 사용하고있는 솔루션과 관련하여 방금 찾은이 게시물을 살펴보십시오. stackoverflow.com/questions/7046495/… application.css 파일에 depends_on 디렉토리를 포함해야합니다.
emrass

4

이 질문 에 따르면 가져 오기를 정의하고 템플릿간에 변수를 공유하기 위해서만 사용할 수 있습니다 application.css.sass.

=> 이름 문제인 것 같습니다.

다른 방법 은 모든 것을 포함하고이 파이프 라인을 비활성화하는 것 입니다.


이것은 본질적으로 Benjamin Udink ten Cate가 답변의 두 번째 부분에서 제공 한 것과 동일하지만, 그의 솔루션이 더 설명 적이므로 그에게 현상금을 수여합니다.
David Savage

1

나는 매우 비슷한 문제가 있었다. 부분을 ​​가져올 때 @import 문에 밑줄을 넣는 것이 도움이되었습니다. 그래서

@import "_base";

대신에

@import "base";

이상한 버그 일 수 있습니다 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.