mlut documentation

2 #concepts Basic concepts

Before reading the documentation, learn mlut basic concepts.

Source: content/main.css, line 121

2.1 #concepts.naming Naming algorithm

Almost all abbreviations in mlut are compiled by one algorithm. Below will be a simplified algorithm for compiling the abbreviations of the utilities names. Later it will be supplemented

  1. get all CSS properties that starts with one letter
  2. make ranking of them by popularity or alphabet if the popularity is not possible to calculate. Popularity for properties is calculated based on Chrome platforf statistic
  3. compose groups of properties that starts with one word. Select a group leader: repeating first word. Leader rating is the max rating of the property from group
  4. make abbreviations by the scheme below. Important notes:
    • in descending order by rating, regardless of the relationship of the property to the group
    • abbreviate the property, group leader or the first word property so that it does not intersect with already abbreviated properties
    • subsequent abbreviations of all properties of the group and properties with the same initial word should begin with the same abbreviation, which was previously done
    • if the group contains 2 or more subgroups (excluding logical: block, inline), its leader is abbreviate by at least 2 letters: Fn, Bd
    • properties from 3 and less letters do not abbreviate: Gap, All
    • properties and subproperties with physical directions have fixed abbreviations: T, R, B, L, I
    • subsequent words in properties are abbreviated by the same rules recursively

The one abbreviation scheme:

  • the name must be abbreviate to the first letter of the source word.
  • if the name is from several words, then every word is abbreviate to one letter
  • if two names have the same first letter, then in the next name, when sorting them by the rating, the letter is added
  • if the name is from several words, then the letter is added, depending on the name affiliation to the group

The order of adding the letter:

  1. consonant of the next syllable. If the next syllable begins to vowel, then we take the nearest previous consonant from it
  2. next consonant
  3. next vowel without a jump through the consonant

Examples you can see in the utils reference. More visual examples here will appear later.

Source: content/main.css, line 131

2.2 #concepts.util Utility

An entity that, depending on the parameters, does 1 action with the element styles. Utilities can change both one CSS property and several.

Source: content/main.css, line 166

2.2.1 #concepts.util.syntax General syntax

Utilities consist of out: utilities syntax

  1. CSS at-rule: breakpoints, @supports, ect
  2. pre-states - part of selector before the utility class name
  3. name
  4. value
  5. post-states - part of selector after the utility class name

Each part is separated by the lower underscore.

Source: content/main.css, line 176

2.2.2 #concepts.util.naming Naming

By origin, the utilities are:

  • Common - named and work like CSS properties.
  • Custom - affects several CSS properties or manages custom properties. Their names begin with a hyphen. All utilities that you will add, it is recommended to name as custom.

The names of utilities are written in upper CamelCase and can only contain letters. Thanks to the first capital letter, they are easy to add to an existing project without fear of name conflicts.

Source: content/main.css, line 195

2.2.3 #concepts.util.components Components

To work with utilities in mlut, the parsing to parts (components) is used. Most of them correspond to the usual syntax. The utility divides to this components:

  • at-rules
  • pre-states
  • post-states
  • important: ! modifier at the end of the utility value adds !important to CSS
  • value: it can be a separate value, the name of the utility, group etc

Here is an example, as the utility will be parsed to the components:

@debug ml.parse-util('<sm_:f:>_D!_h::^sub');
// (
//   'at-rules': '<sm',
//   'pre-states': ':f:>',
//   'post-states': 'h::^sub',
//   'important': true,
//   'value': 'D',
// ),

Note that the order of components is important.

Most of the components in the mlut is convertible. This means that if the component or part of it correspond the rules of conversion, it will unfold into some CSS value. How to convert different components, you can read below in the relevant sections. If the mlut does not know how to convert the component, the behavior will depend on its type.

Source: content/main.css, line 210

2.2.3.1 #concepts.util.components.syntax Utility Generation Syntax (AOT)

Utility Generation Syntax - is the way to describe, with which components we want to generate utilities. It is similar to the syntax utilities in the final code, but has a number of differences:

  • components of the same type are separated by spaces
  • by default, the utilities with the components of each type are generated separately. It means that: xl_^:h_Bdb_h,f => xl_Bdb, ^:h_Bdb and Bdb_f
  • keywords are used, for explicit instructions, with what components we need utilities and not only: BpAll ArSt _Bdb_h

This syntax is used in all places where utilities, utils groups, ranges, etc. are generated.

Source: content/main.css, line 240

2.3 #concepts.values Values

The values of utilities are almost arbitrary. That is, if the value is not converted, it appear in the CSS without changes.

To explicitly prevent conversion, use the = before the value. Also, use = before the value in quotes '': Ct='test'_af, since in the future quotes will be used in the values without separator.

@include ml.mk-util('Ml', (5, 5exe, '=5'));

// CSS
.Ml5 {
	margin-left: 5px;
}

.Ml5exe {
	margin-left: 5exe;
}

.Ml\=5 {
	margin-left: 5;
}
Source: content/main.css, line 253

2.3.1 #concepts.values.type Types

mlut has the following types of values that partially intersect with CSS data types. In the examples below will use a function that get a CSS value of the utility.

Source: content/main.css, line 282

2.3.1.1 #concepts.values.type.abbr Abbreviations

In the values of some utilities you can use the names of other utilities.

@debug ml.uv('Tsp-bdc'); // border-color
Source: content/main.css, line 356

2.3.1.2 #concepts.values.type.color Color

You can use both HEX colors and color names set by the user. Read more about adding your colors here. With colors, you can specify the opacity modifier *. This converter is used to convert opacity. With modifier, you can use CSS variables or global keywords in any position:

@debug ml.uv('C#60c*20p'); // rgba(102, 0, 204, 0.2)
@debug ml.uv('C-red0*$co'); // rgba(204, 0, 102, var(--ml-co, 1))

If a variable is specified as opacity, then by default, it will have fallback 1.

Source: content/main.css, line 321

2.3.1.3 #concepts.values.type.css_var CSS variables

Their names begin with $ written in lower camelCase and may contain numbers. They can be used almost everywhere, even as part of a complex value, for example in fractions:

@debug ml.uv('W1/$div'); // calc(1 / var(--ml-div) * 100%);

To specify a fallback, use ?. In the fallback, you can specify any value, including another variable with fallback:

@debug ml.uv('W-$myCard?200'); // var(--ml-myCard, 200px)
@debug ml.uv('W-$myCard?$defWd?150'); // var(--ml-myCard, var(--ml-defWd, 150px))
Source: content/main.css, line 305

2.3.1.4 #concepts.values.type.gkw Global keywords

Similar to ordinary, but differ in that they can be used in any utility. You can add your global keywords in the settings. It is recommended to use the prefix, for example: gMyKw. You can find the default mlut global keywords here.

@debug ml.uv('W-ih'); // inherit
Source: content/main.css, line 345

2.3.1.5 #concepts.values.type.kw Keywords

Keywords - abbreviations that comply with CSS keywords. They are written Camel Camel Case and may contain numbers. How to add your keywords look here.

@debug ml.uv('D-if'); // inline-flex
Source: content/main.css, line 334

2.3.1.6 #concepts.values.type.number Number

Numbers can be both with units of measurements and without. Float values are allowed, and fractions also can be used in the default conversion type:

@debug ml.uv('Fnw100'); // 100
@debug ml.uv('Ml3r'); // 3rem
@debug ml.uv('W1/4'); // 25%
Source: content/main.css, line 292

2.3.2 #concepts.values.convert Conversion type

In different utilities, the values will be converted in different ways. Conversion type is a rule by which the value will be converted. It consists of a sequence of converters and keywords. Conversion type is specified in the conversion option of utilities. For details on conversion and existing types, see here.

Source: content/main.css, line 367

2.3.3 #concepts.values.multi Multiple values

For any utility you can specify multiple values. Instead of a blank used ;:

@debug ml.uv('Bd3;sec0;d'); // 3px #0c6 dotted

In some utilities, you can specify several lists of values. To do this, use the same separator as in CSS: / or ,

@debug ml.uv('Bdrd1r;2/5p'); // 1rem 2px / 5%

The separator for multi-list is specified in the multi-list-separator utility option. Please note that each value is converted separately. The prevent-conversion token = also applies to each value in the list separately:

@debug ml.uv('M1r;=10x'); // 1rem 10x
Source: content/main.css, line 377

2.3.4 #concepts.values.sep Separators

Depending on the value type, different separators between the name and value of the utility are used. By default, only for strings without quotes (including empty) and CSS variables, the separator - are used: Txd-u, C-$prime. For all other values, separators are not used: W100p, Fnw700, but you can set them in the settings.

= token will also be a separator if you want to prevent conversion: -Mut=5.

Source: content/main.css, line 398

2.3.5 #concepts.values.important CSS important

At the end of the value or their sequences, you can specify ! which will add the CSS !important to the final value. If the utility affects several properties, then !important adds to each.

@include ml.apply('M2r;12! -I2r!');

// CSS
.M2r\;12\! {
	margin: 2rem 12px !important;
}

.-I2r! {
	top: 2rem !important;
	right: 2rem !important;
	bottom: 2rem !important;
	left: 2rem !important;
}
Source: content/main.css, line 410

