Tips for effectively drying up sass mixin code using before and after blocks

Here is the SCSS code I currently have:


@if $position == bottom {
    &:after {
      height: $triangle-width;
      width: $triangle-width;
      content:"";
      position:absolute;
      margin-top: -$triangle-width/2 -$stroke-width;
    }
}

@if $position == top {
    &:before {
      height: $triangle-width;
      width: $triangle-width;
      content:"";
      position:absolute;
      margin-bottom: -$triangle-width/2 -$stroke-width;
    }
}

There is some duplicated code here that I'd like to streamline. I attempted to create a separate class, but it didn't work as expected. Any suggestions on how to optimize this? I thought about creating a mixin within a mixin, but that might be too complex. What are your thoughts?

Answer №1

One effective strategy for keeping code DRY is to extract common components into mixins and then combine them into larger mixins. This method is commonly used in frameworks like Compass. Take a look at the Compass list mixins for reference.

@mixin base-triangle($triangle-width) {
  height: $triangle-width;
  width: $triangle-width;
  content:"";
  position:absolute;
}

@mixin triangle($position, $triangle-width: 4, $stroke-width: 4) {
  @if $position == bottom {
    &:after {
      @include base-triangle($triangle-width);
      margin-top: -$triangle-width/2 -$stroke-width;
    }
  }

  @if $position == top {
    &:before {
      @include base-triangle($triangle-width);
      margin-bottom: -$triangle-width/2 -$stroke-width;
    }
  }
}

.foo {
  @include triangle("top", 8px, 8px);
}

.bar {
  @include triangle("bottom");
}

Compiles to:

.foo:before {
  height: 8px;
  width: 8px;
  content: "";
  position: absolute;
  margin-bottom: -12px;
}

.bar:after {
  height: 4;
  width: 4;
  content: "";
  position: absolute;
  margin-top: -6;
}

Answer №2

One effective way to utilize this type of mixin is by excluding the :before or :after from the mixin and directly applying the mixin in the desired pseudo-class. This not only streamlines the mixin but also eliminates any dependencies on conditional logic.

Here's a sample of how the mixin can be used:

@mixin customMixin($position, $size, $stroke) {
    position: absolute;
    width: $size;
    height: $size;
    margin-#{$position}: -($size / 2) - $stroke;
    content: '';
}

Sample application:

.example {

    &:before {
        @include customMixin(top, 20px, 20px);
    }
}

.example-two {

    &:after {
        @include customMixin(bottom, 20px, 20px);
    }
}

Answer №3

These SASS variables serve as placeholders for this example.

$position : top ;
$triangle-width : 100px;
$stroke-width : 100px;

A SASS mixin that consolidates logic in one location. The absence of IF-ELSE conditions allows for versatile usage across multiple instances.

@mixin before_after($margin-side,$before-after){
&:#{$before-after} {
      height: $triangle-width;
      width: $triangle-width;
      content:"";
      position:absolute;
      margin-#{$margin-side}: -$triangle-width/2 -$stroke-width;
    }

}

The mixin can be integrated with IF-ELSE statements to guide functionality.

p{
    @if $position == top {

        @include before_after(bottom,before);
    }@else{
        @include before_after(top,after);
    }
}

Alternatively, the mixin can be applied without the use of IF-ELSE conditions.

p{
@include before_after(bottom,before);
}

div{
@include before_after(top,before);
}

PS: This response has been expanded to offer additional context for @Sean Stopnik. It aims to provide a foundational understanding for further exploration and development by the original questioner, rather than detailing every aspect of variable application.

  • Please contribute constructive comments to enhance the answer.
  • If you have suggestions for improvement or an alternative solution, feel free to share.
  • Respect others' time by avoiding unnecessary spam in the comment section, as it influences readers seeking clarity on the response.

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

Utilize the grid system from Bootstrap to style HTML div elements

I am working on my angular application and need help with styling items in a Bootstrap grid based on the number of elements in an array. Here's what I'm looking to achieve: If there are 5 items in the array, I want to display the first two items ...

Utilize data attributes in VueJS to dynamically style elements

Is there a way to utilize the data() values within the <style>..</style> section? I have experimented with different combinations (using/omitting this, with/without {{brackets}}, etc.) but haven't been successful. Interestingly, when I man ...

The Chrome browser is failing to detect the hover function of the Surface Pen stylus

Encountering an issue with the hover pseudo-class not functioning properly on Surface pad's Chrome browser. The hover effect is working as expected in other browsers, but not in Chrome. I am using a Surface pen to test the hover functionality. HTML: ...

