Introducing Enhance Styles 5.0
by Cole Peters
@colepeters@mastodon.online
on
Today, we’re excited to announce the release of Enhance Styles 5.0, a major upgrade to the configurable styling library included with all Enhance projects. This release introduces:
- Fluid modular scales for typography and layout, exposed through utility classes and custom properties
- CSS logical properties for margins, padding, borders, sizes, insets, and text alignment, exposed through utility classes
- Updates and revisions to flexbox and grid classes
For existing Enhance projects, you can upgrade to this new release of Enhance Styles via one of two methods:
- If you already have
@enhance/arc-plugin-styles
listed in your project’s dependencies: update this package to the latest release by runningnpm i @enhance/arc-plugin-styles@^3.0.1
- If you don’t have the styles plugin listed in your project’s dependencies: upgrade the
@enhance/arc-plugin-enhance
package to the latest release by runningnpm i @enhance/arc-plugin-enhance@^6.0.1
Being a major release, 5.0 does contain breaking changes. We don’t ship breaking changes often, but for this release of Enhance Styles, we identified a couple key areas of improvement that couldn’t be introduced in any other way. Despite these breaking changes, the upgrade path should be painless (and we’ll cover that throughout this article).
Without further ado, let’s examine these updates in detail!
Fluid modular scales
One of the most powerful features of Enhance Styles (and other atomic or utility class focused styling libraries) is the concept of using modular scales for parametric design and development. Modular scales are of particular value in design systems, where their values can be used for typography as well as layout.
We’ve revised our approach to modular scales in two ways for this new release of Enhance Styles.
First: we’ve adopted fluid modular scales. You might be familiar with the concept of fluid scales thanks to tools like Utopia — but if you’re not, our new Enhance docs on modular (and fluid) scales have you covered! Head on over to the docs for a deep dive. In short, fluid modular scales allow design aspects like font sizes and layout spacing units to scale fluidly between a minimum and maximum viewport size, thus reducing the amount of breakpoint specific CSS you need to write, and providing a great user experience regardless of the size of the user’s device or browser window.
As designers and developers, we can stop fussing about a potentially infinite array of typographic and spatial variations, and instead focus almost entirely on the extremes: ‘What size should this type be at a minimum, and what size should it be at a maximum?’ Or, ‘How far away should element A be from element B at a minimum, and how far away should it be at a maximum?’
— Me, a couple articles ago
Along with adopting fluid modular scales, we’ve also updated Enhance Styles to allow for the generation of two distinct scales: one for type sizes, and another for layout spacing sizes (used for margins and padding, as well as for gaps in flexbox and grid layouts). In our experience, scales for typography and scales for layout spacing can have differing requirements; for example, typographic scales rarely need more than one or two negative steps on the scale (as font sizes quickly approach the illegible as they reduce past the base size), but spacing scales can make great use of a range of smaller sizes. Additionally, you may want your spacing scale’s intervals to increase or decrease at a faster rate than your type scale (or vice versa). Allowing for distinct configurations between the type scale and space scale means a greater range of use cases and design systems can be accommodated by Enhance Styles.
Both the type and the space scale are fully configurable, but come with some sensible defaults out of the box to get you started. Type scale values are baked into font size classes (e.g. .text2
or .text-1
), and space scale values are baked into classes for margins, padding, and gaps (e.g. .m4
, .p0
, or gap-2
). You can also use the scale values within your element styles using the generated custom properties (e.g. var(--text-2)
or var(--space--4)
).
For much more on Enhance Styles’ new fluid modular scales, including a full technical walkthrough, check out the new docs — or see the default scales in action in this tiny little demo!
Upgrading to the fluid modular scales
For the most part, this upgrade path should just be a matter of updating your Enhance Styles configuration file (if you have one — if you don’t, the upgrade should be automatic). For example, here’s an example of the old configuration shape:
{
"base": 16,
"scale": {
"steps": 12,
"ratio": "perfectFourth"
}
}
…and here’s an example of how to use these values with the new scales:
{
"typeScale": {
"steps": 12,
"viewportMin": 320,
"viewportMax": 1500,
"baseMin": 16,
"baseMax": 16,
"scaleMin": "perfect-fourth",
"scaleMax": "perfect-fourth",
},
{
"spaceScale": {
"steps": 12,
"viewportMin": 320,
"viewportMax": 1500,
"baseMin": 16,
"baseMax": 16,
"scaleMin": "perfect-fourth",
"scaleMax": "perfect-fourth",
}
}
Note that the above configuration will not produce fluidly scaling values, but rather reproduces the previous scale exactly. You would, at a minimum, need to set a larger baseMax
size for both your type and space scales in order to see any fluid resizing across viewport widths.
Also, note that the new type scale produces only 2 negative steps — thus, if you’ve used classes like .text-3
or .text-4
, these would need to be refactored to account for this change. However, as these type sizes would likely have been illegible, we expect this is not a common use case.
CSS logical properties
We want Enhance to be a great framework for everyone. But not everyone uses the left to right (LTR) writing system that CSS was originally based on. This is where logical properties come in. Logical properties are used in CSS layout modules to describe ‘logical’ directions based on the current writing mode, as opposed to physical directions. In the LTR writing mode, the block axis runs from the top to the bottom of the page, while the inline axis runs from the left to the right of the page. In a right to left (RTL) writing mode, the inline axis would run from the right to the left of the page, and so forth.
Logical properties allow us to write more robust styles, which are resilient to changes in writing modes. For those working in non LTR writing modes, or those who needs to internationalize their work, logical properties can save a ton of work, and help designers and developers reason about designs in a more logical way.
In order to accommodate these logical properties, we’ve switched our margin, padding, width/height, border, inset, and text alignment classes from using ‘physical’ direction abbreviations (t/r/b/l for top, right, bottom, and left) to using abbreviations for logical directions. So, for example, the .mt4
class, which applied the 4th spacing interval to the margin-top
property, now becomes .mbs4
, which will apply the 4th spacing interval to the margin-block-start
property.
The table below demonstrates each physical direction in the LTR writing mode, and its equivalent using logical properties:
LTR physical | LTR logical & abbreviation |
---|---|
top & bottom | block, b |
left & right | inline, i |
top | block-start, bs |
bottom | block-end, be |
left | inline-start, is |
right | inline-end, ie |
These abbreviations are combined with our margin and padding abbreviations, for example, to create our new margin and padding classes, e.g. mi-4
for setting the inline margins to the -5th spacing interval, or pbe2
for setting the block-end padding to the 2nd spacing interval.
Upgrading to logical properties
This upgrade path involves a little bit more refactoring, but much of this should be able to be accomplished with a little find and replace magic.
- For margin, padding, radius and border classes, replace physical direction abbreviations with logical direction abbreviations (see table above)
- For text alignment classes, replace
.text-left
with.text-start
and.text-right
with.text-end
- For the positioning reset classes
.t0
,.b0
,.l0
and.r0
, replace with.inset-<logical abbreviation>-0
, using the table above. The.trbl
class, used to zero out all insets, is replaced by the.inset-0
class. - For width classes, e.g.
.w-auto
or.w-100
,w
becomessi
(abbreviated for ‘size, inline’). - For height classes, e.g.
.h-auto
or.h-100
,h
becomessb
(abbreviated for ‘size, block’)
Updates to flexbox and grid classes
Finally, we’ve added some classes for properties that were previously missing for flexbox and grid layouts. You should now find options for any declarative flavor of the following properties:
align-items
(.align-items-<N>
)align-content
(.align-content-<N>
)align-self
(.align-self-<N>
)justify-content
(.justify-content-<N>
)justify-items
(.justify-items-<N>
)justify-self
(.justify-self-<N>
)
We also now support the place-
properties (-items
, -content
and -self
):
place-items
(.place-items-<N>
)place-content
(.place-content-<N>
)place-self
(.place-self-<N>
)
Migrating to the new flexbox and grid properties
Follow the table below when migrating to the properties mentioned above:
Before | After |
---|---|
.items-<N> |
.align-items-<N> |
.content-<N> |
.align-content-<N> |
.self-<N> |
.align-self-<N> |
.justify-<N> |
.justify-content-<N> |
Next steps
The new release of Enhance Styles goes a long way to adopting some of the most exciting design and development strategies on the web today. Especially when considering fluid type size and layout spacing, we’re looking forward to helping our users both cut down on repetitive, fragile code, and to delivering a better experience to a wider range of users. We also hope that folks working in writing modes other than LTR will make some great use of our new classes leveraging logical properties.
As part of our work to get this release out, we’ve also made a substantial overhaul of our styling documentation within the Enhance docs. We hope these will be useful to both new and existing users getting familiar with these changes.
With this release now out the door, we’ll be turning our attention to another kind of documentation — a dynamic, generated reference guide that will make both discovering and searching for Enhance utility classes a whole lot easier. Stay tuned for updates on this front!
In the meantime, as always, we can’t wait to see what you build with Enhance. Be sure to drop in to the Enhance Discord to let us know what you’re working on and what you think of the new Enhance styles, or to ask any questions you might have. You can also feel free to ping us on Mastodon!
Have fun, and happy styling!