• Light
  • Dark
  • Darkest
  • Medium
  • Large
  • LTR
  • RTL
  • Default
  • Express

Color wheel

Component status
Contribution
Current version@spectrum-css/colorwheel@4.1.3
ReleasedSeptember 13, 2024
S2-foundations@spectrum-css/colorwheel@5.0.0-s2-foundations.13
ReleasedSeptember 12, 2024

Usage notes


  • For a given rotation on the wheel, X, the .spectrum-ColorHandle should be moved by applying the style property transform: translate(${Y * Math.cos(X)}px, ${Y * Math.sin(X)}px), where Y is ((radius - .spectrum-colorwheel-track-width) / 2))
  • Set the value attribute of .spectrum-ColorWheel-value to the currently selected color (i.e. hsl(326, 100%, 50%))
  • Add .is-dragged when the handle is being dragged
  • To display with ColorArea inside of ColorWheel, add ColorArea to spectrum-ColorWheel-colorarea-container with style="--mod-colorarea-width: 70.1%; --mod-colorarea-height: 70.1%"
  • .spectrum-colorwheel-colorarea-container-size is hard coded to position the ColorArea within the ColorWheel using .spectrum-color-wheel-color-area-margin. Using JS container size can be calcaulted with Math.sqrt(2 * R * R), where R is the innerRadius as calcaulted for the clip paths
  • .spectrum-colorwheel-path, .spectrum-colorwheel-path-borders and .spectrum-colorwheel-colorarea-container are hard coded in CSS and include token values in custom CSS variables so they can be accessed with JS to and used to calcualte these values, const wheel = document.querySelector(".spectrum-ColorWheel-wheel") getComputedStyle(wheel).getPropertyValue('--track-width'))

Variants


Standard
Contribution

Show markup
<div class="spectrum-ColorWheel">
  <div class="spectrum-ColorWheel-inner">
    <div class="spectrum-ColorWheel-colorarea-container"></div>
  </div>
  <div class="spectrum-ColorWheel-border">
    <div class="spectrum-ColorWheel-wheel"></div>
  </div>
  <div class="spectrum-ColorHandle spectrum-ColorWheel-handle">
    <div class="spectrum-ColorHandle-inner" style="background-color: rgb(255, 0, 0)"></div>
    <svg class="spectrum-ColorLoupe">
      <g transform="translate(1 1)">
        <path class="spectrum-ColorLoupe-inner" d="M24,0A24,24,0,0,1,48,24c0,16.255-24,40-24,40S0,40.255,0,24A24,24,0,0,1,24,0Z" fill="rgb(255, 0, 0)" />
        <path class="spectrum-ColorLoupe-outer" d="M24,2A21.98,21.98,0,0,0,2,24c0,6.2,4,14.794,11.568,24.853A144.233,144.233,0,0,0,24,61.132,144.085,144.085,0,0,0,34.4,48.893C41.99,38.816,46,30.209,46,24A21.98,21.98,0,0,0,24,2m0-2A24,24,0,0,1,48,24c0,16.255-24,40-24,40S0,40.255,0,24A24,24,0,0,1,24,0Z"/>
      </g>
    </svg>
  </div>
  <input type="range" class="spectrum-ColorWheel-slider" aria-label="hue" min="0" max="360" step="`">
</div>

Disabled
Contribution

Show markup
<div class="spectrum-ColorWheel is-disabled">
  <div class="spectrum-ColorWheel-inner">
    <div class="spectrum-ColorWheel-colorarea-container"></div>
  </div>
  <div class="spectrum-ColorWheel-border is-disabled">
    <div class="spectrum-ColorWheel-wheel is-disabled"></div>
  </div>
  <div class="spectrum-ColorHandle spectrum-ColorWheel-handle is-disabled">
    <div class="spectrum-ColorHandle-inner" style="background-color: rgb(255, 0, 0)"></div>
    <svg class="spectrum-ColorLoupe">
      <g transform="translate(1 1)">
        <path class="spectrum-ColorLoupe-inner" d="M24,0A24,24,0,0,1,48,24c0,16.255-24,40-24,40S0,40.255,0,24A24,24,0,0,1,24,0Z" fill="rgb(255, 0, 0)" />
        <path class="spectrum-ColorLoupe-outer" d="M24,2A21.98,21.98,0,0,0,2,24c0,6.2,4,14.794,11.568,24.853A144.233,144.233,0,0,0,24,61.132,144.085,144.085,0,0,0,34.4,48.893C41.99,38.816,46,30.209,46,24A21.98,21.98,0,0,0,24,2m0-2A24,24,0,0,1,48,24c0,16.255-24,40-24,40S0,40.255,0,24A24,24,0,0,1,24,0Z"/>
      </g>
    </svg>
  </div>
  <input type="range" class="spectrum-ColorWheel-slider" aria-label="hue" min="0" max="360" step="`">
</div>

Standard with ColorArea
Contribution

Show markup
<div class="spectrum-ColorWheel">
  <div class="spectrum-ColorWheel-inner">
    <div class="spectrum-ColorWheel-colorarea-container">
      <div class="spectrum-ColorArea" style="--mod-colorarea-width: 70.1%; --mod-colorarea-height: 70.1%">
        <div class="spectrum-ColorArea-gradient" style="background: linear-gradient(to top, black 0%, rgba(0, 0, 0, 0) 100%), linear-gradient(to right, white 0%, rgba(0, 0, 0, 0) 100%), rgb(255, 0, 0);"></div>
        <div class="spectrum-ColorHandle spectrum-ColorWheel-ColorArea-handle">
          <div class="spectrum-ColorHandle-inner" style="background-color: rgb(255, 0, 0)"></div>
            <svg class="spectrum-ColorLoupe">
              <!-- use ColorLoupe markup here -->
            </svg>
        </div>
      <input type="range" class="spectrum-ColorArea-slider" name="x" aria-label="saturation and value" min="0" max="1" step="0.01">
      <input type="range" class="spectrum-ColorArea-slider" name="y" aria-label="saturation and value" min="0" max="1" step="0.01">
    </div>
    </div>
  </div>
  <div class="spectrum-ColorWheel-border">
    <div class="spectrum-ColorWheel-wheel"></div>
  </div>
  <div class="spectrum-ColorHandle spectrum-ColorWheel-handle">
    <div class="spectrum-ColorHandle-inner" style="background-color: rgb(255, 0, 0)"></div>
    <svg class="spectrum-ColorLoupe">
      <!-- use ColorLoupe markup here -->
    </svg>
  </div>
  <input type="range" class="spectrum-ColorWheel-slider" aria-label="hue" min="0" max="360" step="`">
</div>

Custom Properties API


This component can be modified via its --mod-* prefixed custom properties. A list of those prefixed custom properties can be found here.

Migration Guide


  • Colorwheel no longer displays a canvas variant
  • ColorWheel refactored to use a clip-path instead of an svg with a mask