web-dev-qa-db-fra.com

Div circulaire circulaire multicolore utilisant des couleurs d'arrière-plan?

J'essaie de créer un cercle multicolore en CSS pour simuler une roue de la fortune, j'ai essayé d'utiliser des dégradés linéaires mais il applique simplement des bandes de couleur qui traversent verticalement le div circulaire plutôt que d'être des zones colorées comme si vous coupiez préparer une pizza si cela a du sens?

Voici le code que j'ai essayé:

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

Ce qui se traduit par:

Wheel-attempt

Mais je veux que ça ressemble plus à ça?:

Coloured wheel

Est-ce possible en CSS ou vais-je devoir utiliser une image d'arrière-plan (je préfère éviter cela car elle n'est pas aussi facile à mettre à l'échelle que la page est redimensionnée, etc.)?

34
EM-Creations

Vous pouvez le faire en utilisant des bordures:

.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>

MISE À JOUR 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>
19
Elvin Mammadov

Une solution pour avoir quelque chose consiste à utiliser plusieurs couches d'arrière-plan en considérant un gradient linéaire tourné . On peut aussi compter sur un pseudo-élément et quelques couleurs transparentes.

Ensuite, ajustez simplement les degrés, les couleurs, l'opacité des couleurs et la position du pseudo-élément pour obtenir le graphique que vous souhaitez:

.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>

Voici plus d'exemples en considérant une configuration différente

  1. En utilisant seulement un élément et plusieurs dégradés:
.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. En utilisant plusieurs éléments et un gradient par élément:
.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. Utilisation de Plusieurs éléments et plusieurs dégradés par éléments et uniquement couleur unie (sans changer background-position comme la réponse de @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. La roue de la fortune (Avec 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>
39
Temani Afif

Cela peut être fait en utilisant quelque chose appelé gradients coniques. Malheureusement, ils ne sont pas pris en charge par de nombreux navigateurs pour le moment. Lea Verou a cependant créé un plugin JS léger qui peut permettre leur utilisation:

https://leaverou.github.io/conic-gradient/

Cela pourrait être utilisé pour créer:

.elem {
width: 200px;
height: 200px;
background: conic-gradient(yellow 8.3%, greenyellow 0 16.6%, green 0 24.9%, darkgreen 0 33.2%, blue 0 41.5%, Violet 0 49.8%, purple 0 58.1%, pink 0 66.4%, red 0 74.7%, orangered 0 83%, orange 0 91.3%, gold 0 100%);
border-radius: 50%
}
<script src="//cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="//cdn.rawgit.com/LeaVerou/conic-gradient/gh-pages/conic-gradient.js"></script>

<div class="elem"></div>
16
SWC

S'étendant sur la réponse de @Temani Afif, mais plus similaire à votre demande:

.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>
10
vals

Vous pouvez y parvenir avec css, mais comme vous voulez 12 tranches, vous devrez utiliser un balisage plus compliqué. Si vous ne souhaitez utiliser que 4 ou 8, une solution beaucoup plus simple utilisant un arrière-plan multiple serait possible.

  • Utilisez le border-radius combiné à un astuce pour dessiner une tranche d'angle d'arbitrage
  • Utilisez plusieurs tranches enveloppées, chacune tournée

Une autre idée que je préférerais: utiliser un graphique svg pour cela.

.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>
7
Joschi

CSS Tricks a un article sur les gradients coniques qui décrit le "parapluie coloré" comme une étape intermédiaire, qui semble parfaite pour votre utilisation. Je l'ai mis dans un Code Pen pour plus de commodité.

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);
    }
  }
}

En guise de remarque, si votre seul problème avec les images d'arrière-plan est le problème de mise à l'échelle, gardez à l'esprit que les images SVG évoluent facilement, car ce sont essentiellement des graphiques vectoriels. (Vous devriez dessiner cela manuellement, mais l'image serait mise à l'échelle.)

5
joanwolk
<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>

Et voilà: un moyen fiable de créer des cercles multicolores. La grande chose à propos de cette approche est qu'elle n'a pas d'importance combien de couleurs vous avez ET cela fonctionne jusqu'à IE.

0
Learn Vern