Materialize CSS: When to Skip M.AutoInit and Initialize Modals Explicitly
Materialize v1.x leaves interactive components inert until JavaScript initializes them. M.AutoInit() applies defaults only; use explicit M.Modal.init() for options and dynamic content.
25 Aug 2026, 21:04 UTC

Useful Answer
In Materialize CSS v1.x, CSS-only utilities such as the grid, buttons, cards, and waves work immediately from markup. Interactive components—modal, sidenav, dropdown, tabs, collapsible, tooltip, carousel, autocomplete, datepicker, timepicker, slider, scrollspy, parallax, and pushpin—remain inert until JavaScript attaches behavior. M.AutoInit() is a convenience scan that initializes every matching selector with defaults, but it cannot apply per-component options or activate nodes added after the page loads. For a modal that needs custom options, or for content injected by AJAX, use explicit M.Modal.init() instead.
How Initialization Works
The global M namespace exposes component constructors. M.AutoInit() queries the document for known selectors like .modal, .sidenav, and .dropdown-trigger, then calls the matching initializer. Explicit initialization targets a specific element and accepts an options object. Instances are stored on the element and retrievable with M.Modal.getInstance(el).
Worked Example: Modal with Options
document.addEventListener('DOMContentLoaded', function () {
// Initialize the rest of the page with defaults
M.AutoInit();
// Explicitly initialize one modal with custom options
var el = document.querySelector('#demo-modal');
if (!el) return;
var instance = M.Modal.init(el, {
dismissible: true,
opacity: 0.5,
inDuration: 300,
outDuration: 200,
onOpenEnd: function () {
var firstInput = el.querySelector('input');
if (firstInput) firstInput.focus();
}
});
// Retrieve later if needed
// var saved = M.Modal.getInstance(el);
});
The trigger markup must reference the modal by ID:
<a class="modal-trigger" href="#" data-target="demo-modal">Open modal</a>
<div id="demo-modal" class="modal">
<div class="modal-content">
<h4>Modal heading</h4>
<p>Content</p>
</div>
<div class="modal-footer">
<a href="#" class="modal-action modal-close waves-effect waves-green btn-flat">Close</a>
</div>
</div>
Dynamic Content
M.AutoInit() only sees elements present when it runs. Nodes inserted later through AJAX, innerHTML, or SPA route changes stay inert. Initialize the new subtree explicitly:
var container = document.querySelector('#ajax-root');
var modals = container.querySelectorAll('.modal');
modals.forEach(function (el) {
if (!M.Modal.getInstance(el)) {
M.Modal.init(el);
}
});
Checking M.Modal.getInstance(el) before calling init() prevents duplicate listeners on elements that were already initialized.
Limits and Common Mistakes
M.AutoInit()applies no per-component options. It initializes every matching selector, which may attach behavior you did not intend.- Options are read once at initialization. Changing attributes afterward does not reconfigure the instance.
- Materialize v1.x dropped jQuery. Syntax such as
$('.modal').modal()or$(document).ready()will fail; use theMnamespace andDOMContentLoaded. - Initializing before the DOM is ready returns
nullselectors. - Modals, dropdowns, and tooltips use
position:fixed. Placing them inside an ancestor withtransform,filter,perspective, orwill-changebreaks overlay positioning. Mount overlays near<body>. - Calling
init()twice on the same element creates duplicate listeners. UsegetInstance()to detect existing instances.
Verification
- Confirm the installed version exposes
M(v1.x) rather than jQuery plugins (v0.x). Checkpackage.jsonor the dist file header. - Run
M.Modal.getInstance(document.querySelector('.modal'))in the console. A returned object means the modal is initialized. - Click a
<a class="modal-trigger" data-target="demo-modal">link and confirm the modal opens. Verifydata-targetmatches the modalid. - After injecting new markup, initialize it explicitly and assert
M.Modal.getInstance(newEl)is non-null.
Explicit initialization gives you control over options and dynamic content, while M.AutoInit() is best reserved for pages where default behavior for all components is acceptable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.