Migration

Migrating from Tailwind CSS

A guide on how to refactor Tailwind CSS using Master CSS.

Overview

Tailwind CSS is a utility-first CSS framework that empowers you to select corresponding values for your requirements from a plethora of defined constraints, such as text-sm, pt-4, lg:w-9, and more.

Master CSS is a markup-driven CSS language with smart syntax that allows you to construct your user interface using structured and native-like syntax, such as font:14, pt:16, w:36@md, instead of referencing tables or relying on memory.

Our syntax concepts draw inspiration from Sass and TypeScript.


Declarations

Master provides various structured property types such as utilities, abbreviations, shorthands, and symbols, as well as automatic conversion of property unit values.

Learn more about style declarations.

Colon instead of dash

Use a colon :, similar to native CSS, to separate property names from values, rather than a dash -.

<p class="text-center"></p>
<p class="text:center"></p>

Delimiter instead of underscore

To avoid conflicts with spaces in class="a b", use the delimiter | to separate parameters within property values, instead of an underscore _.

<div class="shadow-[0_1px_2px_-3px_rgba(0,0,0,0.3)]"></div>
<div class="shadow:0|1|2|-3|rgba(0,0,0,.3)"></div>

You can observe that the reduced contrast of the delimiter |, as highlighted in Master's syntax highlighting above, is intentional to provide a smoother visual appearance that closely resembles native CSS's whitespace separator :

div { box-shadow: 0rem 0.0625rem 0.125rem -0.1875rem rgba(0,0,0,.3) }

We believe that | conveys a stronger separation meaning than _.

Non-abstract unit value

In Tailwind, identical values for different properties may have different constraint values. For example, border-4 sets to 4px, while m-4 sets to 1rem.

Master automatically converts units according to the characteristics of different properties and input values, making styles more predictable.

<div class="p-4">`4` means `1rem` in Tailwind</div>
<div class="p:4x"></div>
<div class="p:16">alternative</div>
<div class="p:1rem">alternative</div>

Whether to use 1/2 to represent 50% depends on your preference, for example, when setting height:.

<div class="h-1/2"></div>
<div class="h:1/2"></div>
<div class="h:50%">alternative</div>

Let's consider another example with border-radius.

<div class="rounded-md">`md` means `0.375rem` in Tailwind</div>
<div class="r:6"></div>
<div class="r:.375rem">alternative</div>

If you don't prefer the abbreviated notation like p:, r:, you can use the full names, such as padding:, border-radius:.

Decimal or percentage

Equivalent to native opacity: 0.2;.

<div class="opacity-20">`20` means `0.2` in Tailwind</div>
<div class="opacity:.2"></div>
<div class="opacity:0.2">alternative</div>

You can use decimals or percentages to adjust the opacity of colors.

<div class="bg-sky-500/75"></div>
<div class="bg:sky-50/.75"></div>
<div class="bg:sky-50/75%">alternative</div>

Selectors

Suffixed with :hover

Add pseudo-classes after the main body.

<div class="hover:bg-sky-700"></div>
<div class="bg:sky-70:hover"></div>

Suffixed with ::placeholder

Add pseudo-elements after the main body.

<div class="placeholder:italic"></div>
<div class="italic::placeholder"></div>

Suffixed with [data-attribute]

Add data attributes after the main body.

<div data-size="large" class="data-[size=large]:text-lg"></div>
<div data-size="large" class="text:18[data-size=large]"></div>

At-rules

Suffixed with @md

Add responsive breakpoints after the main body.

<div class="md:text-left"></div>
<div class="text:left@md"></div>

You can even use operators like @sm&<md, see the Responsive Design guide.

Suffixed with @landscape

Add media queries after the main body.

<div class="landscape:hidden"></div>
<div class="hidden@landscape"></div>

Not just media queries but feature queries and more.


Configuration

Add screens

Define responsive breakpoints using variable screens.

/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
screens: {
'sm': '640px',
'md': '768px',
'lg': '1024px',
'xl': '1280px',
'2xl': '1536px'
}
}
}
/** @type {import('@master/css').Config} */
export default {
variables: {
screen: {
'sm': 640,
'md': 768,
'lg': 1024,
'xl': 1280,
'2xl': 1536
}
}
}

No longer need redundant screen options.

module.exports = {
theme: {
screens: {
'sm': {'min': '640px', 'max': '767px'},
'md': {'min': '768px', 'max': '1023px'},
'lg': {'min': '1024px', 'max': '1279px'},
'xl': {'min': '1280px', 'max': '1535px'},
'2xl': {'min': '1536px'},
},
}
}

Liberate flexibility with syntax-first.

<div class="hidden@sm&<md">

Add media queries

Using at-rules to define media queries, feature queries, and even container queries.

/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
screens: {
'tall': { 'raw': '(min-height: 800px)' },
}
}
}
}
/** @type {import('@master/css').Config} */
export default {
at: {
tall: 'media (min-height: 800px)'
}
}

Strategies

Alternative to @apply

Use styles to abstract styles instead of @apply.

@tailwind base;
@tailwind components;
@tailwind utilities;
.btn {
@apply py-2 px-5 bg-white hover:bg-black;
}
/** @type {import('@master/css').Config} */
export default {
styles: {
btn: 'p:2x|5x bg:white bg:black:hover'
}
}
<button class="btn">Submit</button>

Gap instead of space

To add space between boxes use gap: instead of space-.

<div class="flex space-x-4 space-y-4">
<div class="flex gap:4x">
<div>01</div>
<div>02</div>
</div>

Tailwind uses the > * + * universal selection to implement box spacing, which has some performance overhead. It's better to add flex or grid to the parent container and use the native gap property.

Getting Started
Introduction to Master CSS

The CSS language and framework for rapidly building modern and high-performance websites.

© Aoyue Design LLC.