Experience the magic of a customized cursor that disappears with a simple mouse movement in your website,

I have been experimenting with designing a custom cursor for my website. After finding a design I liked, I made some adjustments to suit my needs. However, an issue I encountered is that when I scroll, the custom cursor also moves away from its original po ...

Issue with Google Chrome not showing stylesheets on Windows 7

Recently, I've been facing an issue with CSS layers on my website while using Google Chrome. Despite following the code accurately, my browser fails to display the expected result. To troubleshoot, I even copied and pasted code from a reliable source ...

When hovering over an "li" element, setting the color to "a" will create a dynamic visual effect

On the platform I'm using, users can adjust element settings with CSS. I'm attempting to make the "a" element change color when hovering over the "li" element. However, the color of the "a" element isn't changing as expected. How can I resol ...

Having trouble with CSS text not wrapping correctly?

While working on a web application, I encountered an issue where the text within a <div> element on my page was not wrapping properly and instead overflowing outside the box. The <div> in question goes through two stages: one where it is not e ...

Problem with the `file` input not working properly

Currently, I am working on creating a form with two input fields - one for text and the other for file upload. However, the issue I am facing is that the Browse button for the file input is being displayed inside the input box. My goal is to have the butto ...

Trouble encountered in adjusting the alignment of labels

I'm struggling with aligning my links properly. https://i.sstatic.net/W5G4Z.png I want Yesterday This week This month to line up perfectly with the DateTime From and Last 2 days Last 7 days Last 30 days labels for DateTime To. This is how it appear ...

Utilizing Jquery to pass two classes along

I am looking for assistance on how to pass multiple classes within if-else statements and jQuery. My goal is to have both divs and divs2 change when the next button is clicked. Can someone please provide guidance on achieving this? --code not mine-- ...

The hover effect on sibling elements is not functioning for the <img> tag

When you hover over the image displayed within the <div class="like absolute">, the image within the <div class="balloons absolute"> doesn't appear. <div id="container" class="relative"> <div class="like absolute"> ...

Ways to adjust image sizes to fill the row with CSS

I am facing an issue with displaying multiple images using flexbox. Whenever an image cannot fit in the same row, it leaves a gap which disrupts the layout. https://i.sstatic.net/bXltY.jpg My goal is to resize these images dynamically so that there are n ...

Is it possible to target the sibling of the currently selected or focused element with CSS?

I'm attempting to add button functionality to show and hide errors using CSS. By clicking the CSS button or link, I can target the siblings of the focused element as shown below. This method is only effective in IE8+ browsers. #ShowErrors:focus + a ...

Ensure that the sidebar in your React application occupies the full height of the page, regardless of the presence of scrolling

In my application, most of the pages fit within the viewport which is why I have been using height: 100vh for my <SideNav /> component. However, some pages now require scrolling and this causes issues with the sidebar as it abruptly ends when scrolli ...

Is it truly unsemantic to use transparent <hr> elements for responsive vertical spacing?

I've recently adopted a unique technique for managing vertical spacing in front-end design by using transparent <hr> elements as spacers. I understand that this method is not favored among most of the web community, but I believe it has its meri ...

I'm having trouble displaying my background image unless I specifically set the height in pixels or viewport height

I have been working with ReactJS and on my main page container, I am setting a background image like this: .opening-container { background-image: url("../../images/sadaqashdbg.png"); background-position: center; background-size: cover; ba ...

Troubleshooting issue with Bootstrap 4 carousel displaying images with overlay

I'm currently working on creating a carousel with 3 background images. The issue I'm facing is that only the first image appears when the carousel slides, while the rest do not display properly - instead, the background color of the slider shows ...

Creating a Form with HTML and CSS

I am currently working on setting up a banner that includes an overlay with a cutout. Beneath the overlay, there is an image. My goal is to create this design using HTML and CSS. I have been experimenting with pseudo-elements but I am having difficulty re ...

What is the reason behind hyperlinks breaking the continuity of the text on a line? Is there a

When I have a line of code containing several hyperlinks, my desired output is a single line. However, despite using CSS to set white-space to nowrap, the result is not as expected. The line of code in question is: <a href="profile.php?v=<?php echo ...

Error encountered in the VS Task Runner Explorer: Node Sass failed to locate a binding

When I try to open the Visual Studio Task Runner Explorer, I encounter an issue where the gulpfile.js fails to load, resulting in an error message in the Output window. Failed to run "C:\DATA\Git\MyApp\MyBiz.MyApp\MyBiz.MyApp.Webs ...