This tutorial has a new version, check it out!

Sass to CSS

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Dinosaurs! Actually, these are our test project, and it's written in Symfony. But everything we'll do translates to any PHP project.

But this look bad - it's messed up. And that's totally my fault. Open up the base layout - app/Resources/view/base.html.twig. I'm including Twitter Bootstrap, but that's it so far:

... lines 1 - 2
... lines 4 - 9
<link rel="stylesheet" href="{{ asset('vendor/bootstrap/dist/css/bootstrap.css') }}"/>
... lines 11 - 15
... lines 17 - 46

I do have a project-specific CSS file, but it's missing from here. The problem is that it's not a CSS file at all - it's a Sass file that lives in app/Resources/assets.

Btw, this is where I've decided to put my frontend assets, but it doesn't matter. But do notice that this is not a public directory.

Gulp's first job will be to turn that Sass file into CSS so I can get my site to stop looking so ugly.

Installing gulp-sass

With Gulp, we make tasks. But it doesn't do much else. Most things are done with a plugin. Go back to Gulp's site and click Plugins to find a search for, not 13, but 1373 plugins. The one we want is gulp-sass.

First, install it! Copy the npm install gulp-sass. But wait! I want you to add that --save-dev because I want this plugin to be added to our package.json file:

npm install gulp-sass --save-dev

Hey, there it is! When another developer clones the project, they just need to run npm install and it'll download this stuff automatically. Oh, and the gulp-sass plugin preps a sass binary in the background. If you have any issues installing - especially you wild Windows users - check out the node-sass docs.

The Classic pipe Workflow

Head back to the docs. This is showing a classic Gulp workflow. We start by saying gulp.src() to load files matching a pattern. Next, you'll pipe it through a filter - in our case sass() - and pipe it once more to gulp.dest(). That actually writes the finished files.

Let's do it! Be lazy by copying the require line and adding it to the top of our file. Now we'll say gulp.src. Let's load all the Sass files that are in that sass/ directory - so app/Resources/assets/sass/**/*.scss:

