0

I'm trying to use multiple transforms in a single element so that the end product is a combination of all of the transformations applied together.

However, the only one transform property will be ignored when there are multiple of them.

Say, if I want a div transformed by rotate(20deg) and skewY(20deg), this wouldn't work:

.foo {
  transform: rotate(20deg);
}

.bar {
  transform: skewY(20deg);
}
<div class="foo bar"></div>

Only one will be applied. Although compounding the transformations could work, it would be impractical as there can be potentially many combinations to the transformations. Rather than doing this:

.one-one {transform: rotate(10deg) skewY(1deg);}
.one-two {transform: rotate(10deg) skewY(2deg);}
.one-three {transform: rotate(10deg) skewY(3deg);}
.one-four {transform: rotate(10deg) skewY(4deg);}
.two-one etc.

I want to do this, so that i can apply the transformations on button clicks, rather than to exhaust all possible combinations of the transformations:

.one {transform: rotate(10deg);}
.two {transform: rotate(20deg);}
.three {transform: rotate(30deg);}
.four {transform: rotate(40deg);}

.uno {transform: skewY(10deg);}
.dos {transform: skewY(20deg);}
.tres {transform: skewY(30deg);}

Current solutions I think are possible:

  • There is a way to add to the transform property of a <div>
  • Somehow modify classes in some way
  • Changing the CSS using jQuery, but it seems like this will also overwrite the property with css() rather than adding to the transform style

I'd prefer css/js solutions, but jQuery answers are welcome too, I'm just not familiar with it.

Mosia Thabo
  • 4,009
  • 1
  • 14
  • 24
SaNoy SaKnoi
  • 25
  • 1
  • 3

2 Answers2

1

You may look at CSS var(--X) (see links below snippet's demo) and , set all transformation you intend to 0 by default and update them via the className :(mind support before use : https://caniuse.com/#feat=mdn-css_properties_custom-property_var and eventually a polyfill https://github.com/nuxodin/ie11CustomProperties )

possible exemple without JavaScript https://codepen.io/gc-nomade/pen/RwWLOWr :

.foo {
  --rotate: 20deg;
}

.bar {
  --skewY: 20deg;
}

div[class] {
  transform: rotate( var(--rotate, 0)) skewY( var(--skewY, 0));/* fallback value is here 0 */
}


/* demo purpose */

div[class] {
  float: left;
  border: solid;
}

html {
  display: flex;
  height: 100%;
}

body {
  margin: auto;
}
<div class="foo bar">foo bar</div>
<div class="foo ">foo</div>
<div class="bar">bar</div>
<div class="nop">no transform</div>

https://developer.mozilla.org/en-US/docs/Web/CSS/--*

Property names that are prefixed with --, like --example-name, represent custom properties that contain a value that can be used in other declarations using the var() function.

Custom properties are scoped to the element(s) they are declared on, and participate in the cascade: the value of such a custom property is that from the declaration decided by the cascading algorithm.

Fallback : https://drafts.csswg.org/css-variables/#example-abd63bac

Note: The syntax of the fallback, like that of custom properties, allows commas. For example, var(--foo, red, blue) defines a fallback of red, blue; that is, anything between the first comma and the end of the function is considered a fallback value.

if supports comes a question, you may look at : IE11 - does a polyfill / script exist for CSS variables?

Community
  • 1
  • 1
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • This was something I was looking into. But man Browser support is poor. But's it's definitely the shortest solution if browser support is not a concern. – Mosia Thabo May 02 '20 at 09:07
  • @MosiaThabo opera and older's IE are indeed bothering here ;) JavascRipt will be required to mind those ones too ;) – G-Cyrillus May 02 '20 at 09:10
  • lol... Exactly @G-Cyrillus I just used javascript above. Just to illustrate how he can approach the solution. It's up to him to decide on how he set/get the values to skew and rotate – Mosia Thabo May 02 '20 at 09:13
  • @MosiaThabo i was more thinking of a polyfill to keep it easy to use from the stylesheet ;) like https://github.com/nuxodin/ie11CustomProperties – G-Cyrillus May 02 '20 at 09:18
  • Lol, I am using windows 7. and Unfortunately still use my Internet Explorer 9. that should tell you something right? But again, you're right. If they aren't interested in older browsers then I guess the CSS vars solutions is the way forward. – Mosia Thabo May 02 '20 at 09:23
  • 1
    @MosiaThabo here is a solution for you : https://stackoverflow.com/questions/46429937/ie11-does-a-polyfill-script-exist-for-css-variables/57000437#49203834 ;) – G-Cyrillus May 02 '20 at 09:36
  • why you reopened the question? The solution you provided is already in the duplicate target – Temani Afif May 04 '20 at 11:46
0

There's many ways you can approach that. How about this below? I have created two ` to read the values for skew and rotation and them apply the effects.

Remember it doesn't matter where the values come from. They can be hard-coded in your buttons as data-* attributes(if you want them fixed). This is just to show you how you can approach it with javascript( Ihave added some commends to make it simpler to understand):

var object = document.querySelector(".shape");

// this function takes care of Rotational effect
function rotate(event)
{
  var rotation_val = document.getElementById("rotationVal").value;
  
  // this get's the css transform expression for rotation which is 
  // stored as data-attribute on every button, because it tells you what button is resposible for what transformation. But you can store this anywhere you want.
  var css_transform = event.currentTarget.getAttribute("data-rotation");
  
  // this here just replaces say rotate(_r_) to rotate(15deg) if val was 15
  var effect = css_transform.replace("_r_",rotation_val + "deg");
  
  // Take not of this. ere I am not overriding the transform property. Instead
  // I am adding a transformation to it. more like compounding but dynamically.
  object.style.transform += effect;
}

// this function takes care of Skewing effect
function skewY(event)
{
  var skew_val = document.getElementById("skewVal").value;
  var css_transform = event.currentTarget.getAttribute("data-skew");
  var effect = css_transform.replace("_s_",skew_val + "deg");
  object.style.transform += effect;
}

function apply_all(){
  var buttons = document.querySelectorAll(".effect_button");
  
  buttons.forEach( function(button){
    button.click();
  });
}
.container{
  padding: 60px;
  border: thin solid #dbdbdb;
}

.shape{
  width: 60px;
  height: 60px;
  background-color: green;
}
<div class="container">
  <div class="shape">
  </div>
</div>

<input id="rotationVal" />
<button class="effect_button" data-rotation="rotate(_r_)" onClick="rotate(event)">rotate</button>
<br />
<input id="skewVal" />
<button class="effect_button" data-skew="skewY(_s_)" onClick="skewY(event)">Skew</button>
<br />

Or Rotate and Skew at the same time:
<button onClick="apply_all(event)">Transform</button>
Mosia Thabo
  • 4,009
  • 1
  • 14
  • 24