CSS / LESS
Overview
Your Servoy solution can be styled using LESS as dynamic style sheet language and/or unprocessed CSS (3.0).
CSS (Cascading Style Sheets) is the style sheet language used in the World Wide Web to describe how elements should be rendered in the presentation layer.
LESS is a CSS preprocessor that adds various features to CSS, such as variables, mixins, and functions. It allows developers to write more maintainable and reusable code by using a dynamic and expressive syntax. By using LESS, you can define variables to store common values, create mixins to reuse code snippets, and define functions for more complex tasks. In Servoy the .less file will compile into an actual .css automatically. For a detailed documentation about Less language see the Official Documentation for Less.
When creating a Servoy NG Client solution, the solution is created with the Servoy default less theme (is possible to opt-out); the theme offers configurable styles for commonly used components and a set of utility classes.
Quick Start
Servoy solutions are styled using a layered approach that combines:
A default theme: Defines base styling across the application (e.g., fonts, colors, spacing).
LESS/CSS files: Allow custom styling, variables, mixins, and layout definitions.
Component-level and form-level overrides: Enable scoped, local customization without affecting global styles.
If you're just getting started, begin with the Default Theme guide to understand how base styles are defined and extended.
Styling Flow in Servoy
Styling in Servoy is applied in a layered manner, where each level can override or extend the one above it. Here’s how it works:
Default Theme (
custom_servoy_theme_properties.less
) The base layer, built into Servoy, contains foundational variables and component styles.Solution-Level LESS/CSS Global styles that apply across your entire solution. By default, Servoy generates a file named
<solution-name>.less
, but this can be overridden.Form-Level LESS/CSS (Scoped) Styles defined directly in the Form Editor’s Less tab, scoped to the form they belong to. Ideal for layout-specific or isolated component styling.
Component-Level Styling Individual components reference class names using the styleClass property. These classes can be defined in any of the above layers.
This layered system gives you flexibility to build a unified design system at the solution level, while enabling isolated, maintainable styling within forms and components.
How it works
Servoy uses a LESS compiler to process and generate the final CSS used by the client. LESS enhances traditional CSS with features like variables, nesting, and imports — making your styles easier to manage and reuse.
Where Styles Come From
Default Theme (
custom_servoy_theme_properties.less
) This built-in file defines Servoy's core variables and component styles. It should not be edited directly. Instead, it can be extended or overridden via your own solution-level LESS files. You can also edit theme variables using the Theme Properties Editor.Solution-Level LESS File A global stylesheet, typically
<solution-name>.less
, located in the media folder. This file is created automatically with your solution and can be customized or replaced.Form-Level LESS (Scoped) A recent addition to Servoy, this lets you write LESS/CSS directly in each form. These styles are encapsulated to the form, allowing class reuse across forms without collision.
Solution-Level Styling
Overview
Solution-level styling refers to a global LESS or CSS file used across your entire application. When you create a new solution, Servoy automatically generates a LESS file named after your solution (e.g., mycrm.less
) and places it in the media
folder.
You are not limited to using this default file. You can configure the solution to use any .less
file in the media
folder instead.
How It Works
The designated
.less
file is automatically compiled and applied globally.Styles from this file affect all forms and components in the solution.
It serves as the main place to:
Override variables from the default theme
Declare global design tokens (colors, spacing, etc.)
Define shared layout patterns and component styles
Organize styles with
@import
to keep the codebase clean
Example
A common pattern in solution-level styling is to define design tokens (like colors or spacing) as variables, and then use them throughout your global styles. You can also break up your styles into separate modular files for better organization.
// media/mycrm.less
@primary-color: #007bff;
.btn-primary {
background-color: @primary-color;
color: white;
border-radius: 4px;
padding: 8px 16px;
}
You can modularize styles by importing them from subfolders:
@import "styles/variables.less"; // All design tokens
@import "styles/layout.less"; // Grid, containers, spacing
@import "styles/components.less"; // Shared UI components like buttons, cards, etc.
These imported files should also be placed inside the media
folder or a subdirectory within it.
Use Cases
Building and maintaining a centralized design system
Defining consistent styles for reusable UI components (e.g., buttons, cards, inputs)
Setting up layout scaffolding for global templates (e.g., header/footer containers)
Overriding default theme values for typography, borders, spacing, and color schemes
Best Practices
Keep your styles modular by using
@import
, for example for:variables.less
for color/spacing/fontslayout.less
for structural containerscomponents.less
for reusable UI parts
Use clear, reusable class names (e.g.,
.app-header
,.form-section
,.btn-primary
)Centralize all shared styles here so they can be consistently reused across forms
Reserve form-level styling only for local exceptions or layouts that aren’t shared
Form-Level Styling (Scoped)
Overview
Form-level styling in Servoy allows you to write form-specific LESS or CSS that applies only to the components on that form. This approach ensures styles are fully encapsulated, meaning class names, layout rules, and overrides cannot conflict with styles- globals or on other forms — even if the same class names are reused.
This feature was introduced to solve stylesheet encapsulation challenges and to enable cleaner styling practices in larger solutions, where global stylesheets often became bloated with rules used in isolated places.
How It Works
Each form has a Less tab in the Form Editor.
Click the
Create Form Less file
button to generate a.less
file tied specifically to that form.The styles written in this file:
Are compiled and applied only to the form they belong to.
Can use full LESS features: variables, mixins, nesting, etc.
Override global styles (e.g., from solution-level LESS or default theme), if class selectors match.
Are inherited by child forms in form hierarchies.
Why Form-Level Styling Matters
✅ Encapsulation: No naming conflicts between styles in different forms. ✅ Maintainability: Keeps form-specific styles close to the form logic. ✅ Override capability: Can locally override global styles for layout or appearance tweaks. ✅ Cleaner solution-level styling: No need to pollute your global .less with one-off or niche form rules. ✅ Layout freedom: Makes it easy to use CSS Grid or Flexbox per form, adapting responsive layout structures without affecting others.
Examples:
Example: Overriding a Global Style in Form-Level LESS
This example demonstrates how the same class name (.content-text
) can be reused across multiple forms, each with its own styling, thanks to form-level encapsulation in Servoy's LESS support.
It shows how form-level styles override global styles without conflict, allowing per-form visual customization without risk of unintended side effects.
Use Case
You want to apply a class called .content-text
to label components across multiple forms.
Each form should display the text in a different color, using the same class name, without modifying the global stylesheet or affecting other forms.
What the Forms Contain
Each of the three forms (Form A
, Form B
, and Form C
) contains:
A title label (e.g., "Form A")
A content label (e.g., description of the applied style)
Both labels have the
styleClass
property set tocontent-text
.
LESS Code
Solution-Level LESS (Global): In
media/<solution>.less
(e.g.,mySolution.less
):.content-text { color: blue; }
This is the default style used by Form A and available to any form that does not override it.
Form B - Form-Level LESS: In Form B’s Less tab:
.content-text { color: red; }
Form B uses the same class name, but styles it differently. This red text applies only within Form B.
Form C - Form-Level LESS: In Form C’s Less tab:
.content-text { color: green; }
Form C also uses
.content-text
, independently overriding both the global and Form B versions.
Visual Result:

Key Takeaways
🔒 Scoped LESS allows safely reusing class names across forms.
🧼 Reduces clutter in global styles by moving isolated rules to local form context.
🔄 Allows per-form overrides without touching or duplicating solution-wide styles.
📦 Keeps form logic and styling self-contained and maintainable.
Example: Form Inheritance with Layered LESS Overrides
This example shows how Servoy's form-specific LESS works in a form inheritance chain. It demonstrates how styles defined in a base form can be reused and selectively overridden in child forms, using the same class names — with each form's styling fully encapsulated.
Use Case
You want a shared base form (baseForm
) that defines reusable layout and style rules.
Child forms (FormA
, FormB
, FormC
, and FormD
) should inherit those styles but optionally override them with their own scoped LESS — without affecting each other or the base form.
What the Forms Contain
baseForm:
2 labels:
Title →
styleClass = "title"
Content →
styleClass = "content-text"
Has its own form-level LESS that overrides the global style:
.title { font-size: 40px; color: black; } .content-text { color: black; font-size: 30px; }
Form A:
Extends
baseForm
Own LESS overrides
.title
only:
.title { color: blue; background-color: cyan; }
Form B
Extends
baseForm
Own LESS overrides
.content-text
only:
.content-text { color: red; background-color: #ECEBEA; }
Form C
Extends
baseForm
Own LESS overrides both
.title
and.content-text
:
.title { font-size: 20px; color: green; background-color: #cef3d5; } .content-text { color: green; }
Form D
Extends
baseForm
No form-level LESS; uses inherited styles as-is
Visual Result:

LESS Inheritance Resolution: Order of Precedence When using form-level LESS with inheritance, Servoy resolves styles in the following order, from lowest to highest priority:
Global (Solution-Level) LESS
Declared in the solution's
.less
file (e.g.,mySolution.less
)Applies universally unless overridden at a more specific level
Base Form LESS
Defined in the base form's own Less tab
Overrides global styles within that form and all forms that inherit it
Child Form LESS
Defined in a child form that extends a base form
Has the highest priority and overrides both base form and solution-level styles
🧠 Even when using the same class name, Servoy ensures styles are scoped and isolated per form. A .content-text
in Form C does not affect the same class in Form B, even though both inherit from the same base form.
Key Takeaways
🧬 Form-level LESS follows inheritance rules — child forms receive styles from parent forms.
🔁 Each form can selectively override inherited styles using the same class names.
🔒 All overrides remain encapsulated to the form; no cross-form conflicts.
🧹 Helps maintain clean and modular styling across large solutions with shared layouts.
Example: Responsive Form: Two-Row Flex Layout (3 Items per Row)
This version of the layout uses form-scoped LESS to create a responsive layout with two rows, each containing exactly three flex items.
What the Form Contains

1 Bootstrap Flex Container
6 child components (flex items), each one with a button inside for example purposes
Visual goal:
[ item 1 ] [ item 2 ] [ item 3 ]
[ item 4 ] [ item 5 ] [ item 6 ]
Form-Level LESS
Inside the form’s Less tab, click Create Form Less file
, then add the custom style:
.flex {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: stretch;
justify-content: flex-start;
gap: 16px;
padding: 16px;
background-color: #f8f8f8;
}
.flex-item {
flex: 0 1 calc(33.333% - 16px); // 3 items per row with spacing
min-width: 200px;
box-sizing: border-box;
background-color: #e0e0e0;
border: 1px solid #ccc;
padding: 12px;
text-align: center;
}
Explanation
flex-wrap: wrap
enables wrapping into multiple rows.flex: 0 1 calc(33.333% - 16px)
ensures three items per row, adjusting for gap.The layout will always break into two rows with three items each, as long as the container is wide enough.
If the screen becomes too narrow, items will start to wrap again (you can constrain with
max-width
or add media queries if needed).
Visual Result:

Use Cases
🧱 Form-specific layouts using Flexbox or CSS Grid Great for dashboards, sidebars, detail views, and other UIs with complex, responsive layouts.
🧪 Isolated design experimentation Safely prototype new styles on a single form without breaking other parts of the app.
💡 UI modularization Encapsulate styles alongside embedded forms, wizards, pop-ups, or reusable UI modules.
🛡️ Conflict prevention Use identical class names across forms without risk of collision or unintended overrides.
Best Practices
Use clear, local naming (e.g.,
.customer-summary
,.invoice-section
).Keep styles focused and scoped — don't attempt to define global utilities or shared variables here.
Use form-specific LESS to define layout logic and fine-tune styling for the form only.
Consider this approach as a way to scale style management in large, modular applications.
Styling Techniques and Best Practices
This section covers practical tips and patterns for writing LESS/CSS effectively in Servoy, including selector usage, styling components, managing specificity, and using variables.
Using Servoy’s Built-In Selectors
Every Servoy element has a default selector in its template — for example, a Bootstrap button has the class .bts-button
. You can target these classes to apply consistent styling across all components of that type.
// Make the borders of all buttons slightly rounded
.bts-button {
border-radius: 6px;
}
Applying Custom Classes with styleClass
styleClass
Each component in Servoy has a styleClass
property, where you can enter one or more custom class names. This is the preferred way to apply additional styles or override default ones.
Example:
styleClass="btn btn-primary my-roundy-btn"
And the LESS:
.my-roundy-btn {
border-width: 2px;
border-radius: 50px;
}
This allows for stacking multiple styles and combining behavior, utility, or appearance.
CSS Specificity in LESS
The final style applied to an element depends on CSS specificity. If multiple class selectors apply to the same property (e.g., border-radius
), the one defined last in the compiled CSS will win if specificity is equal.
Example:
// This will be overridden by .my-roundy-btn if it appears later in the file
.bts-button {
border-radius: 6px;
}
.my-roundy-btn {
border-radius: 50px;
}
Best practice:
Define default element styles first, and custom class-based overrides (used in styleClass
) after.
Using LESS Variables
LESS variables help you keep your styles consistent and easy to update. You can define them once and reuse across multiple components.
// Define a LESS variable
@my-border-radius: 6px;
// Use it across selectors
.bts-button {
border-radius: @my-border-radius;
}
.bts-textbox,
.bts-textarea {
border-radius: @my-border-radius;
}
This improves maintainability, ensures design consistency, and makes theming or refactoring faster.
Servoy elements Selectors
These are the specific class selectors which you can use to style servoy elements based on their types. Please note, depending on the component complexity, the component may have inner selectors to target more specific elements of their template; these inner selectors can be subjects to changes upon upgrades. The most effective way to Style your solution and easily adjust to upgrades is to use the Servoy default Theme.
Common components Selectors
Label, DataLabel
.bts-label
Button
.bts-button
Image
.svy-mediafield
Calendar
.bts-calendar
Calendar inline
.bts-calendar-inline
Checkbox
.bts-check
Choice Group
.bts-radiogroup
Combobox
.bts-combobox
HTML Area
.svy-extra-htmlarea
Slider
.svy-slider
Spinner
.svy-extra-spinner
TextArea
.bts-textarea
TextBox
.bts-textbox
Textbox Group
.bts-textbox
Native Data List
.bts-list
Native Select
.bts-select
Type Ahead
.bts-typeahead
select2tokenizer
.svy-select2-autotokenizer
Note if you have an existing Servoy solution using legacy classic components the bts-
prefix would be replaced by the svy-
prefix, example: .svy-label .svy-button
.
Floating components Selectors
All Floating components are placed within a .svy-form-floating
div
Floating Calendar
.bts-floatlabelcalendar
Floating Combobox
.bts-floatlabelcombobox
Floating Textarea
.bts-floatlabeltextarea
Floating Textbox
.bts-floatlabeltextbox
Floating Type Ahead
.bts-floatlabeltypeahead
Grids Selectors
Data Grid, Power Grid
.ag-table
Tanle
.svy-table
Other components Selectors
Navbar
.bts-extra-navbar
Sidenav
.svy-extra-sidenav
Treeview
.treeview
DBTreeview
.dbtreeview
Form Containers Selectors
Form Container
.svy-container
Tab Panel
.bts-tabpanel
Accordion
.bts-accordion
Split Panel
.svy-extra-splitpane
Collapse
.svy-collapse
Form Component
.svy-formcomponent
List Form Component
.svy-listformcomponent
Form parts Selectors
Form
.svy-form
Header
.svy-header
Body
.svy-body
Footer
.svy-footer
Reconnecting feedback
When the NGClient detects communication issues with the server, a message is shown. This message can be styled and the text can be set using servoy i18n.
The message is a div styled using class svy-reconnecting
:
.svy-reconnecting {
color: red;
}
The message is defined by key servoy.ngclient.reconnecting
:
Loading Indicator
By default NGClient will set the wait mouse cursor on body and all its elements - when a request to the server takes a while. Starting with Servoy 2019.03 it will also show a default loading animation (bottom of page).
The default loading animation can be customized directly from the solution's .css
(or .less
) file. It is made up of a parent div (with class "loading-i-holder"
) and 5 child divs (with class "lii-shape"
on all of them and then each with it's own class from "lii-1"
up to "lii-5"
). You can change colors, position, animation and whatever is supported by CSS. For example if you want to make the shapes blue instead of orange you just add this to the solution style sheet:
// changing default loading indicator color(s)
.lii-shape {
background-color: blue;
}
If you want for example the animation to not be shown at all you could for example add this to solution .css:
// hiding the indicator completely
.loading-i-holder {
display: none;
}
There is another class selector, svy-reconnecting-overlay, which is used to define the css transition. The transition also has a delay (default) half a second in order to avoid this message showing when there is a network hiccup. The delay can be changed from solution css:
.svy-reconnecting-overlay.ng-hide-remove {
transition-delay: 10s !important;
}
Using media file from LESS/CSS
Is possible to import other LESS/CSS files and reference other media files such as images or icons.
If mymedia.gif exists in media files, you can use if in the style as background-image: url("mymedia.gif");
or background-image: url("myimages/mymedia.gif");
if the image is placed in the subfolder myimages.
Importing other .less/.css files in the main solution .less/.css
In the .css/.less
file that you choose as a property of the solution you can also reference other .css/.less files from solution media.
You can import other LESS files using the import statement: example @import "mySecondStyle.less"
;
If you import other .css
files, you need to add to the url the argument "t=##last-changed-timestamp##"
; this is required in order to discard the browser cached version of the css, when a new WAR is deployed (##last-changed-timestamp##
will be replaced during WAR export with the last changed timestamp of the parent CSS).
For example if you have another .css
file in media "stylesheets/ui_customisation.css"
(the path is relative inside media to the solution-css-or-less file that does the import) you can reference that by adding this line at the beginning of you solution's .css/.less
: @import "stylesheets/ui_customisation.css?t=##last-changed-timestamp##";
Dynamic Styling
Style sheets can be changed programmatically, allowing a developer to change styles to different users' taste or to have periodic style changes in their applications. This can be done using the overrideStyle function.
The override style can be used to apply to the solution any style from an existing CSS/LESS file present in the media files or with a generated CSS/LESS file. In the example below the solution's default style is replaced with the style tenantX.less
which is a different LESS file present in the media folder of the solution.
application.overrideStyle('mySolution.less', 'tenantX.less'); // tenant.less can be a solution model changed or generated file, then it will be recompiled at runtime.
In this example instead the solution's style is replaced with a newly generated style. Using LESS variables in style allows you to easily adjust the theme with the overrideStyle
by setting only few variables value dinamically.
var media = solutionModel.getMedia('myDynamicStyle.less');
media.setAsString('@import "mySolution.less"; @main-color:green; @my-border-radius:2px;');
application.overrideStyle('mySolution.less', 'myDynamicStyle.less');
Last updated
Was this helpful?