Search code examples
csscss-shapes

How can I create "sun like" lines around a circle?


CSS sun shape

I basically need to create this design in the image. I know it can be achieved with CSS but I'm not sure how to. I've trying Googling it but I can only find elaborate "sun" designs such as this one, which is too much for me to break down for my current understanding.

https://codepen.io/zmmbreeze/pen/guLfC

I've created the center piece like this (using sass):

  &__count {
    width: 12rem;
    height: 12rem;
    color: $lightPurple;
    border: $border;
    font-size: 4rem;
    font-weight: 500;
    border-radius: 100%;
    @include centerContent;
  }

How can I add the "rays"?

This is what I've tried to extract:

.count-down {
  position: relative;
  margin: auto;
  @include centerContent;
  &__count {
    width: 12rem;
    height: 12rem;
    color: $lightPurple;
    border: $border;
    font-size: 4rem;
    font-weight: 500;
    border-radius: 100%;
    @include centerContent;
  }

  &__go {
    width: 15rem;
    height: 15rem;
    color: white;
    border: 1px solid white;
    font-size: 4rem;
    font-weight: 500;
    border-radius: 100%;
    @include centerContent;
  }
}

.sun-light b,
.sun-light s {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 12%; /* 100*30/100=18.75 */
  background: #fed65b;
}
.sun-light s {
  top: auto;
  bottom: 0;
}
.sun-light:nth-child(10n + 2) {
  -webkit-transform: rotate(18deg);
  -moz-transform: rotate(18deg);
  -o-transform: rotate(18deg);
  -ie-transform: rotate(18deg);
  transform: rotate(18deg);
}
.sun-light:nth-child(10n + 3) {
  -webkit-transform: rotate(36deg);
  -moz-transform: rotate(36deg);
  -o-transform: rotate(36deg);
  -ie-transform: rotate(36deg);
  transform: rotate(36deg);
}
.sun-light:nth-child(10n + 4) {
  -webkit-transform: rotate(54deg);
  -moz-transform: rotate(54deg);
  -o-transform: rotate(54deg);
  -ie-transform: rotate(54deg);
  transform: rotate(54deg);
}
.sun-light:nth-child(10n + 5) {
  -webkit-transform: rotate(72deg);
  -moz-transform: rotate(72deg);
  -o-transform: rotate(72deg);
  -ie-transform: rotate(72deg);
  transform: rotate(72deg);
}
.sun-light:nth-child(10n + 6) {
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  -ie-transform: rotate(90deg);
  transform: rotate(90deg);
}
.sun-light:nth-child(10n + 7) {
  -webkit-transform: rotate(108deg);
  -moz-transform: rotate(108deg);
  -o-transform: rotate(108deg);
  -ie-transform: rotate(108deg);
  transform: rotate(108deg);
}
.sun-light:nth-child(10n + 8) {
  -webkit-transform: rotate(126deg);
  -moz-transform: rotate(126deg);
  -o-transform: rotate(126deg);
  -ie-transform: rotate(126deg);
  transform: rotate(126deg);
}
.sun-light:nth-child(10n + 9) {
  -webkit-transform: rotate(144deg);
  -moz-transform: rotate(144deg);
  -o-transform: rotate(144deg);
  -ie-transform: rotate(144deg);
  transform: rotate(144deg);
}
.sun-light:nth-child(10n + 10) {
  -webkit-transform: rotate(162deg);
  -moz-transform: rotate(162deg);
  -o-transform: rotate(162deg);
  -ie-transform: rotate(162deg);
  transform: rotate(162deg);
}

And this is my component (React.js):

<div className="count-down">
  {timeToStart > 1 ? (
    <div className="count-down__count">{Math.floor(timeToStart)}</div>
  ) : (
    <div className="count-down__go">Go!</div>
  )}

  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
  <div class="sun-light">
    <b></b>
    <s></s>
  </div>
</div>

But I get this result for some reason:

enter image description here


