UI Customization

Almost all of the UI generated by Mavo is customizable. Find out how in this section.

Styling with CSS

The easiest way to customize the UI is via CSS. You can find many style hooks in the index.

Some examples for common cases follow:

Style differently in edit mode

Give an element with property="foo" a yellow background when it is in edit mode:

		[property="foo"][mv-mode="edit"] {
			background: yellow;

Show something only to logged in users

mv-permissions is an attribute set by Mavo on the Mavo root containing a space-separated list of available permissions. When a Mavo allows login but the current user is not logged in, mv-permissions will include the value login. You can use this in your CSS to style things differently based on whether the current user is logged in.

For example, let's say you have an auth class and you want to only show anything with that class to authenticated users. You can do this with this CSS:

		[mv-permissions~="login"] .auth {
			display: none;

Note the ~= in the attribute selector above. This allows you to match for one value in a space-separated list, instead of the entire attribute.

For convenience, there are also mv-logged-in and mv-logged-out classes that you can use on your HTML to show things only to logged in or logged out users respectively.

Mavo toolbar

The Mavo toolbar is the dark toolbar that you get by default on every Mavo app, with controls like Edit, Save, Clear etc. By default it is added inside the Mavo root, at the beginning.

Change its placement and/or use your own HTML element for it

Just use class="mv-bar mv-ui" on your desired element.

Custom button elements

Follow the process above for using a custom toolbar element, and include your custom button inside it with the appropriate mv-[button id] class. For example, to have a Clear button with the text "Delete All" instead of "Clear", you could do:

Remove default styling

Follow the process above for using a custom toolbar element, and omit the mv-ui class. This is useful when you want a completely different styling and would rather start from a blank state. You can see an example of custom toolbar styling on the SVG Paths demo.

Change button order or restrict buttons to a subset

You can also use the mv-bar attribute on your Mavo root to customize which controls can appear and in what order. The default value is "status edit save clear login logout" which includes all controls available by default. Plugins can extend the list of available controls. If you only want to hide a few buttons and not actually change the order or restrict the set of buttons displayed, read the following section.

Hide certain buttons

You can use no- in front of a button id in mv-bar to hide the corresponding button. For example, to hide the login button, you can use no-login the value:

Conveniently, the toolbar will not be visible when it has no buttons, so this essentially hides the toolbar for logged out users. You can still log in without a Mavo toolbar, by adding ?login to the page URL. Note that browsers often block popups more aggressively when they are not triggered by a click so you may need to manually approve the authentication popup when using this.

Hide the toolbar completely

Use mv-bar="none". You can then use classes like mv-status, mv-edit, mv-save, mv-clear, mv-login, mv-logout on your own buttons to provide the corresponding functionality. However, note that if you choose to go this route, these buttons will be always shown, regardless of whether the user has permission for the corresponding action. You can use an mv-permissions attribute selector to fix this.

Item controls

These are the buttons that Mavo adds to each collection item for deleting it, moving it, or adding items before/after it. By default they are added as the last child of the collection item.

To change the placement of their container and/or use your own HTML element for it, just use class="mv-item-bar mv-ui" on your desired element. Note that if you have nested collections, this will be associated with the collection that is the closest ancestor of the element.

Similarly to the Mavo toolbar, if you don’t want any of the default styling associated with these controls just omit the mv-ui class.

Add new item button

For every collection, a button to add new items is generated and placed before the collection if it has mv-order="desc" or after it otherwise. The default label of the button is of the form "Add [name]", where [name] is the name of your collection.

Often you may want a custom label or a custom placement for this button. You can do this by using a class of mv-add-[name] on your desired element, where [name] is the name of the collection you wish to associate it with. Alternatively, if the association is obvious, you can just use a class of mv-add instead.

Both of these classes are also present on the generated buttons and you can use them for styling.

Customizing Text & Localization

Your app needs to be in a different language? No problem! You can customize every bit of displayed text, whether that is to change the text displayed to your liking or to localize it to a different language.


First check the available locale plugins in case your language is available. If not, you would have to write one yourself, using the methods outlined below.

Customizing text via HTML

You can use a <datalist> element to define your own phrases or localize text. The syntax is:

Please note that the lang attribute is mandatory, even if you’re only overriding a few English phrases. Please note that lang is not a Mavo attribute, it’s an HTML attribute and its values are described in any HTML documentation.

Please try to avoid locales with hyphens unless you absolutely need to. E.g. it's better to define a general French (lang="fr") locale and another Canadian French (Québécois) locale (lang="fr-ca") with only the phrases that are different. The reason is that any French dialect can fall back to general French, but not to a specific dialect of French, which means that even if you have defined a locale for fr-ca, apps with lang="fr" will be displayed in English.

Please note that this datalist element is static, i.e. changes to its contents via scripts or expressions will not be picked up.

For a list of ids and phrases that you can copy as a starting point, use src/locale.en.js, however note that plugins can also define their own phrases.

Customizing text via JavaScript

You can write your own localization plugin, by using Mavo.Locale.register(languageCode, phrases). For an example, you can look at the Greek localization plugin.

If you go that route, please consider adding your plugin to the Plugins directory so that others can benefit too! Don’t worry if it's not perfect, others can improve it via pull requests!