0
votes

I'm creating an opacity slider in Angular 8.

I want to set the background to a checkerboard CSS pattern. I am creating the styles in a function because I am sensing the width of the slider and adjusting the size of the checkers as well as allowing custom colors via an input.

background-image needs to be overloaded to account for webkit/moz browser prefixes. Attempting to do that causes an error because the JSON object has duplicate background-image keys.

This code works in a Sass file with the variables hard-coded and it also works in both webkit and moz browsers when the appropriate background-image rule is commented out.

I have tried (without any luck):

  1. Calling [NgStyle] twice with the background-image rules in two different functions.

  2. Calling [NgStyle] using the function, and using [style.background-image] with just the moz rule

  3. Camel casing one of the background-image keys to make it unique to JSON

Is there any way that I can accomplish my goal of having this dynamically created background and also support both moz and webkit based browsers?

public setBackground() {
    let checkerSize: number = this.getCheckerSizeInPixels();
    return {

      "background-image": `-moz-linear-gradient(45deg, ${this.backgroundColor.toRgbaString()} 25%, transparent 25%),
                          -moz-linear-gradient(-45deg, ${this.backgroundColor.toRgbaString()} 25%, transparent 25%),
                          -moz-linear-gradient(45deg, transparent 75%, ${this.backgroundColor.toRgbaString()} 75%),
                          -moz-linear-gradient(-45deg, transparent 75%, ${this.backgroundColor.toRgbaString()} 75%)`,

      "background-image":
        `-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, ${this.backgroundColor.toRgbaString()}), color-stop(.25, transparent)),
        -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, ${this.backgroundColor.toRgbaString()}), color-stop(.25, transparent)),
        -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, ${this.backgroundColor.toRgbaString()})),
        -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, ${this.backgroundColor.toRgbaString()}))`,

      "-moz-background-size": `${checkerSize}px ${checkerSize}px`,
      "background-size": `${checkerSize}px ${checkerSize}px`,
      "-webkit-background-size": `${checkerSize}px ${checkerSize}px`,

      "background-position":`0 0, ${checkerSize/2}px 0, ${checkerSize/2}px -${checkerSize/2}px, 0rem ${checkerSize/2}px`
    };
  }
.opacity-selector {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  display: block;
  width: 100%;
  height: 100%;

  // background-image:
  //   -moz-linear-gradient(45deg, lightgray 25%, transparent 25%),
  //   -moz-linear-gradient(-45deg, lightgray 25%, transparent 25%),
  //   -moz-linear-gradient(45deg, transparent 75%, lightgray 75%),
  //   -moz-linear-gradient(-45deg, transparent 75%, lightgray 75%);
  // background-image:
  //   -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, lightgray), color-stop(.25, transparent)),
  //   -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, lightgray), color-stop(.25, transparent)),
  //   -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, lightgray)),
  //   -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, lightgray));

  // -moz-background-size: 1rem 1rem;
  // background-size: 1rem 1rem;
  // -webkit-background-size: 1rem 1rem;

  // background-position:0 0, .5rem 0, .5rem -.5rem, 0rem .5rem;
}
<div class="opacity-selector"  [ngStyle]="setBackground()"></div>
1

1 Answers

1
votes

The browser pre-fixes are not required anymore. This requires the following changes to the code to get it to work as it was working with prefixes:

public setBackground() {
    let checkerSize: number = this.getCheckerSizeInPixels();
    return {
      "background-image": `linear-gradient(45deg, ${this.backgroundColor.toRgbaString()} 25%, transparent 25%),
                          linear-gradient(-45deg, ${this.backgroundColor.toRgbaString()} 25%, transparent 25%),
                          linear-gradient(45deg, transparent 75%, ${this.backgroundColor.toRgbaString()} 75%),
                          linear-gradient(-45deg, transparent 75%, ${this.backgroundColor.toRgbaString()} 75%)`,

      "background-size": `${checkerSize}px ${checkerSize}px`,

      "background-position":`0 0, 0px ${checkerSize/2}px, ${checkerSize/2}px -${checkerSize/2}px, -${checkerSize/2}px 0px`
    };
}

Changes to background-position are from this post: CSS gradient checkerboard pattern

This solution solves for my specific use-case, but it doesn't answer the broader question: How would this be accomplished if the browser prefixs were still required? If anyone has a solution - I am still interested in hearing it, please post it.