Back

Technologies:

javascriptjavascript
csscss
typescripttypescript
avatar
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)
avatar
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);
  }
}
;