I use a JavaScript-generated HTML5 color picker element to let the user set the color of another element. When the browser executes input type="color"
it draws a rectangle that shows the currently selected color. I name this rectangle the “color well”. The color well can be styled:
const pickerElem = document.createElement('input');
pickerElem.setAttribute ('type', 'color');
pickerElem.setAttribute ('style', "position: absolute; "
+ "top: 10px;" + "left: 10px;"
+ "width: 100px;" + "height: 100px;");
document.body.appendChild(pickerElem);
This draws the color well as expected, but with a white border about five pixels wide. I want to delete the white border.
I’ve tried adding properties like: border: none;
, border-style: hidden;
, padding: 0;
, margin: 0;
and border-color: none;
to the style, but the browser ignores them.
If I use border-color: black;
the browser adds a thin black border around the inner white border, but doesn’t change the inner border color.
How can I style the picker to completely delete the inner white border?
Since the color picker render is mostly ruled by the browser and hard to custom style, you may choose to embed it inside a wrapper div and set its opacity as zero and yet have a way to pick the color chosen to style such wrapper.
Here I used a wrapper div styled with the css rule .colorpicker
and its background color controlled by a function called when the oninput
event triggers on the embedded color picker:
function changeWrapperColor(embeddedColorPicker) {
embeddedColorPicker.parentElement
.style.backgroundColor = embeddedColorPicker.value;
}
.colorpicker {
position: relative;
width: 100px;
height: 100px;
background-color: black;
border: dashed 4px gray;
}
.colorpicker input[type="color"] {
opacity: 0;
position: absolute;
width: 100%;
height: 100%;
cursor: pointer;
}
<div class="colorpicker">
<input type="color" oninput="changeWrapperColor(this)"/>
</div>
As Diego suggested, you could wrap your input in a wrapper and update the background color on change
.
This solution below provides a reusable function (plugin) that can be used to handle multiple inputs. It is even capable of syncing inputs with predefined value
attributes.
CustomColorPicker(); // Invoke
function CustomColorPicker(className=".color-picker") {
function syncWithInput(colorPicker) {
if (!colorPicker) return;
const input = colorPicker.querySelector('input[type="color"]');
if (!input) return;
colorPicker.style.backgroundColor = input.value;
colorPicker.title = input.value; // Update tooltip
}
function handleColorChange({ target }) {
syncWithInput(target.closest(className));
}
document.querySelectorAll(className).forEach(syncWithInput);
document.addEventListener('change', handleColorChange);
}
*, *::before, *::after { box-sizing: border-box; }
html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
body { display: flex; align-items: center; justify-content: center; gap: 1rem; background: #222; }
.color-picker {
display: flex;
position: relative;
aspect-ratio: 1 / 1;
background-color: black;
border: dashed thin white;
width: 3rem; /* You can change this */
}
.color-picker > input[type="color"] {
opacity: 0;
position: absolute;
flex: 1;
cursor: pointer;
}
<!-- Red -->
<div class="color-picker">
<input type="color" value="#FF0000" />
</div>
<!-- Green -->
<div class="color-picker">
<input type="color" value="#00FF00" />
</div>
<!-- Blue -->
<div class="color-picker">
<input type="color" value="#0000FF" />
</div>
Can you give us a minimal reproducible example of what problem you are having?
The given code is enough to reproduce the problem already; and even in “plain HTML” form without any JS involved, the issue is present, as f.e. with the basic example under developer.mozilla.org/en-US/docs/Web/HTML/Element/input/… Not sure if there is anything that can be done about it though. I was not able to identify any property to “turn it off”, and hiding it via a clip-path or something would rely on a magic number of “about five pixels”, but if any browser applies a different one, that might again fail in unwanted ways.
If you eliminate the border and set
background: transparent
, the space will still be there, but less noticeable.FYI: Looks like there is a way to specify this directly after all, see stackoverflow.com/a/11471224/1427878