Documentation / Designing

Styles

Parts, states, the property groups, and the rule that keeps the exported C clean.

LVGL styles an object by part and by state. The designer follows that exactly: the Style settings section of the Inspector has a Part selector, a State selector, and beneath them every style property grouped the way LVGL's documentation groups them. Set a property and it is stored against the part and state you had selected.

Style settings for the Go button: the Part and State selectors, then the groups. Only Background > Color has been set, and it shows the reset control.
Style settings for the Go button: the Part and State selectors, then the groups. Only Background > Color has been set, and it shows the reset control.

Parts

Which parts exist depends on the widget. Every widget has Main. A slider adds Indicator and Knob; a dropdown adds the list's own three; a chart has Items (the series), Indicator (the points), Ticks (the axes) and a Scrollbar. LVGL 9 dropped the Ticks part along with a chart's axes, so there the export puts its default state onto the scales it draws the axes with; see Charts. The widget reference lists each one's parts. The canvas renders the parts it can - a knob colour, an indicator colour, a chart's ticks - and approximates the rest.

States

Six: Default, Pressed, Checked, Focused, Edited and Disabled. A property set in a non-default state overrides the default one while the object is in that state, which is how a button darkens when pressed or a switch turns green when on. The canvas draws the selected widget in whichever state the State selector is on, so a pressed look can be styled without holding anything down; the preview shows Pressed and Checked as you operate things.

Property groups

GroupProperties
BackgroundColor, Opacity, Gradient color, Gradient direction, Main stop, Gradient stop, Image, Image opacity, Image recolor, Recolor opacity, Image tiled
BorderColor, Opacity, Width, Side
OutlineColor, Opacity, Width, Pad
ShadowColor, Opacity, Width, X offset, Y offset, Spread
TextColor, Opacity, Font, Align, Letter space, Line space, Decoration
ImageRecolor, Recolor opacity, Opacity
LineColor, Opacity, Width, Rounded, Dash width, Dash gap
ArcColor, Opacity, Width, Rounded
PaddingTop, Bottom, Left, Right, Row, Column
TransformRotation, Scale, Pivot X, Pivot Y
MiscRadius, Opacity, Clip corner, Blend mode

Colours are entered as hex or picked from the project's named colours; opacities are 0 to 255; sizes are pixels; the font is a family, style and size - Montserrat, built into LVGL, or one from the font library. An Icon widget is coloured by the Text colour and opacity and chooses its own font, so its Text group has no Font. Each group has a heading you can collapse.

A picture behind a part - and a picture for a thumb

The Background group's Image draws one of the project's images behind a part. On the Knob part of a slider or an arc that picture is the thumb, which is how a slider gets a machined cap or a fader gets a lit handle. Set the knob's background opacity to 0 if only the picture should show.

LVGL draws it centred, at its own size - never scaled, never turned - and clips it to the part. So the part has to be as big as the picture: a knob is the track's thickness plus its padding on each side, and the padding is what you raise. The canvas draws a knob with a picture at exactly that size. Recolor tints it, and the Pressed state can carry a different picture or tint. For a thumb that should turn as it goes round an arc, use the arc's Follower instead.

Only what you change is stored

This is the one rule to understand. A widget carries no style at all until you set something, and then it carries only that - keyed by part:state. Everything else is the LVGL default theme, which the canvas draws its own approximation of. Two consequences:

The theme is not one set of numbers. LVGL's default theme gives a panel more padding on a large display than on a small one, and LVGL 8 and 9 do not agree on everything either. It sorts displays into three classes by size - up to 320 pixels, under 720, and larger; LVGL 9 by the longer side, LVGL 8 by the width - and on a 320 × 240 board a panel’s content starts 15 pixels inside it (13 of padding and a 2 pixel border), where on an 800 × 480 one it starts 22 in. The canvas draws those measures as LVGL itself gives them - padding, the gap between a layout’s children, border widths and corners, for every widget and part - for your project’s LVGL version and your board’s display, so a widget laid out inside an untouched panel is where the board will draw it. Change the board to one in another class and an untouched panel’s padding changes with it, as it would on the device; a padding you set yourself never moves.

A property you have set shows a Reset to the theme default control next to it, which removes it from the project rather than writing the default value back.

The theme

The Theme tab's first section, Colours and themes, names the colours a design is drawn in and switches between whole sets of them. Project themes covers it. The section below it is LVGL's own theme, described here.

The LVGL theme section holds Mode light or dark, a Primary colour, a Secondary colour and a Default font, which every widget without a font of its own uses. These become the lv_theme_default_init() call in ui_init(). The Switch Theme action flips light and dark at runtime through a generated _ui_switch_theme(). The preview cannot re-theme the canvas, so it notes the switch in the Console tab instead.

Grow when pressed

LVGL's theme draws three things a little bigger for as long as a finger is on them: a button, a slider's knob and a checkbox's box. Each is drawn 2 pixels bigger on every side, and nothing moves: the caption stays where it was, and so does everything round it. Press Play and press one, and the preview shows it, as it does when the Inspector's State is set to Pressed.

Grow when pressed, in the same section, switches it off for the whole project. On an Arduino export that is one line of lv_conf.h (LV_THEME_DEFAULT_GROW); on MicroPython, where the firmware is already built, the export says so on each button, slider and checkbox instead. ESPHome builds LVGL with it off, so an ESPHome design never grows and the switch is not offered there.

Fonts

Text uses LVGL's bundled Montserrat, or a font from the font library - seven-segment displays, Montserrat Bold for button captions and headings, Roboto, Oswald, Orbitron and more. The generator enables exactly the Montserrat sizes the design uses in lv_conf.h (LV_FONT_MONTSERRAT_14 1 and so on) and copies only the library fonts and sizes it uses into src/ui/fonts/. The Theme tab lists the fonts in use and what each costs in flash. The canvas draws text in the same fonts the board does, so a line's width is within a few per cent; browser anti-aliasing still differs slightly from LVGL's.

The Font control under Style settings, Text: family Montserrat, style Bold, 24 px, with its credit, licence and flash cost.
The Font control under Style settings > Text: a family, its style and a size.

Screen styles

A screen is styled the same way, and a screen background colour is the most common style of all: select nothing, open Style settings, set Background > Color.