How to Create a Color Picker Web App using JavaScript - Part 1
Nitish Kumar Singh
Feb 12, 2024Hello developers! In this blog post, we will create a Color Picker Web App using JavaScript and understand how to design a color picker UI.
To create a color picker, you must know linear-gradient in web development because a color picker is created using linear-gradient. A linear gradient in web development is a graphical effect that creates a smooth transition between two or more colors along a straight line.
In this post, we will only discuss and see code to how to design color-picker UI, and in next blog this series we understand how to write logical code of color-picker.
The following code shows the syntax of linear-gradient and a linear-gradient of red and blue colors from left to right.
linear-gradient(direction, color1 position1, color2 position2, ...);
linear-gradient(to right, #ff0000, #0000ff);
To learn more about linear-gradient, go to MDN linear-gradient DOCS. Before starting, see the image below that shows what we are going to create (picker only).
To create a color picker like above, we need to design the following parts.
- Main color palette: The main palette where colors have been selected. It is a gradient with white in the top-left corner, black in the bottom edge, and a color selected from the color slider on the top-right corner. This palette gives the ability to select a color with the required brightness and darkness of the chosen color from the color slider.
- Colors slider: This is a slider (or palette) from where the color of the main palette has been selected. This is a gradient of Red, Yellow, Green, Cyan, Blue, Magenta, and Red colors with specified positions. The gradient of these colors makes it possible to select almost every type of color.
- Alpha slider: This slider is for changing the alpha channel for the selected color. It is a gradient of transparent and selected color from left to right.
- Thumb: It is a visual indicator that shows the selected value position in the respective palette or slider. I created it by using outline, border, and background with different colors so that at least one color of the thumb visualizes its presence when others are the same as the selected color.
Let's start designing. The following code blocks are HTML and CSS of the main palette.
<div class="mainPalette">
<div class="selectedColor">
<div class="to-right-white-whiteAlpha0">
<div class="to-bottom-blackAlpha0-black"></div>
</div>
</div>
</div>
.mainPalette{
position: relative;
overflow: hidden;
aspect-ratio: 15/9;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Cdefs%3E%3Cpattern id='checkerboard' width='16' height='16' patternUnits='userSpaceOnUse'%3E%3Crect width='8' height='8' fill='%23c8c8c8'/%3E%3Crect x='8' y='8' width='8' height='8' fill='%23fff'/%3E%3Crect width='8' height='8' y='8' fill='%23fff'/%3E%3Crect x='8' width='8' height='8' y='8' fill='%23c8c8c8'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23checkerboard)'/%3E%3C/svg%3E");
}
.selectedColor{
background: red;
position: absolute;
inset: 0;
}
.to-right-white-whiteAlpha0{
position: absolute;
box-shadow: inset 0 0 3px 0#5a5a5a;
inset: 0;
background: linear-gradient(to right,#fff,rgba(255,255,255,0));
}
.to-bottom-blackAlpha0-black{
position: absolute;
inset: 0;
background: linear-gradient(to top,#000,transparent);
}
See the image below, and you will automatically understand what visual appearance is created by the above HTML and CSS code.
The following code blocks are HTML and CSS of Colors and Alpha slider.
<!-- Colors Slider -->
<div class="colorsSlider"></div>
<!-- Alpha Slider -->
<div class="colorsSlider">
<div class="alphaOfSelectedColor"></div>
</div>
.colorsSlider{
box-shadow: inset 0 0 3px 0#5a5a5a;
height: 25px;
background: linear-gradient(to right,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);
overflow: hidden;
position: relative;
}
.alphaSlider{
box-shadow: inset 0 0 3px 0#5a5a5a;
height: 25px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Cdefs%3E%3Cpattern id='checkerboard' width='16' height='16' patternUnits='userSpaceOnUse'%3E%3Crect width='8' height='8' fill='%23c8c8c8'/%3E%3Crect x='8' y='8' width='8' height='8' fill='%23fff'/%3E%3Crect width='8' height='8' y='8' fill='%23fff'/%3E%3Crect x='8' width='8' height='8' y='8' fill='%23c8c8c8'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23checkerboard)'/%3E%3C/svg%3E");
overflow: hidden;
position: relative;
}
.alphaOfSelectedColor{
height: 100%;
background: linear-gradient(to right, #00000000, red);
}
The above code creates Colors and Alpha slider exactly the same as shown in the first image of this blog post. Both selectedColor of the main palette and alphaOfSelectedColor's gradient of the alpha slider are set using JavaScript.
The following code blocks are HTML and CSS of the thumb.
<span class="thumb"><span></span></span>
.thumb{
width: 25px;
height: 25px;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}
.thumb span{
display: block;
width: 15px;
height: 15px;
border-radius: 13px;
box-sizing: border-box;
background: #ffffffe6;
border: 4px solid;
outline: 2px solid #fff;
transition: all .1s linear;
}
When the thumb is at position 0
and 100%
in Colors and Alpha slider, then half of the thumb is off the slider on the left and right sides. Therefore, add translationX -50%
to the thumb, so when it's at zero positions, then half of the thumb is off the slider on the left side, and when at 100%
, then apply 100%
left CSS property so that it's half of the thumb is off the slider on the right side. In the same way, add both translation X and Y for the main palette thumb because it moves in both X and Y directions.
.colorsSlider .thumb, .alphaSlider .thumb {
transform: translateX(-50%);
}
.mainPalette .thumb{
transform: translate(-50%,-50%);
}
Add thumb HTML in sliders and main palette div like below and make sure to make all thumb and all child elements of sliders and main palette non-clickable by applying pointer-events: 'none'
so that all pointer and touch events go to the main element (div) of sliders and the main palette.
<div class="mainPalette">
<!-- rest html codes -->
<span class="thumb"><span></span></span>
</div>
<div class="colorsSlider">
<span class="thumb"><span></span></span>
</div>
<div class="alphaSlider">
<!-- rest html codes -->
<span class="thumb"><span></span></span>
</div>
.mainPalette *, .colorsSlider *, .alphaSlider *{
pointer-events: none;
}
The rest of all designing parts, you can design as you want, like adding margins
, padding
, and design a circular div
to show the selected color. Now all designing (HTML and CSS) parts have been completed.
Now move to JavaScript. In JavaScript, we can easily get X and Y coordinates (positions) of the pointer (mouse or touch) in mousemove and touchmove event handlers. In sliders, we only need the X position, and in the main palette, we need both X and Y positions. After getting the position, we calculate the color at that position in the respective palette and update the background color.
Visit the GitHub repository for the source code. If you face some problems in designing the UI of Color-Picker like in the first image or to know how to do these calculations, go to the NPM package to use it in your projects. In the next blog, we will explore how to do these calculations.
I hope you understand the designing part of the Color Picker and learn something. Happy Coding!