# m(selector, attributes, children) - [Description](#description) - [Signature](#signature) - [How it works](#how-it-works) - [Flexibility](#flexibility) - [CSS selectors](#css-selectors) - [DOM attributes](#dom-attributes) - [Style attribute](#style-attribute) - [Events](#events) - [Properties](#properties) - [Components](#components) - [Lifecycle methods](#lifecycle-methods) - [Keys](#keys) - [SVG and MathML](#svg-and-mathml) - [Making templates dynamic](#making-templates-dynamic) - [Converting HTML](#converting-html) - [Avoid anti-patterns](#avoid-anti-patterns) --- ### Description Represents an HTML element in a Mithril view ```javascript m("div", {class: "foo"}, "hello") // represents
hello
``` You can also [use HTML syntax](https://babeljs.io/repl/#?code=%2F**%20%40jsx%20m%20*%2F%0A%3Ch1%3EMy%20first%20app%3C%2Fh1%3E) via a Babel plugin. ```markup /** jsx m */
hello
``` --- ### Signature `vnode = m(selector, attributes, children)` Argument | Type | Required | Description ------------ | ------------------------------------------ | -------- | --- `selector` | `String|Object` | Yes | A CSS selector or a [component](components.md) `attributes` | `Object` | No | HTML attributes or element properties `children` | `Array|String|Number|Boolean` | No | Child [vnodes](vnodes.md#structure). Can be written as [splat arguments](signatures.md#splats) **returns** | `Vnode` | | A [vnode](vnodes.md#structure) [How to read signatures](signatures.md) --- ### How it works Mithril provides a hyperscript function `m()`, which allows expressing any HTML structure using javascript syntax. It accepts a `selector` string (required), an `attributes` object (optional) and a `children` array (optional). ```javascript m("div", {id: "box"}, "hello") // equivalent HTML: //
hello
``` The `m()` function does not actually return a DOM element. Instead it returns a [virtual DOM node](vnodes.md), or *vnode*, which is a javascript object that represents the DOM element to be created. ```javascript // a vnode var vnode = {tag: "div", attrs: {id: "box"}, children: [ /*...*/ ]} ``` To transform a vnode into an actual DOM element, use the [`m.render()`](render.md) function: ```javascript m.render(document.body, m("br")) // puts a
in ``` Calling `m.render()` multiple times does **not** recreate the DOM tree from scratch each time. Instead, each call will only make a change to a DOM tree if it is absolutely necessary to reflect the virtual DOM tree passed into the call. This behavior is desirable because recreating the DOM from scratch is very expensive, and causes issues such as loss of input focus, among other things. By contrast, updating the DOM only where necessary is comparatively much faster and makes it easier to maintain complex UIs that handle multiple user stories. --- ### Flexibility The `m()` function is both *polymorphic* and *variadic*. In other words, it's very flexible in what it expects as input parameters: ```javascript // simple tag m("div") //
// attributes and children are optional m("a", {id: "b"}) // m("span", "hello") // hello // tag with child nodes m("ul", [ // // array is optional m("ul", // ``` --- ### CSS selectors The first argument of `m()` can be any CSS selector that can describe an HTML element. It accepts any valid CSS combinations of `#` (id), `.` (class) and `[]` (attribute) syntax. ```javascript m("div#hello") //
m("section.container") //
m("input[type=text][placeholder=Name]") // m("a#exit.external[href='http://example.com']", "Leave") // Leave ``` If you omit the tag name, Mithril assumes a `div` tag. ```javascript m(".box.box-bordered") //
``` Typically, it's recommended that you use CSS selectors for static attributes (i.e. attributes whose value do not change), and pass an attributes object for dynamic attribute values. ```javascript var currentURL = "/" m("a.link[href=/]", { class: currentURL === "/" ? "selected" : "" }, "Home") // equivalent HTML: // Home ``` If there are class names in both first and second arguments of `m()`, they are merged together as you would expect. --- ### DOM attributes Mithril uses both the Javascript API and the DOM API (`setAttribute`) to resolve attributes. This means you can use both syntaxes to refer to attributes. For example, in the Javascript API, the `readonly` attribute is called `element.readOnly` (notice the uppercase). In Mithril, all of the following are supported: ```javascript m("input", {readonly: true}) // lowercase m("input", {readOnly: true}) // uppercase m("input[readonly]") m("input[readOnly]") ``` --- ### Style attribute Mithril supports both strings and objects as valid `style` values. In other words, all of the following are supported: ```javascript m("div", {style: "background:red;"}) m("div", {style: {background: "red"}}) m("div[style=background:red]") ``` Using a string as a `style` would overwrite all inline styles in the element if it is redrawn, and not only CSS rules whose values have changed. Mithril does not attempt to add units to number values. --- ### Events Mithril supports event handler binding for all DOM events, including events whose specs do not define an `on${event}` property, such as `touchstart` ```javascript function doSomething(e) { console.log(e) } m("div", {onclick: doSomething}) ``` --- ### Properties Mithril supports DOM functionality that is accessible via properties such as `