Hi, I am a bit curious about the default behaviour of Ionic 2 regarding generation of css files from component scss files. I don’t know if this is the right place to ask, but anyway…
From what I see, the gulp sass task generate a single css file from the /app/theme/app.core.scss
file (and other scss files from the /app/theme/
folder, where app.core.scss
import each component file.
This means that a component scss file will pretty much work as a global css file, so it can change the styles of other (unrelated) components inadvertedly.
Reading the Angular 2 specification about component styles Angular, they refer to components as independent pieces of code, including the template (html) and style (css), and I see their point:
This is a big improvement in modularity compared to how CSS traditionally works:
- We can use the CSS class names and selectors that make the most sense in the context of each component.
- Class names and selectors are local to the component and won’t collide with classes and selectors used elsewhere in the application.
- Our component’s styles cannot be changed by changes to styles elsewhere in the application.
- We can co-locate the CSS code of each component with the TypeScript and HTML code of the component, which leads to a neat and tidy project structure.
- We can change or remove component CSS code in the future without trawling through the whole application to see where else it may have been used. We just look at the component we’re in.
Workaround
**
For now, I just changed the way the gulpfile.js
generates css from:
gulp.task('sass', buildSass);
to:
gulp.task('sass', function() {
buildSass(); // generate files from /app/theme/
buildSass({
src: 'app/pages/**/*.scss',
dest: 'www/build/css/components',
sassOptions: {}
});
});
So I can use a component specific style using styleUrls
in the @Component
decorator:
In a component .ts file
/app/pages/my-component/my-component.ts
I use
styleUrls: ['build/css/components/my-component/my-component.css']
Updated
Changed the code in the gulpfile with:
var customBuildSass = function () {
buildSass({
src: 'app/theme/app.+(ios|md|wp).scss',
dest: 'www/build/css',
sassOptions: {
includePaths: [
'node_modules/ionic-angular',
'node_modules/ionicons/dist/scss'
]
}
}); // generate files from /app/theme/ (original)
buildSass({
src: 'app/pages/**/*.scss',
dest: 'www/build/css/components',
sassOptions: {}
}); // generate files from /app/pages/ (customized)
};
gulp.task('sass', customBuildSass);
The previous code works the first time, but if gulp is watching for changes, only the components scss files will be built again, but the global ones will not, and you will need to execute the gulp build task again or execute ionic serve
again. See why here.
I would like to know if there is a good/better reason for using component styles as global styles (like Ionic 2 does now), or if this behaviour (merging in 1 css file all component styles and making the styles global) is just a matter of choice or something like that (and if this default behaviour may change in the future to use styles per component).
(Of course, I think that global styles would still be used (massively), but they could be, for example, in the /app/theme/
folder (and subfolders), instead of being in the components’ scss files)