29

I'm searching online and I didn't find anything. I'm trying to update the placeholder color of a textbox using javascript, but how can I do that? I have a color picker and the color is changing.

If I have something like this in my CSS, how can I update it?

::placeholder {
  color: red;
}
<input placeholder="placeholder" />

Is there a javascript command to edit this? Something like

document.getElementById('text').style.placeholderColor = newColor;
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Manuel Rizzo
  • 585
  • 6
  • 14

5 Answers5

50

Use CSS variables. You can also target only the needed element

function update() {
  document.querySelector('input[type=text]').style.setProperty("--c", "blue");
}
::placeholder {
  color: var(--c, red);
}
<input type="text" placeholder="I will be blue">
<input type="number" placeholder="I will remain red">
<button onclick="update()">change</button>

CSS variables are useful when it comes to modify pseudo elements that you cannot access with JS such as :before/:after/::placeholer/::selection, etc. You simply define your custom property that you can easily update on the main element and the pseudo element will inherit it.

Related : Selecting and manipulating CSS pseudo-elements such as ::before and ::after using jQuery

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
4

As stated in the other answers, you cannot change pseudo-element styles inline. However, you can modify the CSS rule in the <style> itself, and you don't need a browser support ing CSS variables for that. Access the stylesheet and either get the existing rule or insert your own, then play with its style declarations like you would with an element .style:

const {sheet} = Object.assign(document.head.appendChild(document.createElement("style")), {type: "text/css" });
const placeholderStyle = sheet.rules[sheet.insertRule("::placeholder {}")].style;
placeholderStyle.color = "red";

Object.assign(document.body.appendChild(document.createElement("input")), {
  type: "button", value: "Color!", onclick() {
    placeholderStyle.color = "#"+Math.round(Math.random()*0xFFF).toString(16).padStart("0",3);
}});
<input placeholder="placeholder" />
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • How easy can this be changed to consider a dynamic selector? I suppose there is a more efficient way than this: https://jsfiddle.net/xqu9g7r2/1/ or probably not? – Temani Afif Feb 20 '19 at 21:37
  • @TemaniAfif You probably don't want to create a new rule on every `update` call, [like this](https://jsfiddle.net/bwv6qkpz/1/). But in general, yes, you need one rule per selector. – Bergi Feb 20 '19 at 22:18
  • 1
    yes, the update was somehow what I am looking for. Thanks – Temani Afif Feb 20 '19 at 22:26
1

There is another approach, but it's somewhat hacky: use JS to append more CSS to the end of the body. Browsers will override current CSS with the newest CSS, assuming the rules are identical.

function changeColor(toColor) {
  addCSS = document.createElement('style');
  addCSS.innerHTML = "::placeholder { color: " + toColor + "; }";
  document.body.append(addCSS);
}
::placeholder { color: green; }
<input type="text" placeholder="placeholder">
<button onclick="changeColor('red')">red</button>
<button onclick="changeColor('blue')">blue</button>
tdv
  • 21
  • 2
0

If the placeholder color semantics depends on some state, it can be set indirectly

::placeholder { color: green; }
.warn::placeholder { color: red; }
<input id="test" placeholder="hello">
<button onclick="test.classList.toggle('warn')">Warning!</button>

In many cases this doesn't require javascript at all:

::placeholder { color: green; }
.color::after { content: 'green'; }

:checked + .color + ::placeholder { color: red; }
:checked + .color::after { content: 'red'; }
<input type="checkbox" id="color01">
<label class="color" for="color01">Color: </label>
<input placeholder="hello">
Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
0

The snippet below works without needing to make any changes to any existing CSS. You would need to modify it to work with your color picker, but hopefully this will give you something to start with.

const placeholder = document.createElement("style");
placeholder.innerHTML = `::placeholder { color:red;font-weight:bold;font-size:1.25rem;} #plchld { font-size:1.25rem;text-align:center; } `;
const plchld = document.getElementById("plchld");
plchld.addEventListener("click", function () {
  plchld.setAttribute("placeholder", "Now I'm Bright Red!");
  document.form.appendChild(placeholder);
});
plchld.addEventListener("blur", function () {
  plchld.setAttribute("placeholder", "now I'm a dreary gray again...");
  document.form.removeChild(placeholder);
});
<form name="form" action="">
<input type="text" id="plchld" size="28" placeholder="I'm currently a dreary shade of gray...">
</form>  
Realto619
  • 83
  • 2
  • 7