Skip to content

Use CSS Logical Properties and Values for Styling #13619

@tay1orjones

Description

@tay1orjones

The problem

Component styling currently uses typical properties for positioning and sizing, things like margin-top, padding-left, border-right, etc.

These properties are static and are not impacted by the writing mode. When a page is rendered in rtl, padding-left does not automatically become padding-right. It is static on the left.

Due to this, we currently recommend that applications using Carbon with a requirement to support rtl mode use a postprocessor like RTLCSS. RTLCSS converts these static properties into their logical inverse property for rtl mode( padding-left becomes padding-right). The output stylesheet can then be loaded when the document is in rtl mode and override the default styles provided by Carbon.

We do not have RTLCSS as part of the pipeline within the monorepo. This means that if we were to alter the writing mode in the storybook canvas, the components would not have appropriate styling to be rendered correctly.

The solution

We should instead use Logical Properties and Values to specify styling that will be impacted by the writing mode.

From the MDN docs:

CSS Logical Properties and Values is a module of CSS introducing logical properties and values that provide the ability to control layout through logical, rather than physical, direction and dimension mappings.
...
Logical properties and values use the abstract terms block and inline to describe the direction in which they flow. The physical meaning of these terms depends on the writing mode.

In effect, this means that we can specify things like padding, margin, text-alignment, etc. to be dependent on the writing mode rather than static right/left/top/bottom values.

Examples

Here's an example from this excellent article on the topic. It does a much better job of explaining all the facets of this than I can do here, please read.

/* Without logical properties and values */
.my-element {
  padding-top: 2em;
  padding-bottom: 2em;
  margin-left: 2em;
  position: relative;
  top: 0.2em;
}

/* With logical properties and values */
.my-element {
  padding-block-start: 2em;
  padding-block-end: 2em;
  margin-inline-start: 2em;
  position: relative;
  inset-block-start: 0.2em;
}
- [ ] Make a new WIP branch for everyone to work off of (or do work against main if we can keep the stylelint rule to warning instead of error)
- [ ] Add a stylelint rule to enforce logical properties https://github.com/csstools/stylelint-use-logical
- [ ] Phase 1 mob programming session (do as many as possible in a timeboxed meeting together in a single sprint) - make changes to the WIP branch
- [ ] Phase 2 mob session (if needed)
- [ ] Phase ... mob sessions (if needed)
- [ ] Merge WIP branch into main

With this mapping I think we could get most (all?) of the way there in a single sprint https://github.com/csstools/stylelint-use-logical#property-and-value-mapping

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

Status
✅ Done
Status
Completed 🚢

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions