Working with CSS in your first Magento 2 project

So, you’ve finally managed to create your new theme in Magento 2. After a few hours of swearing and sweating, you’ve successfully created all necessary files, defined fallback to Luma (you can blame Luma for all the mess that will happen later on), registered your theme within the system, activated it in the Magento Administration…aaaand…you are ready to go!
But, what now?
We’ve all been reading about the new changes that will happen in Magento 2 frontend.
Everyone was talking about speed, new technologies that we’ll be able to see in new edition.
Platform was in development phase, things were changing from release to release…and, of course, no one was really thinking about first questions that start to show up after you really start to work on your first Magento 2 project.
Soon I realized that, regardless of what I already know about all the new stuff and how to work with them, I was really absolutely clueless on how to begin with work, how to set up and organize everything properly.
Yes, we had official documentation but for me it was confusing and some things weren’t clearly explained.
In this article, I will show you everything I did during my work on the first Magento 2 project.
There may be better solutions than mine and I hope you will write them down in comments!
I presume you know about CLI commands for Magento 2. We will use some of them to work with static files and compiling.
If you don’t know which one to use and when, here’s the list of all commands with description.
I created new theme in new Vendor package, fallback was set to Luma theme.
I was using default tools for work :
- Grunt as task runner
- LESS as pre-processor
- Livereload to inject changes in browser.
LESS structure
Structure is totally different than in Magento 1, LESS files can be found on multiple places.
Theme-related LESS files are located in :
/Magento2/app/design/frontend/Magento/luma/web/css
Module-specific LESS files can be found in modules folder. For example, you can find LESS files for the Checkout module (including cart,minicart etc.) here :
/Magento2/app/design/frontend/Magento/blank/Magento_Checkout/web/css
As you can see, LESS files for Magento checkout module are stored inside “Blank” theme, not “Luma”.
If you don’t see LESS files in module folders inside “Luma” theme, you know that they can be found in “Blank” theme.
Like we will override/extend some “Luma” LESS files for our newly created theme, “Luma” does the same to “Blank” theme – it inherits some of the styles and overrides others.
Magento 2 comes with UI library that was built to help Front end developers deal with common tasks. It employs a set of mixins for base elements to ease Front end theme development and customization.
UI library can be found here:
/Magento2/lib/web/css
So, we have theme-related LESS files, module-related LESS files and LESS UI library.
After we are familiar with the structure, it is time to start with the real work.
First thing first – we need to deploy static files that will be served to the client.
Static files are to be found in this folder:
/Magento2/pub/static
We can deploy static files by triggering
grunt exec:<YourThemeName>
in console.
This command will generate static files for your theme and also, symlinks to corresponding LESS files.
Symlinks are basically symbolic links to your actual LESS files that are placed inside your theme (or fallback theme).
So , when you edit LESS file in your theme, changes will be automatically applied to the symlinked file stored in pub/static folder.
If you don’t get why is that so important, think about cleaning and deploying your static files after every change in LESS files.
Symlinks are also good for tracing and debugging.
If your LESS files icon has small arrow that points to top right, you know that file is symlinked.
Hovering over symlinked file will reveal real location of file that is stored in your theme (or fallback theme, or “lib” folder :)).
Extending Theme-related LESS files
OK, we have successfully deployed static files which are symlinked. That means we are ready for styling!
If you are happy with how most of the “Luma” theme looks like and would like to extend styling with your own css, the easiest way to achieve that is to create _extend.less file which will be placed here:
/Magento2/app/design/frontend/<Vendor>/<yourTheme>/web/css/source/_extend.less
After adding new LESS files, you must deploy static content again.
First, in console type
grunt clean:<yourTheme>
to remove all static files.
Then, type:
grunt exec:<yourTheme>
to create new static files.
(Whenever you are creating new LESS files inside your theme, you must generate new static content)
Now, you can write your own CSS inside that file and changes will be applied to your theme!
Oh yes, Don’t forget to trigger
grunt watch
that tracks the changes in the source files, recompiles .css
files, and reloads the page in the browser pages (you need to have LiveReload installed for you browser).
Overriding Theme-related LESS files
Similar approach as with extending your theme but difference is that we use exact LESS filename in order to override file in parent theme.
So, if you want to override _theme.less file and use your own variables inside your theme, do so by creating your own _theme.less file and place it here:
/Magento2/app/design/frontend/<Vendor>/<YourTheme>/web/css/source/_theme.less
Extending UI Library components
You can also extend files from LESS UI Library. For example, if you want to extend _buttons.less file, you need to create “_buttons_extend.less” file inside your theme folder:
In _extend.less, register the _buttons_extend.less by adding the following code:
@import 'lib/_buttons_extend.less';
Again, clean and generate your static files.
Overriding UI library components
Similar approach as with overriding theme files. If you want to override _buttons.less file, create new one inside your theme folder:
Again, don’t forget to clean and generate your static files.
Extending Module-related LESS files
As I mentioned above, module-related LESS files are located inside Module folder.
What if I like default styling of a certain module but I want to add some of my own CSS, just like I did with _extend.less for my theme?
Same as with extending a theme, we must create _extend.less inside module folder we wish to work with:
Clean static files, deploy new ones and you can write your css inside newly created _extend.less.
HINT: the best way to check if you properly extended theme or module files is to hover over Symlinked LESS file inside “pub/static” and see what is the real location of file.
If your file is located in “blank” or “luma” theme, you did something wrong.
Overriding Module-related LESS files
I think that now you are pretty much familiar with the process so I’ll keep it simple.
I created _Module.less inside my “Magento Checkout” folder and by doing that, I override parent theme module.less. Inside “module.less” I have @import directives for those 3 files that you see inside “module” folder.
Now I have full control of what will be loaded and I can easily remove, for example, “checkout.less” and/or add my own less file/s.
Adding new LESS files inside your theme
That one is simple. Create new file inside
Magento2/app/design/frontend/<vendor>/<yourTheme>/web/css/source/
And then, inside _extend.less file, register that file with @import directive.
Enough,huh? 😀
Of course there are much more on this topic but those basic actions we went through will help you kickoff with your project.
However, if this or anything else regarding Magento development confuses you, we will gladly check out your site and offer technical insights on what to improve based on our detailed custom report. Feel free to get in touch!
Good luck and have fun 🙂
20 comments
Hi Team,
I want to change the order sequence of CSS and render it at last.
hi, how to change the css for the homepage/landingpage.
I actually decided to not use “lib” folder in my custom theme. It just got so confusing having it (note Luma doesn’t use it either) due to deciding if a file extends directly UI library or not, etc… Rather, I just keep all my _extend.less files in css/source/*. Is this not a good idea?
Neat and clean explaination. Kudos 🙂
Hi, i’ve been trying this for days and still can’t see my changes. I have a new theme set in app/design/frontend/magento (based on luma). I have added extend.less to the css/source folder. I am not using grunt (yet) but trying to see the changes by executing the magento setup:static-content:deploy command in my cli. I have added a simple css change to the header into extend.less -> .page-header {background-color: green} Then i removed that simple css statement and tried this: & when (@media-common = true) { .page-header {background-color: green; }
I should be seeing some color change to the header background, correct? . Can anyone help? thanks.
Thank you very much for shedding some light in my begginer path with Magento 2.
I’m used to work directly in css using chrome to test changes, and then directly apply it to the css file mentioned in the debug window. I’m using prestashop 1.6 in my current shop, but I’m willing to do my new shop with Magento.
Is it possible to temporrarly pass/load the source file reference directly to browser? This way I could live test the changes more easly.
okok I can extend quite everything but… what if I would like to extend web/css/source/module/minicart.less?
Thanks a lot Nenad, better than devdocs explain it 😉
I’m using _extend.less to override the parent theme’s style. But I find that I have to use !important everywhere. Am I doing something wrong?
Hi Francis,
to override the parent’s styles, you don’t have to extend anything.
You have to create a new file with the same name in your theme
f.e: you want to override the whole _buttons.less of blank (which is your parent theme i guess)
Create a file _button.less in Source/app/design/frontend///web/css/source/_buttons.less
If you want to overwrite just some variables, like button background color, you look the variable name up in the corefiles (Source/lib/web/css/source/lib/variables/_buttons.less)
Copy it to your _theme.less which should be located unter Source/app/design/frontend///web/css/source/
Give the variable the value, you want like:
@button__background: red;
Shouldn’t it be _extends (with an “s”)
I had some doubts about it too. But it’s extend in the end, the doc itself tells it: http://devdocs.magento.com/guides/v2.1/frontend-dev-guide/css-guide/css_quick_guide_approach.html
The fact you can find an extends in the web source of the blank theme, for instance, it’s just because, i guess, they’re all plural in that folder: _extends, _forms, _icons… yes, it’s kinda confused!
Hi,
How can i change my button color ii have default theme. i need to change .action.primary class background color which is found in styles-m.css
Thanks
Hi Jack,
you can overwrite the variable @button-primary__background in your custom theme.
Go to _theme.less which should be located unter Source/app/design/frontend///web/css/source/ and assign your color to it.
@button-primary__background: #ff0;
As Luma is a demonstration theme, it is recommended to not use it as a parent theme.
Blank theme is the best choice to base your new theme on.
That was awesome article, i got few confusions how to define custom media queries like orientation and max and min together, provided doc in CSS folder has no topic like this.
Thanks ! Very informative, please do keep sharing information regarding Magento2.
Thanks Nenad!
Great article! I just started working with Magento 2 a week ago and this article comes in just the right time to confirm my knowledge. I struggle however with how to display images via CSS. For example I want a new background image. Should I store it inside //web/images or inside //Magento_Theme/web/images? How do I link an image from either of those two locations?
Hi Marush,
I stored my images in “/Magento2/app/design/frontend/Vendor/YourTheme/web/images”.
Linking is the same as always, you need to specify correct path to image. In this case, path would be “../images/image.jpg”