Multi-coloured circular div using background colou

2019-01-13 13:07发布

I'm trying to create a multi-coloured circle in CSS to simulate a wheel of fortune, I've tried using linear gradients but it just applies strips of colour running vertically through the circular div rather than being coloured areas as if you were cutting up a pizza if that makes sense?

This is the code I've tried:

background: -moz-linear-gradient(left, red, red 20%, blue 20%, blue);

Which results in:

Wheel-attempt

But I want it to look more like this?:

Coloured wheel

Is this possible in CSS or am I going to have to use a background image (I'd rather avoid this because it isn't as easy to scale as the page resizes etc..)?

7条回答
闹够了就滚
2楼-- · 2019-01-13 13:38

You can make this with using borders:

.chart {
  position: absolute;
  width: 0;
  height: 0;
  border-radius: 60px;
  -moz-border-radius: 60px;
  -webkit-border-radius: 60px;
}

#chart1 {
  border-right: 60px solid red;
  border-top: 60px solid transparent;
  border-left: 60px solid transparent;
  border-bottom: 60px solid transparent;
}

#chart2 {
  border-right: 60px solid transparent;
  border-top: 60px solid green;
  border-left: 60px solid transparent;
  border-bottom: 60px solid transparent;
}

#chart3 {
  border-right: 60px solid transparent;
  border-top: 60px solid transparent;
  border-left: 60px solid blue;
  border-bottom: 60px solid transparent;
}

#chart4 {
  border-right: 60px solid transparent;
  border-top: 60px solid transparent;
  border-left: 60px solid transparent;
  border-bottom: 60px solid yellow;
}
<div id="chart1" class="chart"></div>
<div id="chart2" class="chart"></div>
<div id="chart3" class="chart"></div>
<div id="chart4" class="chart"></div>

UPDATE 1

.pizza {
width: 300px;
height: 300px;
border-radius: 100%;
background: linear-gradient(45deg, lightblue 50%, blue 0%), linear-gradient(-45deg, green 50%, darkgreen 0%), linear-gradient(-45deg, #E5E500 50%, yellow 0%), linear-gradient(45deg, tomato 50%, red 0%);
background-size: 50% 50%;
background-position: 0% 0%, 100% 0%, 0 100%, 100% 100%;
background-repeat: no-repeat;
}
<div class="pizza"></div>

查看更多
ゆ 、 Hurt°
3楼-- · 2019-01-13 13:40

Extending on the answer of @Temani Afif, but more similar to your request:

.test {
  width: 600px;
  height: 600px;
  border-radius: 50%;
  background-size: 50% 50%;
  background-repeat: no-repeat;
  background-image: linear-gradient(150deg, transparent 63%, tomato 63%),  
    linear-gradient(120deg, transparent 36.5%, red 36.5%),
    linear-gradient(fuchsia, fuchsia),
    linear-gradient(240deg, transparent 63%, green 63%),  
    linear-gradient(210deg, transparent 36.5%, lime 36.5%),
    linear-gradient(lightgreen, lightgreen),
    linear-gradient(330deg, transparent 63%, blue 63%),  
    linear-gradient(300deg, transparent 36.5%, lightblue 36.5%),
    linear-gradient(cyan, cyan),
    linear-gradient(60deg, transparent 63%, papayawhip 63%),  
    linear-gradient(30deg, transparent 36.5%, yellow 36.5%),
    linear-gradient(gold, gold);
  background-position: right top, right top, right top, 
        right bottom, right bottom, right bottom,
        left bottom, left bottom, left bottom,
        left top, left top, left top;
}
<div class="test"></div>

查看更多
欢心
4楼-- · 2019-01-13 13:43
<div class="circle">
    <div class="table italy">
        <div class="table-cell green"></div>
        <div class="table-cell white"></div>
        <div class="table-cell red"></div>
    </div>
</div>
<div class="circle">
    <div class="table france">
        <div class="table-cell blue"></div>
        <div class="table-cell white"></div>
        <div class="table-cell red"></div>
    </div>
</div>
<div class="circle">
    <div class="table windows">
        <div class="table-cell red"></div>
        <div class="table-cell green"></div>
        <div class="table-cell yellow"></div>
        <div class="table-cell blue"></div>
    </div>
</div>
<div class="circle">
    <div class="table rainbow">
        <div class="table-cell red"></div>
        <div class="table-cell orange"></div>
        <div class="table-cell yellow"></div>
        <div class="table-cell green"></div>
        <div class="table-cell blue"></div>
        <div class="table-cell indigo"></div>
        <div class="table-cell violet"></div>
    </div>
</div>

There you have it: a reliable way to create multi-color circles. The great thing about this approach is that it doesn’t matter how many colors you have AND it works all the way back to IE.

查看更多
Root(大扎)
5楼-- · 2019-01-13 13:45

You could achieve this with css, but as you want 12 slices you will have to use a more complicated markup. If you only want to use 4 or 8, a much simpler solution using a multiple background would be possible.

  • Use the border-radius combined with a skew-trick to draw a slice of arbitratry angle
  • Use multiple wrapped slices, each rotated

Another idea which I would prefer: Use a svg graphic for it.

.container {
  position: absolute;
  left: 300px;
  top: 0;
}

.wrap {
  position: absolute;
  transform: rotate(30deg);
  transform-origin: 0% 100%;
}

.slice {
  height: 100px;
  width: 100px;
  overflow: hidden;
  transform-origin: 0% 100%;
  transform: skew(-60deg);
  position: relative;
}

.slice::before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 0 100% 0 0;
  transform-origin: 0% 100%;
  transform: skew(60deg);
}

