This is very old-school webdev, but I recently had reason to create a styled placeholder. Or specifically, a placeholder where part of the placeholder text has a different style. This doesn't seem possible to do reasonably without vendor-prefixed web APIs. Here's how you can do it.

<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Conforming HTML5 Template</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
#sp-container {
    position: relative;

#sp-placeholder {
    position: absolute;

   /* non-essential; mimic default placeholder */
    font-family: sans-serif;
    font-size: 14px;
    color: #777777;

    /* vertically centre */
    top: 50%;
    transform: translate(0%, -50%);
const PLACEHOLDER_ID = 'sp-placeholder';
const INPUT_ID = 'sp-input';

function onReady() {
    const span = document.getElementById(PLACEHOLDER_ID);
    const input = document.getElementById(INPUT_ID);

    const maybeShow = () => {
        if (input.value === "") {
   = 'inline-block';

    const hide = () => { = 'none';

    // If the value was pre-filled by some query param, don't show the hint.
    const maybeHide = () => {
        if (input.value !== "") {

    // To hide on focus:
    //input.addEventListener('focus', hide)
    input.addEventListener('input', hide)
    input.addEventListener('blur', maybeShow);


document.addEventListener('DOMContentLoaded', onReady);
<form id="sp-container">
<span id="sp-placeholder">Enter text <strong>here</strong></span>
<input type="text" id="sp-input"/>
<input type="submit"/>

Several things to note here. This uses the relative-inside-absolute trick to take the placeholder span out of the main flow. Note that if the form is submitted, and the user then presses the back button, the form values will be recalled by default on page load. In this case, you should hide the placeholder span. I'm not totally sure that this solution actually handles that properly, although it attempts to.

The vertical centring can be handled either through the top/translate trick shown above, or it can be handled through tricky margins and calc(). I didn't have much luck with flexbox in this case, although it may also be a possibility.