Currently, I am in the process of integrating RTL support into a vast framework. To achieve this, I have replaced all directional rules with mixins like:
a {
@include padding(0, 1px, 0, 0);
@include margin(0, 1px, 0, 0);
}
This implementation ensures that the appropriate padding/margin is applied based on the document's direction.
Each mixin presents cases for ltr
and rtl
.
The following code shows the results generated by these mixins:
[dir="ltr"] a {
padding: 0 1px 0 0;
}
[dir-"rtl"] a {
padding: 0 0 0 1px;
}
[dir="ltr"] a {
margin: 0 1px 0 0;
}
[dir="rtl"] a {
margin: 0 0 0 1px;
}
This approach works effectively but leads to duplicate selectors (2 per mixin). As a result, the CSS bundle size increases by 100kb (20%), primarily due to this repetition.
Desired outcome:
[dir="ltr"] a {
padding: 0 1px 0 0;
margin: 0 1px 0 0;
}
[dir="rtl"] a {
padding: 0 0 0 1px;
margin: 0 0 0 1px;
}
I am seeking post-processing solutions to consolidate duplicate selectors without disrupting the order of CSS execution.
Challenge:
For instance, consider the following code snippet:
b.s1 {
padding-left: 1px;
margin: 0;
}
b.s2 {
padding-left: 0;
margin: 1px;
}
b.s1 {
padding-left: 1px;
}
If I merge b.s1 upwards, it might lead to s2’s padding-left overriding it. Conversely, merging b.s1 downwards could result in s2's margin being overridden.
Is there a viable solution to address this challenge?
EDIT: Original Code
// Incorporate property for all sides
// @param {string} $prop
// @param {string} $top
// @param {string} $end
// @param {string} $bottom
// @param {string} $start
// @param {boolean} $content include content or use default
// ----------------------------------------------------------
@mixin property($prop, $top, $end: $top, $bottom: $top, $start: $end, $content: false) {
@if $top == $end and $top == $bottom and $top == $start {
@include multi-dir() {
#{$prop}: $top;
}
} @else if $top == $bottom and $end == $start and $top != null and $end != null {
@include multi-dir() {
#{$prop}: $top $end;
}
} @else if $end == $start and $top != null and $end != null and $bottom != null {
@include multi-dir() {
#{$prop}: $top $end $bottom;
}
} @else if $top != null and $end != null and $bottom != null and $start != null {
@include ltr() {
#{$prop}: $top $end $bottom $start;
}
@include rtl() {
#{$prop}: $top $start $bottom $end;
}
} @else {
@if $content == true { // TODO check if @content exists instead
@content;
} @else {
@include property-horizontal($prop, $start, $end);
@include multi-dir() {
#{$prop}-top: $top;
#{$prop}-bottom: $bottom;
}
}
}
}
// Integrate padding for all sides
// @param {string} $top
// @param {string} $end
// @param {string} $bottom
// @param {string} $start
// ----------------------------------------------------------
@mixin padding($top, $end: $top, $bottom: $top, $start: $end) {
@include property(padding, $top, $end, $bottom, $start);
}
// Integrate margin for all sides
// @param {string} $top
// @param {string} $end
// @param {string} $bottom
// @param {string} $start
// ----------------------------------------------------------
@mixin margin($top, $end: $top, $bottom: $top, $start: $end) {
@include property(margin, $top, $end, $bottom, $start);
}