2.3.6 #concepts.values.negation Negation

The negation is denoted by - before the value and works everywhere where it is appropriate. With numbers, with CSS variables and with keywords, if the final value may be negative.

@include ml.mk-util('Ml', ('2/-8', -0.7, '-$myVar'));

// CSS
.Ml2\/-8 {
	margin-left: -25%;
}

.Ml-0\.7 {
	margin-left: -0.7rem;
}

.Ml--\$myVar {
	margin-left: calc(var(--ml-myVar) * -1);
}
Source: content/main.css, line 435

2.4 #concepts.at_rules At-rules

At-rules component may consist of breakpoints and rules. To specify breakpoint, just write it name: lg_D-f. To add rule, specify @ before its name: @s:ctv_D-g. Breakpoints can only be specified 1 time in the entire component and only at the beginning, and rules - as much as you need.

@include ml.mk-util('D', ('xl_', '@s:ctv_g'));

// CSS
@media (min-width: 1200px) {
  .xl_D {
    display: block;
  }
}

@supports (content-visibility: auto) {
  .\@s\:ctv_D-g {
    display: grid;
  }
}

In all at-rules, you can create complex conditions using the : and , operators, which corresponds and and or in CSS. In some examples below, functions for at-rules conversion will be used for brevity.

@debug ml.convert-ar-media('pr:h>gSm:dm,p-c:w>=90r'); // print and (min-height: #{ml.bp(sm) + 1}) and (display-mode: fullscreen), (pointer: coarse) and (min-width: 90rem)

And of course, Rules can be used in any order and in any combination.

Source: content/main.css, line 461

2.4.1 #concepts.at_rules.bp Breakpoints

The width of the screen on which the styles change. The default mobile-first approach is used, so breakpoints are converted to min-width media queries. How to configure breakpoints see here.

If required max-width, add the < before the breakpoint:

@debug ml.convert-ar-bp('<sm'); // (max-width: 519px)

Or use operators to create a range:

@debug ml.convert-ar-bp('sm:md,xl'); // (min-width: 520px) and (max-width: 767px), (min-width: 1200px)
Source: content/main.css, line 493

2.4.2 #concepts.at_rules.container @container

With the @container rule you can use both generic and named container queries

@include tools.apply('@c:w>600_C-red');
@include tools.apply('@c:box:h>20r_P5u');

// CSS
@container (min-width: 601px) {
  .\@c\:w\>600_C-red {
    color: red;
  }
}

@container box (max-height: 20rem) {
  .\@c\:box\:h\<\=20r_P5u {
    padding: 1.25rem;
  }
}
Source: content/main.css, line 608

2.4.3 #concepts.at_rules.layer @layer

With the @layer rule, you can put some utils to different cascade layers

@include ml.apply('@l:utils_C-red');

// CSS
@layer utils {
  .\@l\:utils_C-red {
    color: red;
  }
}
Source: content/main.css, line 589

2.4.4 #concepts.at_rules.media @media

In @media rule, you can use the type, features and custom queries. There are two media types:

  • pr - print
  • s - screen

@media is the default rule. To choose it, just write @ and then specify queries. The default rule can be selected in the settings.

@include ml.mk-util('@:w>=gSm:o _D', 'if');

// CSS
@media (min-width: 520px) and (orientation: landscape) {
  .\@\:w\>\=gSm\:o_D-if {
    display: inline-flex;
  }
}
Source: content/main.css, line 510

2.4.4.1 #concepts.at_rules.media.feat Media features

Work almost as well as utilities. Key differences:

  • if the feature has only two values, then to check its presence, you can simply write a name. For checking lack, you can use the none keyword. Note that some features also have the default value.
  • if the features can check the range of values, then you can use the range syntax from The Media Queries Level 4
@debug ml.convert-ar-media('ah'); // (any-hover)
@debug ml.convert-ar-media('h-n'); // (hover: none)
@debug ml.convert-ar-media('dm'); // (display-mode: fullscreen)
@debug ml.convert-ar-media('c<256'); // (max-color: 255)
Source: content/main.css, line 532

2.4.5 #concepts.at_rules.supports @supports

In @supports rule, you can check the support of properties and values of any utility from the registry. To check the current value of the utility used, leave the rule blank.

@include ml.mk-util('Ps', '@s:d-flr_sk');
@include ml.mk-util('D', '@s_f');

// CSS
@supports (display: flow-root) {
  .\@s\:d-flr_Ps-sk {
    position: sticky;
  }
}

@supports (display: flex) {
  .\@s_D-f {
		display: flex;
	}
}

