Exploring the differences between SASS and Bootstrap: the battle of mixins versus @extend

Currently utilizing the SASS version of Bootstrap found here. Curious as to whether there are distinctions between using the pre-set mixins versus utilizing SASS's @extend.

For example, considering the following:

<div class="wrapper">
    Some content here....
</div>

Would there be any variance between:

.wrapper {
    @include make-row();
}

and

.wrapper {
    @extend .row;
}

If there is no discernible difference, are there additional mixins that do not equate to a single @extend statement? In the absence of such unique mixins, what is the reasoning behind their existence?

Answer №1

When it comes to comparing @extend and mixins, one of the key differences lies in how the CSS is compiled. While the variance may not seem significant in basic examples, the implications can be substantial and lead to headaches if used carelessly. Think of @extend as akin to fool's gold - initially appealing, but...

Let's illustrate with a simple example:

@extend

.row {
    width: 50px;
}
.new-row {
    @extend .row;
}
.another-row {
    @extend .row;
}

Compiles to:

.row,
.new-row,
.another-row {
     width: 50px;
}

Mixin

@mixin row() {
    width: 50px;
}
.new-row {
    @include row();
}
.another-row {
    @include row();
}

Compiles to:

.new-row {
   width: 50px;
}
.another-row {
   width: 50px;
}

A mixin duplicates properties each time they are called, whereas @extend groups selectors and defines properties just once. This distinction may not be immediately apparent since it affects the compiled CSS, but it carries some important consequences:

Load Order

With @extend, selectors are grouped where first encountered in the SCSS, which can result in unexpected overriding. For instance, attempting to override a property defined earlier in your SCSS file after the grouping by @extend will not work as anticipated.

Consider this logically-ordered CSS set with corresponding HTML:

<div class='row highlight-row'></div>
:

.red-text {
    color: red;
}
.row {
    color: green;
}
.highlight-row {
    @extend .red-text;
}

Compiles to:

.red-text,
.highlight-row {
    color: red;
}
.row {
    color: green;
}

Even though the order suggests the text should be red, the compiled CSS makes it green.

Poor Groupings

@extend can lead to poorly organized selectors in the resulting CSS, with unrelated items sharing the same properties. Fonts are a common example of this issue when using @extend.

Nesting

If you have deeply nested SASS (which is generally discouraged), using @extend can result in bloating the CSS with duplicated fully-nested selectors for every @extend used.

.selector-1 .selector-2 .selector-3 .selector-4,
.selector-1 .selector-2 .selector-3 .selector-4 a,
.selector-1 .selector-2 .selector-3 .selector-4 li,
.selector-1 .selector-2 .selector-3 .selector-4 td {
    font-family: arial;
}

For SASS newcomers, examining the compiled CSS is highly advisable.

Media Queries

@extend does not function within media queries because media queries are not selectors.

Conclusion

As a general rule, use @extend over mixins without parameters if you can define the extension reasonably and share it among closely-related selectors nearby in the SASS file. Buttons are a prime example of proper usage of @extend:

%button {
    padding: 10px;
}
.call-to-action {
    @extend %button;
    background-color: $green;
}
.submit {
    @extend %button;
    background-color: $grey;
}

To make an informed decision, refer to the comprehensive article available here.

PS: The % symbol corresponds to placeholder extensions.

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

How can you use JavaScript to retrieve the position of an element on a webpage?

As mentioned in the title, I am looking for a way to retrieve the x and y positions of an element relative to its location on the webpage and based on its positioning schemes such as absolute or relative. ...

Can we implement a variety of site designs based on the size of the window?

Utilizing media queries allows us to modify the CSS for various screen sizes. My inquiry is: can we switch to a completely different page layout (or View in MVC) when the window size, specifically when the width is less than 500? Assuming that the control ...

On mobile devices, the alignment of text in Bootstrap doesn't appear as intended

I'm creating a portfolio website for showcasing my design projects from university. The text in the "my work" section is centered, but it seems misaligned with other elements like buttons when the window width is reduced. What could be the issue? Cod ...

Attempting to toggle the visibility of div elements through user interaction

I'm having an issue with click events on several elements. Each element's click event is supposed to reveal a specific div related to it, but the hidden divs are not appearing when I click on the elements. Any help in figuring out what might be g ...

Having issues with CSS animation keyframes not functioning properly in NextJS

Currently, I have a straightforward component in NextJS that is displaying "HI" upon loading. This component fades in when rendered, but I am facing an issue while trying to pass a prop to make it fade out. The problem lies in the fact that even though the ...

Learn how to easily center a responsive navbar using Twitter Bootstrap

I'm having a bit of trouble creating a website with Twitter Bootstrap, specifically when it comes to centering the navigation links in responsive design. My goal is to have a two-row navigation bar for tablet and phone devices, with the brand name at ...

The mobile header appears without any background shading

Hey there, I'm encountering a puzzling issue: I have a header with a gradient background that displays perfectly on desktop. However, when I preview it on Chrome mobile emulator, it looks fine. But when I test it on an actual tablet or mobile device, ...

Using jQuery to create a captivating Parallax Effect on your website's background image

Hey there! I have a div with the class 'section' that serves as a key element on my website. It has a background image set using the following CSS: .section-one { width: 100vw; height: 100vh; background-image: url(images/outside-shot ...

Elements are receiving CSS properties from other elements within the same component

I'm encountering an issue with my components: 1. I cannot seem to style html and body in signin.component.css for some reason. The workaround I found was using: encapsulation: ViewEncapsulation.None ==> This works perfectly However, when I switch ...

Is there a way to determine the orientation of an image in React-Native, whether it is horizontal or vertical

When working with react-native, I aim to utilize the 'contain' feature for vertical images and the 'stretch' feature for horizontal images. What would be the best way to determine the orientation of an image as either horizontal or vert ...

Using Bootstrap svg link in background-image not functioning correctly for radio buttons, checkboxes, and various other icons

I decided to give my Bootstrap design a personal touch by customizing it with my own styles. To do this, I copied an HTML page containing all the Bootstrap elements from bootswatch.com/default. After adjusting the directories in the "link" and "script" tag ...

What is the best way to make a message appear only when the browser screen is smaller?

I am struggling to make a message appear only when the screen is resized. It's puzzling me why my current approach isn't yielding the desired result. Instead of displaying the message only on a shrunk screen, it shows up all the time. I can confi ...

How can I customize the color of the disabled state in a mat-slide-toggle?

I am trying to customize the disabled state color of a mat-slide-toggle. This is what my slide toggle currently looks like: https://i.sstatic.net/Lhz0U.png Here is the code I have been using: <div> <mat-slide-toggle>Slide me!</mat-slide ...

Using Javascript to deactivate a clickable image upon clicking another image

I have two buttons with alert functions assigned to each. I want the function on the first button to only work when that button is clicked, and not work if the second button has been clicked. Below is the code I've tried, but it's not functioning ...

Does the Bootstrap 4 flex system allow for arranging self-row items within a parent column?

Displayed below is the navbar code snippet: <div class="d-flex flex-column flex-lg-row"> ...... </div> As shown in the example: .bd-highlight { background-color: rgba(86,61,124,.15); border: 1px solid rgba(86,61,124,.15); } < ...

Images that dynamically adjust to different screen sizes with captions that are perfectly

For a while now, I have been utilizing <picture> to display images with more design control. I typically use CSS to show or hide specific images within the <div> block. However, I am now considering using <figure> with <figcaption> ...

Troubleshooting: CSS Pseudo :after doesn't apply to an anchor tag

I've created a pseudo CSS style for an anchor tag, which was working fine before. However, for some reason, it's no longer working. I tried using Chrome inspect element to add the CSS but it's not being read by the anchor tag. @font-face ...

Combining various arbitrary values, like :has in Tailwind, can be achieved by following these steps

I'm facing an issue where I need to hide an element if it has children. In regular CSS, this is achieved with the following code: &:not(:has(*)){ display: none } However, when trying to implement this in Tailwind, I'm struggling to figure ...

Is it possible to slide-toggle and alter the background color of a div when clicked?

Imagine having several div's on a webpage all with the ID of "Toggle". Each div contains two other smaller divs. "Headline" which is always visible. "Comment" which appears/disappears when the headline is clicked (initially hidden). How could I ac ...

`Why are my overflow-x and flex-wrap not functioning as expected in React JS?`

Having trouble aligning all the movie posters in a single line? It appears that your overflow-x and flex-wrap properties aren't functioning as expected in your App.css. Here's a snippet of your App.css: body { background: #141414; color: ...