CSS and Less Files
File Location
Place Less files in:
view/frontend/web/css/source/_module.less
The _module.less file is automatically compiled and included.
Basic Less Structure
// view/frontend/web/css/source/_module.less
// Variables
@prep-primary-color: #1979c3;
@prep-secondary-color: #f5f5f5;
@prep-border-color: #cccccc;
// Common styles (all contexts)
& when (@media-common = true) {
.prep-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.prep-header {
background-color: @prep-primary-color;
color: white;
padding: 15px;
border-radius: 4px;
&__title {
font-size: 24px;
font-weight: 600;
}
&__subtitle {
font-size: 14px;
margin-top: 5px;
opacity: 0.9;
}
}
.prep-item {
border: 1px solid @prep-border-color;
padding: 15px;
margin-bottom: 10px;
background: @prep-secondary-color;
&__name {
font-weight: 600;
font-size: 16px;
}
&__price {
color: @prep-primary-color;
font-size: 18px;
}
}
}
// Mobile styles
.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
.prep-container {
padding: 10px;
}
.prep-header {
&__title {
font-size: 18px;
}
}
}
// Desktop styles
.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
.prep-container {
padding: 30px;
}
}
Multiple Less Files
Create additional files and import them:
// view/frontend/web/css/source/_module.less
@import 'components/_header.less';
@import 'components/_items.less';
@import 'components/_buttons.less';
Custom CSS (Without Less)
If you prefer plain CSS, place files in:
view/frontend/web/css/custom.css
Add to layout:
<page>
<head>
<css src="Amazon_Prep::css/custom.css"/>
</head>
</page>
JavaScript Configuration
requirejs-config.js
// view/frontend/requirejs-config.js
var config = {
map: {
'*': {
'prepComponent': 'Amazon_Prep/js/component'
}
},
paths: {
'amazonPrep': 'Amazon_Prep/js'
},
deps: [
'Amazon_Prep/js/init'
]
};
Map vs Paths
| Type | Purpose | Example |
|---|---|---|
| map | Alias a module name | 'prepComponent': 'Amazon_Prep/js/component' |
| paths | Define a base path | 'amazonPrep': 'Amazon_Prep/js' |
JavaScript Component
// view/frontend/web/js/component.js
define([
'jquery',
'uiComponent'
], function ($, Component) {
'use strict';
return Component.extend({
defaults: {
template: 'Amazon_Prep/component',
title: 'Default Title'
},
initialize: function () {
this._super();
console.log('Component initialized');
return this;
},
getTitle: function () {
return this.title;
},
setTitle: function (title) {
this.title = title;
return this;
}
});
});
jQuery Widget
// view/frontend/web/js/widget.js
define([
'jquery',
'jquery/ui'
], function ($) {
'use strict';
$.widget('amazon.prepWidget', {
options: {
container: null,
animate: true
},
_create: function () {
this.container = this.options.container || this.element;
this._bindEvents();
},
_bindEvents: function () {
var self = this;
this.container.on('click', '.prep-btn', function () {
self._handleClick($(this));
});
},
_handleClick: function ($btn) {
if (this.options.animate) {
$btn.fadeOut(200).fadeIn(200);
}
},
destroy: function () {
this._super();
}
});
return $.amazon.prepWidget;
});
JS Mixins
What are Mixins?
Mixins allow you to extend or modify existing JavaScript components without rewriting them. They're Magento's way of applying the Open/Closed principle to JS.
Creating a Mixin
// view/frontend/web/js/mixin/component-mixin.js
define([
'jquery'
], function ($) {
'use strict';
return function (targetModule) {
// Extend the target module
return targetModule.extend({
// Override a method
getTitle: function () {
var originalTitle = this._super();
return originalTitle + ' (Modified by Mixin)';
},
// Add a new method
customMethod: function () {
return 'This is a new method added by mixin';
},
// Modify initialize
initialize: function () {
this._super();
console.log('Mixin initialized after parent');
return this;
}
});
};
});
Register Mixin
// view/frontend/requirejs-config.js
var config = {
config: {\ mixins: {
'Amazon_Original/js/component': {
'Amazon_Prep/js/mixin/component-mixin': true
}
}
}
};
Conditional Mixins
var config = {
config: {
mixins: {
'Magento_Catalog/js/product/list': {
'Amazon_Prep/js/mixin/product-list-mixin': true
}
}
}
};
Mixin Best Practices
- Always call
_super()— preserves parent behavior - Don't modify data directly — use methods
- Keep mixins focused — one change per mixin
- Test thoroughly — mixins affect all instances
- Document dependencies — note which module is being extended
Using Mixins in Templates
<!-- In .phtml template -->
<div data-mage-init='{"prepComponent": {"title": "Custom Title"}}'>
<h1 data-bind="text: getTitle()"></h1>
</div>
<!-- Or with script tag -->
<script type="text/x-magento-init">
{
"*": {
"prepComponent": {
"title": "Custom Title"
}
}
}
</script>
Asset Deployment
Static Content Deployment
After adding CSS/JS files, deploy static content:
# Development
bin/magento setup:static-content:deploy -f
# Specific theme
bin/magento setup:static-content:deploy -f Magento/luma en_US
# With language
bin/magento setup:static-content:deploy -f en_US de_DE
Clear Cache
bin/magento cache:clean
bin/magento cache:flush
Remove Old Static Files
# Remove compiled Less
rm -rf pub/static/frontend/Amazon/Theme/
# Re-deploy
bin/magento setup:static-content:deploy -f
View File URL Helper
// In PHP
$url = $this->getViewFileUrl('Amazon_Prep::images/logo.png');
// In template
$url = $block->getViewFileUrl('Amazon_Prep::css/custom.css');
// In layout XML
<css src="Amazon_Prep::css/custom.css"/>
<img src="<?= $block->getViewFileUrl('Amazon_Prep::images/logo.png') ?>"/>
Head Assets in Layout
<page>
<head>
<!-- CSS -->
<css src="Amazon_Prep::css/custom.css"/>
<!-- JS -->
<script src="Amazon_Prep::js/custom.js"/>
<!-- RequireJS config -->
<script type="text/x-magento-init">
{
"*": {
"prepComponent": {
"title": "Custom"
}
}
}
</script>
<!-- Inline styles -->
<style>
.custom { "color": red; }
</style>
<!-- Meta tags -->
<meta name="description" content="Custom description"/>
</head>
</page>
Asset Compilation Pipeline
Less → CSS (compiled)
JS Modules → Bundled (if enabled)
Templates → Compiled (Knockout.js)
Pipeline commands:
# Compile Less to CSS
bin/magento setup:static-content:deploy -f
# Compile DI (generates proxy/factory classes)
bin/magento setup:di:compile
# Compile everything (production)
bin/magento deploy:mode:set production
Quiz
1. Where should Less files be placed in a module?
2. What does requirejs-config.js configure?
3. What is a JS mixin in Magento?
Flashcards
Question
Where do Less files go?
Click to reveal answer
Answer
view/frontend/web/css/source/_module.less
Question
What does requirejs-config.js do?
Click to reveal answer
Answer
Configures JS module aliases, paths, and dependencies
Question
How do you create a JS mixin?
Click to reveal answer
Answer
Return a function that takes the target module and calls .extend() on it
Question
How do you add CSS via layout XML?
Click to reveal answer
Answer
<css src="Vendor_Module::css/file.css"/>
Question
What command deploys static content?
Click to reveal answer
Answer
bin/magento setup:static-content:deploy -f
Revision Notes
Key Takeaways
- 1. Less files go in view/frontend/web/css/source/ and are auto-compiled
- 2. requirejs-config.js maps module names to file paths
- 3. JS mixins extend existing components via .extend() and _super()
- 4. Run static-content:deploy after adding or changing assets
- 5. Use getViewFileUrl() helper to generate asset URLs
Interview Tips
- • Explain the Less compilation pipeline in Magento
- • Know how to create and register JS mixins
- • Be ready to add custom CSS and JS to a module
- • Discuss static content deployment strategies
Cheat Sheet
Less: view/frontend/web/css/source/_module.less
JS: view/frontend/web/js/
Config: view/frontend/requirejs-config.js
Mixin:
define([], function() {
return function(target) {
return target.extend({ "method": function() { this._super(); } });
};
});
Deploy: bin/magento setup:static-content:deploy -f