9 lines gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('default', function() {
... lines 6 - 7

That double ** tells Gulp to look recursively inside the sass directory for .scss files. That'll let me create subdirectories later if I want.

Now that we've loaded the files, we'll just pipe them through whatever we need. Use pipe() then sass() inside of it. Gulp works with streams, so imagine Gulp is opening up all of our .scss files as a big stream and then passing them one-by-one through the pipe() function. So at this point, all that Sass has been processed. Then finally, we'll pipe that to gulp.dest() and say: "Hey, I want you to dump the finished product to the web/css/ directory.":

9 lines gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('default', function() {

That's all we need! Head back to the terminal and just type gulp:


Ok, no errors - that seems good. But now we do have a web/css/styles.css file. And I know it got processed through Sass because the original is using a variable.

Using the Boring CSS File

Now that we have a boring, normal, generated styles.css file, let's add the link tag to our base template. This uses that asset() function from Symfony, but that's not actually doing anything here. The path is relative to the public directory - web/ for a Symfony project.

... lines 1 - 2
... lines 4 - 9
<link rel="stylesheet" href="{{ asset('vendor/bootstrap/dist/css/bootstrap.css') }}"/>
<link rel="stylesheet" href="{{ asset('css/styles.css') }}"/>
... lines 13 - 17
... lines 19 - 48

Head back, and refresh! Dinosaurs! That's much better.

Ignore Directories in git

Since the web/css/ directory only contains generated files, we don't need to commit it. If these files are missing, just run gulp! The same goes for node_modules - we can get that by running npm install. Silly directories.

So anyways, it'd be great to not commit these. So let's open up the .gitignore file and add /node_modules and /web/css:

17 lines .gitignore
... lines 1 - 13
... lines 16 - 17

Now when I run git status again, that stuff's gone!

Leave a comment!

  • 2017-07-17 weaverryan

    Yo Konrad Zając!

    I think I may know why everyone is so confused :).You're 100% correct that there is no "serve" task in gulpfile.js in the "start" code download. That's because we're not using gulp to serve the site in this tutorial: we use the built-in PHP web server in Symfony (app/console server:run). I noticed that we do a poor job of mentioning that in the tutorial itself (my apologies - we do a much better job in all of our more recent tutorials). We *do* mention this in the file that's in the code download, which you can also see here:

    So, try app/console server:run instead. You can of course make your own gulp serve command - but because we're using a PHP application as our "backend", we're using the PHP web server.


  • 2017-07-14 Konrad Zając

    I don't think I should just continue without the server the next chapter "sourcemaps" requires inspecting the graphical site.

  • 2017-07-12 Diego Aguiar

    Hey Konrad Zając

    I can't find that "serve" task either (maybe in a further chapter?) but you should be able to load the page without it, you just need to follow the steps in the README and then hit the page


  • 2017-07-11 Konrad Zając

    Got it thx!

  • 2017-07-11 Konrad Zając

    Firstly I did instalI gulp globally.
    Secondly there's no error per se.
    I know all that, but there's no serve task in the gulpfile.js in the "start" directory - there's no error, but I'm supposed to see the dinosaurs...

  • 2017-07-11 Diego Aguiar

    Hey Konrad Zając

    Did you install gulp globally ?
    Could you show me the error message you are getting ?

    When you run "gulp task_name" this by default will open any gulpfile.js file which lives in the same directory where you ran the command, and it will try to find and execute the given task name.

    Have a nice day!

  • 2017-07-11 Konrad Zając

    how to servw the application? "gulp serve" doesn't work.

  • 2017-07-11 Victor Bocharsky

    Hey Konrad,

    The "sudo npm install gulp-sass --save-dev" command shouldn't create a web/css directory - it just add a new dependency to your package.json file and download it locally. Probably "gulp" command will create it, but I'm not sure, maybe you should create this directory manually. And when it will be exist, "gulp" command will write there CSS files.


  • 2017-04-28 maxii123

    My error. It was indeed listed as a task in the readme. Apologies.

  • 2017-04-27 Diego Aguiar

    Hey maxii123!

    You are right, we forgot to talk about running "bower install"
    Thanks for letting us know, we will add a note as soon as we can.


  • 2017-04-27 maxii123

    Where is this bootstrap css from? Its not in your start code. post edit: did I need to do a "bower install"? I dont think this was mentined til now.

  • 2016-05-23 Andrea

    Yes you right.
    The second one is the right answer.
    Thanks a lot.

  • 2016-05-22 weaverryan

    Hi Andrea!

    Hmm. The fact that you see the error means that Symfony *is* running correctly. What happens if you run "app/console router:debug" from the terminal? Do you see the dinosaur_list route in the list?

    Also, you could try starting the web server on a different port - e.g.

    app/console server:run localhost:9002

    Then go to http://localhost:9002. I'm wondering if you have some other Symfony app already running on port 8000, so you're seeing this *other* app instead :).

    Let me know!

  • 2016-05-21 Andrea

    I tried to setup the project, downloaded your code, using dir "start", then i read all the steps in README but when i look for the site in http;//localhost:8000 symfony says "No route found for "GET /". What's i'm wrong?

  • 2015-05-25 weaverryan

    You got it! I just updated the README with these installation instructions (note: the assetic:dump isn't needed for this project). I'll start making sure we have these for *every* project.


  • 2015-05-25 Pietrino Atzeni

    Autoanswer: the missing step is

    bower install

  • 2015-05-25 Pietrino Atzeni

    Hi Ryan,
    trying to follow the tutorial, I downloaded the project and started the base project. As usual, then, some

    composer install

    app/console doctrine:database:create
    app/console doctrine:schema:create
    app/console doctrine:fixtures:load

    app/console assets:install --symlink
    app/console assetic:dump

    and finally

    app/console server:run

    Opening the page, though, there is no vendor/bootstrap folder, and so the page is even uglier than yours :). Am I missing something?