The overwriting of SCSS transition properties

I have a handy @mixin that I use to easily add different transition properties to elements. Here's an example of how I use it in my .scss file:

@mixin transition($prop, $sec){
  -webkit-transition: $prop $sec;
  -moz-transition: $prop $sec;
  -ms-transition: $prop $sec;
  -o-transition: $prop $sec;
  transition: $prop $sec;
}

and then I apply it like this:

.sample{
  @include transition(background-color, 0.2s);
  @include transition(margin, 0.3s)
}

In this case, .sample only has a margin transition, but I also want to include a background-color transition. Is there a simple way to achieve this without having to make separate calls?

I need to have different transitions applied individually.

Answer №1

In SASS, there is currently no built-in way to concatenate properties, and it's uncertain if there exists a CSS external tool to perform this task. The purpose of Sass is to enhance CSS capabilities, not promote bad programming practices by allowing developers to create multiple CSS declaration statements when they could be consolidated into a single statement. Consolidating all transitions into one statement significantly improves the structure, workflow, and performance of Sass code.

That being said, as you previously mentioned, sometimes you have to let the kludge be.

Here are two mixins for handling transition declarations—one for shorthand and one for the long form. The differences in processing and load time between them are negligible; the primary distinction lies in the stylistic presentation of your code.

Long form mixin

@mixin transition($properties, $durations, $timing-function: null, $delay: null) {
  $declarations: (property, $properties),
                 (duration, $durations),
                 (timing-function, $timing-function),
                 (delay, $delay);
  
  @each $declaration in $declarations {
    @if nth($declaration, 2) {
      $output: ();
        @each $val in nth($declaration, 2) {
          $output: append($output, $val, comma);
        }
      @each $prefix in '-webkit-', '-moz-', '-ms-', '-o-', '' {
        #{$prefix}transition-#{nth($declaration, 1)}: $output;
      }
    }
  } 
}

This mixin is similar to @LeBen's mixin but allows you to use the include statement with comma-separated arguments without quotes:

@include transition(background-color margin, 0.2s 0.3s);

Shorthand form

@mixin transition($declarations...) {
  @each $prefix in '-webkit-', '-moz-', '-ms-', '-o-', '' {
    #{$prefix}transition: $declarations;
  }
}

Here's how you can implement it in your code:

@include transition(background-color 0.2s, margin 0.3s);

To address the issue of handling "different calls," the only feasible approach, in my opinion, is to utilize the list function append().

Let's consider an example. Suppose you have four pages—three partials (_variables.scss, _page1.scss, _page2.scss, _page3.scss)—and a main style.scss file that imports them:

_VARIABLES.SCSS

// Variable declaration
$transition-list: color 1s;

_PAGE1.SCSS

// Using append($list, $val, $separator:auto) list function
$transition-list: append($transition-list, margin 2s, comma);

_PAGE2.SCSS

// Adding the output of a function
@function example(){
  @return unquote("background-color 1s")
}

$transition-list: append($transition-list, example(), comma);

STYLE.SCSS

// Adding new values within the same page
$transition-list: append($transition-list, padding 4s, comma);
$transition-list: append($transition-list, border 10s, comma);

// Using the include to generate the final transition
example {
  @include transition($transition-list);
}

As mentioned earlier, this method is not recommended as a best practice.

Answer №2

Your current mixin seems restrictive and lacks the fluidity of natural CSS. In my opinion, it would be beneficial to utilize the mixins available in Compass, especially as they can handle prefixed values effectively. If you are looking for a straightforward mixin, consider using variable arguments as shown below:

@mixin transition($values...) {
    -webkit-transition: $values;
    // other vendor prefixes
    transition: $values;
}

@mixin transition-property($values...) {
    -webkit-transition-property: $values;
    // other vendor prefixes
    transition-property: $values;
}
@mixin transition-delay($values...) {
    -webkit-transition-delay: $values;
    // other vendor prefixes
    transition-delay: $values;
}

// additional mixins

.foo {
    @include transition(background-color, margin); // or transition-property
    @include transition-delay(0.2s);
}

Output:

.foo {
  -webkit-transition: background-color, margin;
  transition: background-color, margin;
  -webkit-transition-delay: 0.2s;
  transition-delay: 0.2s;
}

Alternatively:

.foo {
    @include transition(background-color 0.2s, margin 0.3s);
}

Output:

.foo {
  -webkit-transition: background-color 0.2s, margin 0.3s;
  transition: background-color 0.2s, margin 0.3s;
}

Answer №3

Check out this useful mixin you can implement:

@mixin animation($properties, $durations, $timing-function: null, $delay: null) {
  $props: unquote($properties);
  $durs: unquote($durations);

  -webkit-animation-property: $props;
     -moz-animation-property: $props;
      -ms-animation-property: $props;
       -o-animation-property: $props;
          animation-property: $props;

  -webkit-animation-duration: $durs;
     -moz-animation-duration: $durs;
      -ms-animation-duration: $durs;
       -o-animation-duration: $durs;
          animation-duration: $durs;

  @if ($timing-function) {
    -webkit-animation-timing-function: $timing-function;
       -moz-animation-timing-function: $timing-function;
        -ms-animation-timing-function: $timing-function;
         -o-animation-timing-function: $timing-function;
            animation-timing-function: $timing-function;
  }

  @if ($delay) {
    -webkit-animation-delay: $delay;
       -moz-animation-delay: $delay;
        -ms-animation-delay: $delay;
         -o-animation-delay: $delay;
            animation-delay: $delay;
  }
}

