skip to Main Content

Everything that I have researched comes up with ways to nest CSS. That’s not what I am trying to do.

UPDATE: The question that was associated with mine which caused it to close does not have an answer that helps. Most answers are years old. One answer mentions using LESS, so I would ask how that can work with the Rails 7 asset pipeline.

What I am trying to accomplish

I am trying to reference a CSS class within another CSS class to limit replication. Much like a variable is used.

Example

I am using Bootstrap for my design foundation. Within the footer section, there are columns that each have the following classes specified:

col-lg-3 col-md-6 mb-5 mb-lg-0

I’d like to make a class footer-section and reference those classes above. That way if I should want to change how the sections are shown, I don’t have to go through each to update, just update the CSS class.

Example Bootstrap Code

.col-lg-3 {
    flex: 0 0 auto;
    width: 25%;
}
.col-md-6 {
    flex: 0 0 auto;
    width: 50%;
}
.mb-5 {
  margin-bottom: 3rem !important;
}
.mb-lg-0 {
    margin-bottom: 0 !important;
}

What I’d like my custom-footer.scss to look like:

footer {
    .footer-section {
        .col-lg-3, .col-md-6, .mb-5, .mb-lg-0
    }
  
    /* Other Code */
}

HTML

<footer>
     <div class="footer-section">
         ... Section content
     </div>
     <div class="footer-section">
         ... Section content
     </div>
     <div class="footer-section">
         ... Section content
     </div>
</footer>

In practice

With the above code it would then be easy to change all sections within the footer by just updating the CSS footer .footer-section {} declaration

My Development Environment

I am using Ruby on Rails for Development and my Asset Pipeline looks like this:

app/assets/stylesheets--
                        |
                        pages--
                        |      |
                        |      legal_styles.scss
                        |
                         _variables.css
                         application.css
                         changed_bootstrap.scss
                         custom_text_styles.scss
                         custom.scss
                         footer_styles.scss

vendor/assets/stylesheets--
                           |
                            animate.min.css
                            bootstrap.min.css
                            bootstrap.min.css.map
                       

application.css Code

/* application.css file
 
 *= require _variables
 
 *= require bootstrap.min
 *= require animate.min
 *= require font-awesome
 
 *= require_tree .
 *= require_self
 */

UPDATE: So, per a comment and suggested answer, I tried this in my footer_styles.scss file:

.footer-section {
        @extend .col-lg-3;
        @extend .col-md-6;
        @extend .mb-5;
        @extend .mb-lg-0;
}

But, I get a compile error that the ‘target selector was not found.’ I call for the bootstrap.min.css to be called before the footer_styles.scss is called. So, the selector should be visible within the compiled application.css file before it is @extended. So, I am not sure what is going on there or if I am doing something wrong.

Justification

I know that I could just copy the Bootstrap code for each class over to the .section area, but that would be a duplication of code.

I know that the footer section is centralized and only has a few areas, so maintenance/updates would be rather easy; but, I’d like to utilize this type of technique in other areas of my site. I am seeing that I utilize the Bootstrap classes often together throughout my site and instead of updating each declaration on each page, it would be easy to just change the CSS code.

Question

Is it possible to ‘reference’, not nest, CSS classes within another CSS class?

2

Answers


  1. You seem to be looking for https://sass-lang.com/documentation/at-rules/extend

    .error:hover {
      background-color: #fee;
    }
    
    .error--serious {
      @extend .error;
      border-width: 3px;
    }
    
    Login or Signup to reply.
  2. There are quite a few issues/ideas here to tackle.

    Don’t use Sprockets directives

    #= require and #= require_tree are extremely primitive and read each file and then pass them into the compiler one by one. The result is then concatenated and fed into any postprocessors. This does not work well with Sass or any other kind of precompiler where you can use variables or functions defined in another file.

    So you want to change your assets manifest into a SCSS file and use let the SASS compiler do the work.

    With the deprechiated LibSass sass compiler you’re stuck with @includes:

    // application.scss
    @include 'variables';
    @include 'changed_bootstrap';
    @include 'custom_text_styles';
    @include 'custom';
    @include 'footer_styles';
    

    Note that the files you’re including should have their names prefixed with an underscore as they are not intended to compile into individual files.

    However the modern way going forward is to use Dart-Sass and SASS modules:

    // style.scss
    @use 'variables';
    @use 'changed_bootstrap';
    

    This fixes a lot of the headaches involved with @includes which is actually a CSS feature that the SASS compiler clobbers.

    Inheritance in CSS

    You have to remember that CSS was designed as a simple declaritive language. It does not have inheritance in the sense that you can inherit from another rule.

    CSS did get custom properties (variables) relatively recently which lets you resuse values at least.

    Copy-pasting SASS style

    Sass has @extend which basically just copies all the attributes of one CSS rule to another:

    .foo {
      color: "red";
    }
    
    .bar {
      @extend .foo;
      display: block;
    }
    

    Which compiles down into:

    .foo {
      color: "red";
    }
    
    .bar {
      color: :red;
      display: block;
    }
    

    However the rule you’re defining must be in a file previously loaded by the SASS compiler. While SASS can load plain CSS files as SASS is a superset I can’t guarentee that what you’re doing there will actually work.

    While Bootstrap was in the past ported to Sass from Less so that your could reuse parts of it remember that Bootstrap is 11 years old and has aged like milk. If you want to use it just live with the fact that your HTML is going to be a soup of purely presentational classes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search