Technologies:
Tolerim
18 hours ago
What is the method for creating a variable size Angular Corner Ribbon Component?
After finding a CSS implementation of a corner ribbon, I created an Angular component from it. The ribbon size can be made dynamic by adding an input attribute for the size in pixels. I initially considered using the CSS "transform scale" function, but scaling would require updating the positions with "translateX" and "translateY" for the ribbon to sit perfectly at the corner of its parent element. However, the math involved is challenging, so I'm exploring other options. Below you can find the code implementation so far, with a pure CSS implementation referenced from CodePen as well as an SCCS rewrite.
Answers(1)
Tolerim
18 hours ago
Verified Answer
One solution for making the size of the ribbon dynamic based on an @Input value is to apply a scaling transform to the .ribbon class. However, since this will affect the positioning of the ribbon, you will also need to adjust the positioning using the translateX and translateY properties.
Here's an example of how you can modify the component to allow for dynamic sizing:
1. Define a new @Input property for the size in px:
@Input() size = 150;
2. Calculate the dimensions of the ribbon based on the size input value:
$main-width: $size;
$ribbon-width: $size * 1.5;
$ribbon-underside-length: $size * 0.033;
$ribbon-padding: $size * 0.1;
$label-min-height: $size * 0.12;
$offset: $ribbon-underside-length * -2;
3. Apply a scaling transform to the .ribbon class based on the size input value:
.ribbon {
transform: scale($size/150);
width: $ribbon-width;
height: $ribbon-width;
overflow: hidden;
position: absolute;
...
4. Adjust the positioning using the translateX and translateY properties based on the size input value:
.ribbon-position(top, left, -45) {
top: $offset / ($size/150); // adjust for scaling
left: $offset / ($size/150); // adjust for scaling
...
.ribbon-label {
...
left: -25px / ($size/150); // adjust for scaling
top: 30px / ($size/150); // adjust for scaling
transform: rotate(-45deg);
}
}
.ribbon-position(top, right, 45) {
top: $offset / ($size/150); // adjust for scaling
right: $offset / ($size/150); // adjust for scaling
...
.ribbon-label {
...
right: -25px / ($size/150); // adjust for scaling
top: 30px / ($size/150); // adjust for scaling
transform: rotate(45deg);
}
}
.ribbon-position(bottom, left, 225) {
bottom: $offset / ($size/150); // adjust for scaling
left: $offset / ($size/150); // adjust for scaling
...
.ribbon-label {
...
left: -25px / ($size/150); // adjust for scaling
bottom: 30px / ($size/150); // adjust for scaling
transform: rotate(225deg);
}
}
.ribbon-position(bottom, right, -225) {
bottom: $offset / ($size/150); // adjust for scaling
right: $offset / ($size/150); // adjust for scaling
...
.ribbon-label {
...
right: -25px / ($size/150); // adjust for scaling
bottom: 30px / ($size/150); // adjust for scaling
transform: rotate(-225deg);
}
}