As the scale of the application grows, the description of the application.scss file becomes longer, so I decided to separate the file for each controller this time. I had a lot of trouble and learned a lot, so I decided to write an article so that I wouldn't forget it.
Ruby 2.5.7 Rails 5.2.4
I will write only the answer first.
application.scss
// require_tree .
// require_self
erb:application.html.erb
<head>
...
<%= stylesheet_link_tag 'application' %>
...
</head>
It's okay if you create this description and a .scss file for each controller name in app / assets / stylesheet /!
I will explain the contents a little from here.
At first, I made application.scss a common style file, and tried to support all pages with two files of controller name.scss on each page. The description at that time is as follows.
application.scss
// require_self
erb:application.html.erb
<head>
...
<%# application.loading scss%>
<%= stylesheet_link_tag 'application' %>
<%#Controller name.loading scss%>
<%= stylesheet_link_tag params[:controller] %>
...
</head>
The // require_tree .
in the application.scss file is a description that reads all the .scss files in app / assets / stylesheet, so delete it once.
Instead, if you write params [: controller] in the stylesheet_link_tag of application.html.erb, you can get the path of the controller including the directory, so even if the controller is divided into directories, this writing method can be used.
However, this method is fine for .css files, but it causes an error for .scss.
.scss can only be supported by browsers by compiling it into .css format. In other words, it usually cannot be displayed in .scss format.
And the precompiled .scss file (.css file) is stored under app / public / assets in the production environment, and the file name is changed to hash format.
In other words, the css file cannot be picked up by <% = stylesheet_link_tag params [: controller]%>
described in application.html.erb.
Even if the file name is changed to the hash format, if you specify the hash as it is in the stylesheet_link_tag
, it will work, but this hash is not realistic because it changes every time the file is updated.
I couldn't really get to the way I wanted to split the .scss file by controller, so I switched to the description at the beginning.
If application.scss has // require_tree .
, it means that all .scss files under assets / stylesheet will be loaded.
This shouldn't happen too much, but if you specify the style while the class name of the css selector is covered, the one described later will be given priority, so you can not change it as you want. By the way, there is a risk of creating dependencies.
application.scss
// require_tree .
// require_self
If you write it like the beginning, application.scss will be loaded after all .scss files have been loaded.
Also, the order of the contents of // require_tree .
is in dictionary order, and the files are read in the order of file name a → z.
Inevitably, in tree., The closer the initial of the file name is to z, the later it will be read, so it tends to have a higher priority.
Before that, let's take a look at the variables in .scss.
In scss, properties and values can be used as variables. For now in my case
_variables.scss
//Hamburger animation
$hamburger-transition: 0.3s;
//Theme color
$thema-color1: #fff9f9;
$thema-color2: #ffefef;
$thema-color-font: #555;
//Media queries
$media-sp-max: 450px;
$media-pc-min: 1024px;
$media-tb-min: $media-sp-max + 1px;
$media-tb-max: $media-pc-min - 1px;
//Example
Selector name{
background: $thema-color1;
}
With this, you can change the theme color, media query width, hamburger menu transition, etc. for each file at once.
You can define a variable by writing the variable name from $ and then entering the value. When calling, just write the variable name in place of the value.
However, as it is, the variable is not defined in each file, so you need to import the file that describes only this variable into the .scss file of each controller name.
Controller name.scss
@import "variables";
...
By describing @import" file name "
, in this case, the variables written in _variables can be used.
The question arose here.
"Application.scss describes // require_tree .
. Each .scss file describes the import of variable files, so each time each file is read at compile time, the variable file is also described. Is it read as a .css file? "
I can say that there is no problem even if it is read, but I thought that there was a lot of waste, so I investigated further.
The result was that I was avoiding it without knowing it. Lol
I made a file name by looking at some article and referring to how to make a variable file, but it seems that it will not be compiled by adding an "_" underscore at the beginning of the file name lol In other words, _variables.scss used this time is a file name that starts with an underscore, so it is excluded from precompilation. If you think about it carefully, it is true that files that only write variables do not style directly, so there is no point in converting to .css, and when converting other files to .css, replace the variable part with the contents. I was strangely convinced that if I could do it, the variable file would be enough.
I will return to the implementation method at the beginning, but for the time being, I am thinking of operating it in this way.
application.scss
// require_tree .
// require_self
...
_variables.scss
$Variable name:value;
...
Each controller name.scss
@import "variables";
...
erb:application.html.erb
<head>
...
<%= stylesheet_link_tag 'application' %>
...
</head>
Until now, I wrote the style only in application.scss and made a block by writing the controller name by making full use of comments, but I wonder if it will be easier to maintain even if the file is separated for each controller. I think. In the unlikely event that the class name is covered, we will use the selector nesting, which is also a feature of .scss, to describe it visually in an easy-to-understand manner. (The class name for reuse (flex, grid, btn, etc.) is described separately in the application.scss file.)
I would appreciate it if you could teach me how to precompile the .scss file for each controller without using // require_tree .
!
Also, if you have any questions, differences in interpretation, or discomfort in the description method, we would appreciate it if you could point them out in the comments.
Thank you for reading until the end!
Rails Guide-Asset Pipeline Web Design Leaves - SASS [CSS HappyLife --Let's learn Sass! Vol.7] Divide files for easier management (partial)](http://css-happylife.com/archives/2012/0124_1850.php) HACK NOTE --Sass: Let's manage variables in a separate file
Recommended Posts