🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
CSS BEM
This page was created by Hans.karlsen on 2019-06-30. Last edited by Wikiadmin on 2026-07-29.

You can use BEM (Block, Element, Modifier) selectors to target a specific MDriven Turnkey control, part of a control, or Designer-assigned style in your CSS.

What BEM means in Turnkey

BEM is a CSS naming convention: Block, Element, Modifier. In Turnkey, the natural block is one control placed from a ViewModel column, widget, or control.

BEM term Meaning in Turnkey Example
Block The outer div for one rendered control. When the ViewModel uses CSS Grid, this is the element placed in the grid. .tk-text-field
Element An inner part of that block. .tk-text-field__label
Modifier An additional class placed on the block through the control's Style ref in MDriven Designer. Use it to express a variation or state. .required, .status-missing

For example, a text field named Name can render as:

<div class="tk-component tk-text-field">
    <label class="tk-text-field__label">Name</label>
    <input class="tk-text-field__native">
</div>

In this example:

  • tk-text-field is the block.
  • tk-text-field__label and tk-text-field__native are elements of that block.
  • tk-component is a common class that Turnkey adds to every BEM block.

Choose the right selector

Use the narrowest selector that expresses the styling intent. Target an element when you need to change only that part of a control; target the block when the whole control needs the same treatment.

Goal Selector Example rule
Style every Turnkey control .tk-component .tk-component { margin-bottom: 0.5rem; }
Style all labels generated inside Turnkey controls .tk-component label .tk-component label { font-weight: 600; }
Style all text-field blocks .tk-text-field .tk-text-field { max-width: 28rem; }
Style only labels in text fields .tk-text-field__label .tk-text-field__label { color: #333; }
Style the editable native input in text fields .tk-text-field__native .tk-text-field__native { border-radius: 0; }
Style one control variation assigned in Designer block and modifier together .tk-text-field.required .tk-text-field__label { font-weight: 700; }

Turnkey block classes

Turnkey assigns the following block class according to the rendered control type. Each block is also assigned tk-component.

Control type Block class
Static text tk-static-text
Image tk-image
Text field tk-text-field
Checkbox tk-checkbox
Date picker tk-datepicker
Combobox tk-select
Grid tk-data-table
Group box tk-groupbox
Button tk-button
File upload tk-file-upload
Link tk-link
Text area (multiline text) tk-textarea
Number field tk-number-field
Float number field tk-float-field

Turnkey element classes

Turnkey uses these suffixes for inner parts of a BEM block:

Element suffix Purpose Example
__native The actual HTML control. .tk-text-field__native
__interactive The part that the user changes. For some controls, such as a checkbox, the native control can be hidden and a different element is used for interaction. .tk-checkbox__interactive
__label The control label. .tk-text-field__label
__content An enclosing inner content div. .tk-groupbox__content

Do not assume that every control renders every element suffix. Inspect the rendered HTML before writing a selector, especially when styling controls with custom presentations.

Add a modifier with Style ref

A modifier is a class that you add in MDriven Designer to distinguish one rendered control from another. Turnkey adds the Style ref as a separate class on the control block.

For example, to mark a Name text field as required:

  1. In the ViewModel Editor, select the ViewModel column or control for Name.
  2. Enter required in the Style ref field.
  3. Add a CSS rule that combines the text-field block with the modifier:
.tk-text-field.required .tk-text-field__label {
  font-weight: 700;
}

.tk-text-field.required .tk-text-field__native {
  border-color: #b00020;
}

The block then includes both classes:

<div class="tk-component tk-text-field required">
    <label class="tk-text-field__label">Name</label>
    <input class="tk-text-field__native">
</div>

This approach keeps the rule limited to required text fields. A rule such as .required would instead affect every element with that class.

Use a dynamic Style ref

You can make a Style ref an expression when the class must depend on ViewModel data. For example, a field can use status-missing when no car is selected and status-selected when a car is selected. Define both classes in your CSS, then have the Style ref expression return the appropriate class name.

.tk-text-field.status-missing .tk-text-field__native {
  border-color: red;
}

.tk-text-field.status-selected .tk-text-field__native {
  border-color: green;
}

Use meaningful class names that describe the UI meaning, such as status-missing, rather than a visual result such as red. This allows you to change the color later without changing the ViewModel expression.

Labels and omitted labels

A label is not always rendered. When a control has no label, Turnkey adds the NoLabel class to the div that encloses the control. Use it when a rule must apply only to controls without labels.

.tk-text-field.NoLabel .tk-text-field__native {
  margin-top: 0;
}

Scope a rule to one ViewModel

Turnkey adds a CSS class named after the ViewModel high in the rendered HTML hierarchy. Combine that class with BEM selectors when a style must apply in one view only.

For a ViewModel named WorkBoard, this rule changes text-field labels only in that ViewModel:

.WorkBoard .tk-text-field__label {
  font-weight: 700;
}

This is preferable to a global .tk-text-field__label rule when other views should retain their existing appearance.

Where to put CSS

BEM selectors describe what to target; they do not determine where CSS is stored or how themes are deployed. Use MDriven Turnkey theming for tkusercss.css, CSS custom properties, and deployment guidance. Use Theme as data when the application supplies CSS from data at runtime.

For page structure, CSS Grid placement, and the surrounding Turnkey layout wrappers, see Documentation:Layout and CSS. For Style ref behavior outside the BEM-specific approach, including formatting and table styling, see HowTos:Styling and CSS for Bootstrap, Angular and MVC.

See also