.wrap-0 {
  transform: rotate(0deg);
}

.wrap-0 .slice::before {
  background: hsl(0, 100%, 50%);
}

.wrap-1 {
  transform: rotate(30deg);
}

.wrap-1 .slice::before {
  background: hsl(30, 100%, 50%);
}

.wrap-2 {
  transform: rotate(60deg);
}

.wrap-2 .slice::before {
  background: hsl(60, 100%, 50%);
}

.wrap-3 {
  transform: rotate(90deg);
}

.wrap-3 .slice::before {
  background: hsl(90, 100%, 50%);
}

.wrap-4 {
  transform: rotate(120deg);
}

.wrap-4 .slice::before {
  background: hsl(120, 100%, 50%);
}

.wrap-5 {
  transform: rotate(150deg);
}

.wrap-5 .slice::before {
  background: hsl(150, 100%, 50%);
}

.wrap-6 {
  transform: rotate(180deg);
}

.wrap-6 .slice::before {
  background: hsl(180, 100%, 50%);
}

.wrap-7 {
  transform: rotate(210deg);
}

.wrap-7 .slice::before {
  background: hsl(210, 100%, 50%);
}

.wrap-8 {
  transform: rotate(240deg);
}

.wrap-8 .slice::before {
  background: hsl(240, 100%, 50%);
}

.wrap-9 {
  transform: rotate(270deg);
}

.wrap-9 .slice::before {
  background: hsl(270, 100%, 50%);
}

.wrap-10 {
  transform: rotate(300deg);
}

.wrap-10 .slice::before {
  background: hsl(300, 100%, 50%);
}

.wrap-11 {
  transform: rotate(330deg);
}

.wrap-11 .slice::before {
  background: hsl(330, 100%, 50%);
}
<div class="container">
  <div class="wrap wrap-0">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-1">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-2">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-3">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-4">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-5">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-6">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-7">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-8">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-9">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-10">
    <div class="slice"></div>
  </div>
  <div class="wrap wrap-11">
    <div class="slice"></div>
  </div>
</div>

查看更多
何必那么认真
6楼-- · 2019-01-13 13:50

CSS Tricks has a post about conic gradients that describes the "colorful umbrella" as an intermediate step, which looks perfect for your use. I've put it together into a Code Pen for convenience.

HTML:

<div class="wheel">
  <ul class="umbrella">
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
  </ul>
</div>

SCSS:

@mixin circle($size) {
  content: "";
  position: absolute;
  border-radius: 50%;
  width: $size;
  height: $size;
  left: calc(50% - #{$size/2});
  top: calc(50% - #{$size/2});
}

$wheel: 15em;
.color {
  @include circle($wheel);
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
  &:after {
    @include circle($wheel);
    background: blue;
    clip: rect(0, #{$wheel/2}, $wheel, 0);
    transform: rotate(45deg);
  }
}

.color, .color:nth-child(n+7):after {
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
}
.color:after, .color:nth-child(n+7) {
  @include circle($wheel);
  clip: rect(0, #{$wheel/2}, $wheel, 0);
}

$colors: (#9ED110, #50B517, #179067, #476EAF, #9f49ac, #CC42A2, #FF3BA7, #FF5800, #FF8100, #FEAC00, #FFCC00, #EDE604);
@for $i from 0 to length($colors) {
  .color:nth-child(#{1+$i}):after {
    background-color: nth($colors, $i+1);
    @if $i < 6 {
      transform: rotate(#{30*(1+$i)}deg);
      z-index: #{length($colors)-$i};
    } @else {
      transform: rotate(#{-30+(30*(1+$i))}deg);
    }
  }
}

As a side note, if your only issue with background images is the scaling issue, keep in mind that SVG images scale smoothly, since they're basically vector graphics. (You'd have to draw that manually, but the image would scale.)

查看更多
狗以群分
7楼-- · 2019-01-13 13:51

A solution to have something is to use multiple background layer considering rotated linear-gradient. We can also rely on pseudo-element and some transparent colors.

Then simply adjust the degrees, colors, opacity of colors and position of pseudo element to obtain any chart you want:

.circle {
  margin: 20px;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: 
    linear-gradient(to right, rgba(255,0,0,0.5) 50%, yellow 0%), 
    linear-gradient(-110deg, black 50%, pink 0%);
  position: relative;
  overflow: hidden;
}

.circle:after,
.circle:before{
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}
.circle:after {
  background: linear-gradient(-45deg, rgba(255, 180, 180, 0.5) 50%, transparent 0%);
    bottom: 50%;
    left: 50%;
}

.circle:before {
  background: 
    linear-gradient(0deg, rgba(128, 169, 170, 0.5) 50%, transparent 0%), 
    linear-gradient(50deg, rgba(0, 169, 170, 1) 50%, transparent 0%);
}
<div class="circle"></div>

Here is more example considering different configuration

  1. Using only one element and multiple gradient:

.circle {
  margin: 20px;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(0deg, rgba(0, 255, 217, 0.4) 50%, transparent 0%), 
              linear-gradient(45deg, rgba(0, 128, 0, 0.4) 50%, transparent 0%), 
              linear-gradient(90deg, rgba(11, 255, 0, 0.4) 50%, transparent 0%), 
              linear-gradient(135deg, pink 50%, transparent 0%), 
              linear-gradient(180deg, brown 50%, transparent 0%),
              linear-gradient(225deg, yellow 50%, transparent 0%),
              linear-gradient(270deg, red 50%, transparent 0%);
  position: relative;
  overflow: hidden;
}
<div class="circle"></div>

  1. Using multiple elements and one gradient per element :

.circle {
  margin: 20px;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(to right, red 50%, yellow 0%);
  position: relative;
  overflow: hidden;
}

.circle:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: linear-gradient(45deg, rgba(255, 180, 180, 0.5) 50%, transparent 0%);
}

.circle:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: linear-gradient(125deg, rgba(128, 169, 170, 0.5) 50%, transparent 0%);
}

.circle-alt {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(to bottom, rgba(0, 250, 0, 0.5) 50%, rgba(0, 250, 255, 0.5) 0%);
  position: absolute;
  overflow: hidden;
}
<div class="circle">
  <div class="circle-alt"></div>
</div>

  1. Using Multiple elements and multiple gradients per elements and only solid color (without changing background-position like the answer of @vals) :

.circle {
  margin: 20px;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(to right, red 50%, transparent 0%), 
              linear-gradient(225deg, transparent 50%, blue 0%),
              linear-gradient(0deg, green 50%, transparent 0%),
              linear-gradient(-45deg, black 50%, transparent 0%),
              linear-gradient(-90deg, yellow 50%, transparent 0%);
  position: relative;
  overflow: hidden;
}

.circle:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 50%;
  right: 50%;
  background:linear-gradient(45deg,lightblue 50%, transparent 0%)
}
.circle:after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  bottom: 0;
  right: 50%;
  background:linear-gradient(135deg, brown 50%, pink 0%);
}
<div class="circle"></div>

  1. The wheel of fortune (With rotation !):

.circle {
  margin: 20px;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(to right, #06b51d 50%, transparent 0%), 
              linear-gradient(60deg, #7e00ff 50%, transparent 0%), 
              linear-gradient(30deg, #ff00bd 50%, transparent 0%), 
              linear-gradient(0deg, #ff0000 50%, transparent 0%), 
              linear-gradient(-30deg, #ff4700 50%, transparent 0%), 
              linear-gradient(-60deg, #ffa500 50%, transparent 0%), 
              linear-gradient(-90deg, #ffff00 50%, transparent 0%);
  position: relative;
  overflow: hidden;
  animation: rotate 6s linear infinite;
}
.circle:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 50%;
  right: 50%;
  background: linear-gradient(210deg, transparent 64%, #09ffa5 0%),
              linear-gradient(240deg, transparent 37%, #34ff00 0%);
}

.circle:after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  bottom: 0;
  right: 50%;
  background:linear-gradient(150deg, #00acff 37%, transparent 0%),
             linear-gradient(120deg, #0075ff 63%, #1200ff 0%);
}
@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
<div class="circle"></div>

查看更多
登录 后发表回答