Use the following code snippet to apply the mixin:

@include animation("transform, opacity", 0.3s, ease-in-out, 0.1s);

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

Is it possible to recognize when the mouse button is held down and the cursor is outside the viewport by using mouseleave detection?

Is there a way to detect when a user moves the mouse outside of the view-port, even if they are holding down the mouse button (for example, if the mouse is on the browser address bar)? In the code below, I am currently using mouseout and mouseleave to det ...

State change shows the previous and current values simultaneously

I've been working on updating the values of initUsers on the DOM. The initial state values work fine, but when I try to update initUsers, it displays different values than expected. Essentially, entriesNum receives a number as an event and changes th ...

Tips for Creating a Fixed-Width Element

I am struggling with creating text wrapping around a box inside a full width page template on Wordpress. The plugin developer suggested wrapping the text inside a fixed width element, but I am unsure how to do this. Any assistance would be greatly apprecia ...

Mobile devices cause CSS drop shadows to malfunction | Next.js

Update: After some testing, I discovered that this issue is specific to iPhones. When I tested it with an android device, everything worked perfectly fine. However, when I tried viewing the page on two different iPhones, it broke on both. This problem see ...

I am puzzled as to why my text and div boxes are displaying in my navbar/hamburger menu instead of at the bottom of the page

Greetings, everyone! This is my debut post here so bear with me if it's not presented in the correct format. Currently, I am deep into creating a website using HTML, CSS, and just a hint of JavaScript. My primary focus right now is on building the ho ...

Absolute positioned content causing unexpected spacing on top of relative positioned content

I've been experimenting with a fantastic technique by Chris Coyier for implementing full page video backgrounds with content scrolling over the video. However, I've encountered an issue where there's an unexpected gap to the right in Windows ...

Utilizing ease-in effect on show more button clicks in CSS

When I click "show more," I want to have a smooth ease-in/out animation for 3 seconds. However, I am facing difficulties achieving this because I am using overflow: hidden and -webkit-line-clamp: 2; Are there any other methods to accomplish this? https: ...

Low-quality CSS Gradient Design

Hey everyone, Feel free to take a look at my preloader on this link: (Hit ESC as soon as the page loads to pause the website and focus on the loader) Upon closer inspection, you'll notice that there is an issue with the quality of the background l ...

Modify the css with JQUERY when there are no rows inside the tbody section

Is it possible to change the css using jquery if there are no rows in the table body? I have attempted this but my current approach is not working. I tried adding an alert within the if statement, but the alert did not appear. My goal is to hide the table ...

What class is utilized when multiple classes are specified?

When an element has two classes assigned to it and the CSS for the two classes conflict with each other, which one takes precedence? Is there a method to determine which one will be used? For instance: <p class='red small'>Some Text Here& ...

ReactJS Navbar component experiencing CSS hover bug

While developing a navbar component in React, I encountered an unexpected issue - the hover effect on my navigation links suddenly stopped working. Strangely enough, the cursor: pointer functionality still operates on my logo but not on the nav links durin ...

What is the best way to create a new column that wraps content from existing columns?

While working on some homework, I encountered an issue with flex-wrap. I have columns that I want to wrap into at least two columns, but instead, they are overflowing my container. Note: I am aware that this can be achieved with grid as well, but I wanted ...

The pointer cursor seems to be missing in action

Currently using ReactJS, I have implemented a custom upload image button on my webpage. .upload-btn-wrapper { position: relative; overflow: hidden; display: inline-block; cursor: pointer; } .upload-btn-wrapper input[type=file] { font-size: 10 ...

Tips for overlaying text on an image in html with the ability to zoom in/out and adjust resolution

My challenge is aligning text over an image so that they move together when zooming in or out. However, I am facing difficulties as the text and image seem to move in different directions. I have attempted using media queries and adjusting the positions of ...

Troubleshooting problem with iPhone X responsiveness

Struggling with responsive issues on iPhone X. Issue is only appearing on actual device. Any tips for fixing this? I'm facing an issue where the website looks good and responsive on all devices in Chrome's responsive view. But when I access it th ...

Struggling to properly line up the baselines of navigation list items that are styled as circular elements using CSS

I have transformed my navigation menu into a series of CSS circles with text inside. The issue I am facing is that the text spills out unevenly based on the amount of content in each circle. To address this, I used a JavaScript solution to center-align the ...

Clone content upon pressing the Enter key

I am facing an issue with my editable container where I have a div inside it. Whenever I press enter, the div duplicates, resulting in two divs stacked on top of each other. The container has contenteditable set to true, which might be causing this problem ...

Tips for effectively displaying elements on a page

After making changes to my css/html code, all the elements within a div are now displayed in a single line instead of appearing as separate <p>contents</p> tags with each on a new line. An example of this issue can be seen here: Dealing with C ...

Tips for creating a div that covers the entire screen and prevents it from resizing

I am facing an issue with a container having the className "container". When I set the height to 100vh like this: .container{ height:100vh } Whenever I resize my screen, such as with dev-tools, the div also shrinks. How can I prevent this? Is it possi ...

Overcomplicating div elements with unnecessary cloning during checkbox usage

Whenever I check the checkbox and press OK, I want to clone a div with specific user details. Everything works as expected when selecting multiple users. However, adding more users without unchecking the previous checkboxes results in cloned buttons but no ...