To check the property, it is not necessary to specify the value:

@debug ml.convert-ar-supports('apcr'); // (aspect-ratio: initial)

You can also use this-utility alias & in a complex condition.

@debug ml.convert-ar-supports('d-ig:&', ('name': 'Jc', 'value': '-se'); // (display: inline-grid) and (justify-content: space-evenly)

To check the lack of support, add an operator ! before the utility:

@debug ml.convert-ar-supports('!d-ig'); // (not (display: inline-grid))

Please note that in one supports rule, only one type of the operator is supported for a combination of expressions. When using both immediately, an error will appear

@debug ml.convert-ar-supports('ps-sc,h1vh:m-a'); // ERROR: Different operators are not allowed in one abbreviations list
Source: content/main.css, line 548

2.4.6 #concepts.at_rules.custom Custom expressions

You can add custom expressions to any at-rule. Regardless of the name you specify, custom expressions always begin with -. See in the settings how to add it.

Source: content/main.css, line 634

2.5 #concepts.states States

In the states you can use pseudo-class, pseudo-elements and almost everything that CSS selectors allow. States are two types: pre and post, depending on the position in the CSS utility selector. In both of them, you can use the same parts.

@include ml.mk-util(':h _D_ af', 'f');

// CSS
.D-f {
	display: flex;
}

:hover .\:h_D-f {
	display: flex;
}

.D-f_af::after {
	display: flex;
}

In essence, the states is a simplified CSS selector list. To combine the states, use :, and for the separation of selector to the lists - ,. For a space in the selector, use :: or : if post-state is the first in the list.

@include ml.mk-util('D_ h,f h:b :fc', '');

// CSS
...

.D_h\,f:hover,
.D_h\,f:focus {
	display: block;
}

.D_h\:b:hover::before {
	display: block;
}

.D_\:fc :first-child {
	display: block;
}

You can use almost arbitrary parts in any order: combinators, classes, etc. In terms of conversion, the states are similar to the values of utilities:

  • unconvertible parts will fall into the selector unchanged
  • use = to prevent conversion
@include ml.mk-util('=a. h1+ _D_ .js:a', '');

// CSS
...

a.\=a\._D {
	display: block;
}

h1 + .h1\+_D {
	display: block;
}

.D_\.js\:a.js:active {
	display: block;
}

Full list of existing states see in the configuration.

Source: content/main.css, line 644

2.5.1 #concepts.states.special Special states

There are several special states that are converted by a special way.

Source: content/main.css, line 713

2.5.1.1 #concepts.states.special.ctx Context

With the help of a context, the utilities can react to the state of the container, adjacent item etc. It is denoted by ^ and is just an alias for .-Ctx. Add this class to markup, and in the states of utilities, make a combination for the necessary behavior.

You can also specify the name of the context. Allowed lower camelCase and numbers.

@include ml.mk-util('^:h ^one:lc:>_D', 'f');

// CSS
...

.-Ctx:hover .\^\:h_D-f {
	display: flex;
}

.-Ctx-one:last-child > .\^one\:lc\>_D-f {
	display: flex;
}
Source: content/main.css, line 721

2.5.1.2 #concepts.states.special.not Not

To use a pseudo-class not, add ! before any part of state:

@include ml.mk-util('D_!fc !input', '');

// CSS
...

.D_\!fc:not(:first-child) {
	display: block;
}

.D_\!input:not(input) {
	display: block;
}
Source: content/main.css, line 745

2.5.1.3 #concepts.states.special.tu This utility alias

As in @supports, & can be used in the states. To increase specificity, it can only be used in post-states so many times as much as you need:

@include ml.apply('D_&');

// CSS
...

.D_\&.D_\& {
	display: block;
}
Source: content/main.css, line 767
Source: content/main.css, line 785

2.6 #concepts.custom_unit Custom units of measure

In mlut there are 3 custom units:

  • u - space unit
  • gg - grid gutter
  • gc - grid column. Used only in the legacy grid-system

You can set the custom units values in the settings.

Source: content/main.css, line 795

2.6.1 #concepts.custom_unit.gg Grid gutter

The value of this unit depends on the CSS variable --ml-gg. Due to this, it value can be changed dynamically. By default --ml-gg = 3u but increase to 4u on the lg breakpoint.

@debug ml.uv('Ml-2.5gg'); // calc(var(--ml-gg) * -2.5)
Source: content/main.css, line 821

2.6.2 #concepts.custom_unit.su Space unit

Unit of measurement to create a scale of sizes and indents in your design system. By default 1u = 0.25rem(4px).

@debug ml.uv('Fns6u'); // 1.5rem
Source: content/main.css, line 810