Combining CSS styles

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);
}

Answer №1

I came up with a targeted solution for the issue with dir, which is the primary concern for me, rather than the minor duplications that make up just a small portion of my bundle.

The fix is straightforward and effective, taking 0 seconds to execute. It doesn't involve merging upwards or downwards, but instead eliminates the existing code and appends a new chunk containing the combined directional code at the end. This method works well for directional content since it preserves the order and specificity of each element.

function joinDirections(contents) {
  // This handles multi-directional selectors like `[dir="ltr"] sel, [dir="rtl"] sel`,
  // where the ltr information is retained as `sel, [dir="rtl"] sel` remains unaffected.
  const dirExp = /\[dir="(.*?)"\](.*?){\s*([^}]*?)\s*}/gm;

  let directions = {};

  let matches;
  while (matches = dirExp.exec(contents)) {
    if (!(matches[1] in directions))
      directions[matches[1]] = {};
    if (!(matches[2] in directions[matches[1]]))
      directions[matches[1]][matches[2]] = '';
    directions[matches[1]][matches[2]] += matches[3];
  }

  contents = contents.replace(dirExp, '');
  let directionalContents = '';

  Object.keys(directions).forEach(dir => {
    Object.keys(directions[dir]).forEach(selector => {
      directionalContents += `[dir="${dir}"]${selector}{${directions[dir][selector]}}\n`;
    });
  });

  return contents + directionalContents;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

If the text width of a label exceeds the total width of its container, intelligently display a sub-string based on pixel calculations

I am looking to shorten the text inside a label if its width exceeds the total width of its container. Instead of displaying the full text, I want to display a sub-string of it. if (SensorType.Text.Length >= 25) { SensorType.Text = SensorType.Text ...

The Carousel feature functions properly with 3 or more slides, but malfunctions when there are only 2 slides present

After implementing a minimal carousel, I discovered that it functions perfectly with 3 or more slides. However, as soon as I remove some slides, issues start to arise. Some of the problems I encountered include: The sliding animation is removed on ' ...

Is there a way to customize the hover effect on this navigation link in Bootstrap that includes a span and an icon from Bootstrap?

<li class="nav-item mt-3"> <a href="#" class="nav-link px-2 d-flex justify-content-start align-items-center"> <i class="nav-icon bi bi-calculator-fill fs-4"></i> ...

Determining the total of input values based on identification number

Can anyone help me figure out how to calculate the total sum of the values entered using IDs? I've been struggling with it and can't seem to get it to work. Your assistance would be greatly appreciated. <input type="number" id=&quo ...

Customizing Material-UI Select Styles

I have been attempting to customize the appearance of Material-UI's <Select> component with variant="outlined". In this particular scenario, my objective is to hide the dropdown icon and set padding-right to 0px. Based on my interpretation of t ...

Experiencing difficulties with utilizing height percentages for CSS divs

Despite encountering similar issues with others, I am still unable to resolve the problem on my own. Your assistance is greatly appreciated. Currently, I am developing a guestbook in PHP using an HTML template. The issue I am facing is that the div elemen ...

The gulp-stylus plugin fails to compile files due to an out-of-memory issue

Whenever I attempt to use the gulp-stylus plugin for compiling my stylus files, I encounter an issue. After running gulp stylus, gulp initiates the task "stylus," causing my CPU usage to spike up to 100%. Eventually, I receive this error message: FATAL ERR ...

CSS Alignment in React with Material UI

Is there a way to align one button to the left while centering the other two? To see an example in Codesandbox, please visit HERE <DialogActions sx={{ justifyContent: "center" }}> <Button>Left</Button> <Button on ...

Developing User-Friendly Websites with Responsive Design

While I was working on my project, I realized that using only pixel values in tables and sidebars was a big mistake. This caused issues because if someone had a different screen resolution, my website would look distorted and unappealing. Could you please ...

Slider in MaterialUI featuring a vibrant spectrum of colors

Currently, I am delving into MaterialUI and my focus is on creating a range slider. I came across this example that I found useful: https://material-ui.com/components/slider/#range-sliders My goal is to assign different colors to the "high," "medium," and ...

Toggle Div Visibility with Span Value Change

In my quiz, there is a span that displays the sum of checked checkboxes. Depending on the value in the span, I want to show or hide two different divs. Currently, my code hides the divs but does not show them. Please help! <div class="results center"&g ...

Tips for creating PrimeNG tables with columns that automatically adjust in size

Is there a way to automatically adjust and resize the columns in my PrimeNG table? I'm looking for a method to make this happen. Can you help me achieve this? ...

Fixed table layout prevents table cells from expanding inside a 100% width table row with absolute positioning, while also ensuring that the elements do not collapse

I'm struggling to understand this, as I am not very well-versed in CSS. I would consider myself more of a beginner than an expert. The reason why I am using relative/absolute is because I am working with dynamically paginated tables from large datase ...

The Gulp task is failing to generate the CSS file

Greetings! I have a task set up in my gulpfile.js as shown below: const gulp = require('gulp'); const sass = require('gulp-sass'); gulp.task('sass', function(){ return gulp.src('sass/*.scss') .pipe(sass()) ...

navigating through a specific section of a data chart

I need the first column of a table to stay fixed while the rest of the columns scroll horizontally. Here's the code I have: <div id="outerDiv"> <div id="innerDIv"> <table> <tr><td>1</td><t ...

Shorten certain text in Vuetify

Here's an example of a basic select component in Vuetify: <v-select :items="selectablePlaces" :label="$t('placeLabel')" v-model="placeId" required ></v-select> I'm looking to apply a specific style to all selec ...

Struggling with vertical and responsive image centering in Bootstrap 4?

I'm currently developing an Angular 6 app and facing an issue with centering an image on the home screen. Despite trying various solutions from this platform, the image always ends up positioned right next to the top navbar instead of being vertically ...

Tips on how to align text vertically next to an image

I am struggling to vertically center the text alongside an image on my website. Despite my efforts, I can't seem to get it right. Do you have any suggestions on why this might be happening? I've tried searching for a solution but haven't had ...

Comparing the impact of mixins styles versus additional style rules

I have customized mixins for a red button. For example: .btnRed{ background:red; color:white; border-radius:3px; min-width:200px; font-size:18px; } I typically use this to style my main buttons, but for one specific button, I n ...

Customizable styling using SQL and PHP

I've reached a dead end with this issue. Here's the current situation: When User 1 clicks "not available," the background of a div turns red and updates on all other users' screens. CSS: #User1 { background-color: green; <--This is ...