Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for New CSS Property: 'mask-rotation' #10024

Open
Naryalin opened this issue Mar 3, 2024 · 5 comments
Open

Request for New CSS Property: 'mask-rotation' #10024

Naryalin opened this issue Mar 3, 2024 · 5 comments

Comments

@Naryalin
Copy link

Naryalin commented Mar 3, 2024

Summary:

I am proposing the addition of a new CSS property, mask-rotation, to provide developers with more control over the orientation and rotation of CSS masks.

Motivation:

Currently, CSS offers properties like mask-size, mask-origin, and mask-position for controlling the size, origin, and position of masks. However, there is no direct property to manage the rotation or orientation of the mask. This feature would be particularly useful for scenarios where precise control over the mask's rotation is required.

Proposed Solution:

Introduce a new property, mask-rotation, that allows developers to specify the rotation angle for CSS masks. The property value could accept degrees (deg) as a unit, similar to how rotate works in transformations.

Example:

.element {
    mask-image: url('mask.png');
    mask-size: cover;
    mask-origin: center;
    mask-rotation: 45deg; /* Rotates mask-image 45 degrees clock-wise */
}

Key Words:

The new property could have key words to specify the type of rotation and the axis where it is rotating:

  • right: Rotate the mask 90 degrees
  • flip: Rotate the mask 180 degrees
  • left: Rotate the mask 270 degrees

Also, adding the axis to the key words specify the axis where it is rotating:

  • 'x' (default): Rotates in clock-wise direction
  • 'y': Rotates mask horizontally
  • 'z': Rotates mask vertically

Example:

.element {
    mask-image: url('mask.png');
    mask-size: cover;
    mask-origin: center;
    mask-rotation: y right, flip; /* Rotates mask-image horizontally 90 degrees, and rotates mask 180 degrees clock-wise */
}

Benefits:

  • Enhances flexibility in designing complex visual elements.
  • Provides a more comprehensive set of tools for controlling mask behavior.
  • Enables masks complex animations.
  • Aligns with existing CSS properties, making it intuitive for developers.
@fantasai
Copy link
Collaborator

fantasai commented Mar 8, 2024

We should do backgrounds and masking in conjunction here... and I wonder if it shouldn't be a more generic -transform property.

@SebastianZ
Copy link
Contributor

This use case is covered by the @image rule we resolved on.

Examples:

@image --rotate {
  rotate: 45deg;
}

@image --flip-vertically {
  transform: rotateX(180deg);
}

.element {
    mask-image: image(url('mask.png'), --rotate);
    mask-size: cover;
}

.element {
    mask-image: image(url('mask.png'), --flip-vertically);
    mask-size: cover;
}

This has two major advantages over new properties:

  1. It can be used everywhere were images are allowed and is not limited to masks.
  2. It allows all kinds of image manipulations and is not limited to rotations.

So I vote to close this in favor of the more general solution.

Sebastian

PS: @Thiago2104 Your second example rotates the image by 90 degrees along the y-axis, which effectively makes it invisible.

@Naryalin
Copy link
Author

Naryalin commented Mar 9, 2024

Hi @SebastianZ

I've tried your proposal with a mask image animation that makes the mask to rotate 180deg when .dark tag triggers. I'm using an svg as the mask:

@image --rotate {
  rotate: 180deg;
}
.light .alternate-gradient-bg{
    clip-path: circle(150% at 95.25% 90.5%);
    mask-image: none;
    mask-composite: exclude;
    mask-repeat: no-repeat;
    mask-size: 4500px;
    mask-position: bottom -2180px right -2180px;
    transition: 1s ease-out;
}
.dark .alternate-gradient-bg{
    clip-path: circle(4.4% at 95.25% 90.5%);
    mask-image: image(url("/BlackHole.svg"), --rotate);
    mask-composite: exclude;
    mask-repeat: no-repeat;
    mask-size: 100px;
    mask-position: bottom 20px right 20px;
    transition: 1s ease-out;
}

But what I got is that the tag image in the mask-image makes the mask of the svg to not being applied even without using the @image rule.
What I currently have is a mask animation where the gradient background has a black hole mask, that when combined with clip-path and changing the mask-size, gives the illusion of the background being absorbed by a blackhole, the only thing left is making the mask to rotate from 0 to 180deg during transition so the black hole effect is done. That's why I'm proposing a mask-rotate property, so it is consistent with mask-size and mask-position properties on making mask animations.

I'm sharing a code-pen with a small demonstration of what I currently have BlackHole - Supernova Theme Toggle (It is not responsive yet, so it is possible that mask is not allign with button or clip-paths seems weird)

Thiago2104 - Naryalin

@SebastianZ
Copy link
Contributor

But what I got is that the tag image in the mask-image makes the mask of the svg to not being applied even without using the @image rule.

That is because the @image rule and the new syntax for the image() function don't exist in browsers yet, nor are they specified. There is only a resolution to add them to the specifications, at the moment. So it will still take some time until that solution will work.

For now, you might get the result you're looking for by using two separate elements that overlay each other and work with mix-blend-mode rather than a mask. (I didn't try that out, though. Maybe someone else can come up with a better solution.)

Sebastian

@Naryalin
Copy link
Author

Naryalin commented Mar 9, 2024

Thank you @SebastianZ for your explanation. Then I'll try your suggestion while the @image rule comes to the browsers. I'll let this issue open for now if there are other use cases where this new property is reasonable (for a small example, maybe masks without using images, but I didn't check that though).

Thiago2104 - Naryalin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants