Buy

RAWR! Um, click on the T-rex. Here, we get personal with Mr Tyranosaur. His big image has a class called dino-img-show that's not used anywhere else on this site. But the CSS behind this lives in styles.scss. And that means we're including it on every page.

That's a bummer! I need the flexibility to have page-specific CSS files, in addition to my one big giant layout CSS file.

First, move this stuff into its own Sass file called dinosaur.scss. I'll paste that in there:

4 lines app/Resources/assets/sass/dinosaur.scss
.dino-img-show {
margin-bottom: 50px;
}

The Gulp watch robots are hard at work in the background. AND, they're looking for every .scss file in that directory. That means, when I refresh, I still have the dino-img-show styling. See, it's adding all that margin between the image and the button. We have 3 Sass files, but it's all still compiling into one big main.css.

Here's the goal: configure Gulp to give us two files: main.css made from styles.scss and layout.scss and dinosaur.css made from this new one. Then, we can include dinosaur.css only on this show page. RAWR!

Include specific Files in main.css

First, let's make main.css only include two of these files. Update gulp.src(). Instead of a pattern, we can pass it an array. We'll feed it sass/layout.scss and then sass/styles.scss:

30 lines gulpfile.js
... lines 1 - 10
gulp.task('sass', function() {
gulp.src([
config.assetsDir+'/sass/layout.scss',
config.assetsDir+'/sass/styles.scss'
])
... lines 16 - 21
.pipe(gulp.dest('web/css'));
... lines 23 - 30

Ok gulp, restart yourself!

gulp

And refresh! The margin is gone - the stuff from dinosaur.scss is no longer included. Ok, good start!

Isolating the Styles Pipeline

Now, how can we get Gulp to do all of this same logic, but dump out a new dinosaur.css file.

Start by creating a new variable called app. We'll use this as a place to store our own custom functions - including a nice new one called addStyle. Give this two arguments - the paths we want to process and the final filename to write. Next, copy the guts of the sass task into addStyle and make it dynamic: fill in paths on top, and filename instead of main.css:

39 lines gulpfile.js
... lines 1 - 11
app.addStyle = function(paths, outputFilename) {
gulp.src(paths)
.pipe(plugins.plumber())
.pipe(plugins.if(config.sourceMaps, plugins.sourcemaps.init()))
.pipe(plugins.sass())
.pipe(plugins.concat(outputFilename))
.pipe(config.production ? plugins.minifyCss() : plugins.util.noop())
.pipe(plugins.if(config.sourceMaps, plugins.sourcemaps.write('.')))
.pipe(gulp.dest('web/css'));
};
... lines 22 - 39

Can you guys see what's next? In the sass task, we'll call app.addStyle(), keep the two paths, comma, then main.css:

39 lines gulpfile.js
... lines 1 - 22
gulp.task('sass', function() {
app.addStyle([
config.assetsDir+'/sass/layout.scss',
config.assetsDir+'/sass/styles.scss'
], 'main.css');
... lines 28 - 31
});
... lines 33 - 39

I like it! Let's make sure we didn't break anything. Restart gulp and then refresh the page:

gulp

Processing a Second CSS File

Yep, still looks ok! Now let's put that margin back!

To do that, we can just call addStyle() again. Copy the first addStyle and make it load only dinosaur.scss. Oh, and give it a different output name - how about dinosaur.css:

39 lines gulpfile.js
... lines 1 - 22
gulp.task('sass', function() {
... lines 24 - 28
app.addStyle([
config.assetsDir+'/sass/dinosaur.scss'
], 'dinosaur.css');
});
... lines 33 - 39

Ok! Hit ctrl+c then restart Gulp:

gulp

I'm hoping we'll uncover a new dinosaur.css when we dig inside the web/css directory. Yes! And it's got just the stuff form its one source file.

Updating the Template

The last step has nothing to do with Gulp: we need to add a link tag to this one page. In Twig, I'll override my block stylesheets, call the parent() function to keep what's in my layout, then create a normal link tag that points to css/dinosaur.css:

23 lines app/Resources/views/dinosaurs/show.html.twig
... lines 1 - 2
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('css/dinosaur.css') }}"/>
{% endblock %}
... lines 8 - 23

That should do it. Go back and refresh that page! The margin is back, thanks to our page-specific CSS. So when you need to add some new CSS, you don't need to throw it in your one, gigantic main CSS file. If it's specific to a page or section, compile a new CSS file just for that. It's all really simple.

Leave a comment!