Solution

  • You can try it using conic-gradient and mask like below

    .box {
      --s:20px; /* length */
      --o:10px; /* offset */
      --w:6deg; /* thickness */
      --n:8;    /* numbers*/
      --c:green;/* color */
      
      margin:calc(var(--s) + var(--o) + 10px);
      width:100px;
      height:100px;
      display:inline-block;
      border:2px solid red;
      border-radius:50%;
      position:relative;
    }
    .box::before {
      content:"";
      position:absolute;
      top:    calc(-1*var(--s) - var(--o));
      bottom: calc(-1*var(--s) - var(--o));
      left:   calc(-1*var(--s) - var(--o));
      right:  calc(-1*var(--s) - var(--o));
      border-radius:inherit;
      background:repeating-conic-gradient(from calc(-1*var(--w)/2), var(--c) 0 calc(var(--w) - 2deg),transparent calc(var(--w)) calc(360deg/var(--n) - 2deg),var(--c) calc(360deg/var(--n)));
      -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - var(--s)),#fff calc(100% - var(--s)));
              mask:radial-gradient(farthest-side,transparent calc(100% - var(--s)),#fff calc(100% - var(--s)));
    }
    
    body {
      background: #000;
    }
    <div class="box"></div>
    <div class="box" style="--s:30px;--o:5px;--n:10;--c:yellow;--w:4deg"></div>
    <div class="box" style="--s:15px;--o:20px;--n:6;--c:blue;--w:10deg"></div>

    CSS circular sun shape

    For better support you can replace the conic-gradient with multiple linear-gradient but you will have less flexibility to control the number of rays:

    .box {
      --s:20px; /* length */
      --o:10px; /* offset */
      --c:green; /* color */
      --w:4px; /* thickness*/
      
      --grad:transparent calc(50% - var(--w)/2), 
            var(--c) calc(50% - var(--w)/2 + 1px) 
                     calc(50% + var(--w)/2 - 1px), 
             transparent calc(50% + var(--w)/2);
      
      margin:calc(var(--s) + var(--o) + 10px);
      width:100px;
      height:100px;
      display:inline-block;
      border:2px solid red;
      border-radius:50%;
      position:relative;
    }
    .box::before {
      content:"";
      position:absolute;
      top:    calc(-1*var(--s) - var(--o));
      bottom: calc(-1*var(--s) - var(--o));
      left:   calc(-1*var(--s) - var(--o));
      right:  calc(-1*var(--s) - var(--o));
      border-radius:inherit;
      background:
        /* 8 rays */
        linear-gradient(0deg   ,var(--grad)),
        linear-gradient(45deg  ,var(--grad)),
        linear-gradient(-45deg ,var(--grad)),
        linear-gradient(90deg  ,var(--grad));
        /* */
      -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - var(--s)),#fff calc(100% - var(--s)));
              mask:radial-gradient(farthest-side,transparent calc(100% - var(--s)),#fff calc(100% - var(--s)));
    }
    
    body {
      background: #000;
    }
    <div class="box"></div>
    <div class="box" style="--s:30px;--o:5px;--c:yellow;--w:8px"></div>
    <div class="box" style="--s:15px;--o:20px;--c:blue;--w:10px"></div>

    CSS linear-gradient sun shape

    And if you want to consider border-radius for the ray here is an idea with SVG. Here you will need to adjust manually the SVG each time you want to have a different color, thickness or radius:

    .box {
      --s:20px; /* length */
      --o:10px; /* offset */
      
      --grad:transparent calc(50% - var(--w)/2), 
            var(--c) calc(50% - var(--w)/2 + 1px) 
                     calc(50% + var(--w)/2 - 1px), 
             transparent calc(50% + var(--w)/2);
      
      margin:calc(var(--s) + var(--o) + 10px);
      width:100px;
      height:100px;
      display:inline-block;
      border:2px solid red;
      border-radius:50%;
      position:relative;
    }
    .box::before {
      content:"";
      position:absolute;
      top:    calc(-1*var(--s) - var(--o));
      bottom: calc(-1*var(--s) - var(--o));
      left:   calc(-1*var(--s) - var(--o));
      right:  calc(-1*var(--s) - var(--o));
      border-radius:inherit;
      background:
        /* 8 rays */
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' width='256' style='transform:rotate(0deg);'> <rect x='118' y='0' width='20' height='100%' rx='10' ry='10' fill='green' /></svg>"),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' width='256' style='transform:rotate(45deg);'> <rect x='118' y='0' width='20' height='100%' rx='10' ry='10' fill='green' /></svg>"),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' width='256' style='transform:rotate(-45deg);'> <rect x='118' y='0' width='20' height='100%' rx='10' ry='10' fill='green' /></svg>"),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' width='256' style='transform:rotate(90deg);'> <rect x='118' y='0' width='20' height='100%' rx='10' ry='10' fill='green' /></svg>");
        /* */
      background-size:100% 100%;
      -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - var(--s)),#fff calc(100% - var(--s)));
              mask:radial-gradient(farthest-side,transparent calc(100% - var(--s)),#fff calc(100% - var(--s)));
    }
    
    body {
      background: #000;
    }
    <div class="box"></div>
    <div class="box" style="--s:30px;--o:5px;"></div>
    <div class="box" style="--s:15px;--o:20px;"></div>

    SVG background sun like circle


    A final idea without mask, SVG and complex gradient but many elements:

    .box {
      --s:20px; /* length */
      --o:10px; /* offset */
      --w:6px; /* thickness */
      --c:green;/* color */
      
      margin:calc(var(--s) + var(--o) + 10px);
      width:100px;
      height:100px;
      display:inline-block;
      border:2px solid red;
      border-radius:50%;
      position:relative;
    }
    .box span{
      content:"";
      position:absolute;
      width:var(--w);
      left:50%;
      top:    calc(-1*var(--s) - var(--o));
      bottom: calc(-1*var(--s) - var(--o));
      border-radius:5px;
      background:
        linear-gradient(var(--c),var(--c)) top,
        linear-gradient(var(--c),var(--c)) bottom;
      background-size:100% var(--s);
      background-repeat:no-repeat;
      transform:translate(-50%) rotate(var(--r,0deg));
    }
    
    .box span:nth-child(2) { --r:45deg; }
    .box span:nth-child(3) { --r:-45deg; }
    .box span:nth-child(4) { --r:90deg; }
    
    body {
      background: #000;
    }
    <div class="box">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    </div>
    
    <div class="box" style="--s:30px;--o:5px;--c:yellow;--w:4px">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    </div>
    
    <div class="box" style="--s:15px;--o:20px;--c:blue;--w:10px">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    </div>

    Sun like CSS shapes