0

I'm working in a WYSIWYG ad builder and trying to style the first letter ("H" in Hello) in the following manner, inline JS, which I'm limited to.

<script>
  div.innerHTML = unit.greeting;  //string value 
  div.style.color = "gray";    //works
  div.firstLetter.style.color = "orange";   // doesnt work
</script>

.

WYSIWYG output:

 <div>
    Hello
 </div>
Jake
  • 85
  • 4

6 Answers6

5

You can't do it with inline style (without wrapping the first letter in another element), but you can add a class via JavaScript, and do it with CSS:

var div = document.getElementById("target");
div.className = "the-class";
.the-class {
  color: gray;
}
.the-class:first-letter {
  color: orange;
}
<div id="target">
  Hello
</div>

If you need to generate the style dynamically, too:

var div = document.getElementById("target");
div.className = "the-class";

var style = document.createElement("style");
style.type = "text/css";
style.textContent =
  '.the-class { ' +
  '  color: gray; ' +
  '} ' +
  '.the-class:first-letter { ' +
  '  color: orange; ' +
  '}';
document.body.appendChild(style);
<div id="target">
  Hello
</div>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I don't have access to a stylesheet in this case otherwise I would have used ::first-letter – Jake May 31 '18 at 21:18
  • @Jake - You can add a `style` element dynamically, too. – T.J. Crowder May 31 '18 at 21:19
  • You can do this with inline styles. I wouldn't recommend it but it is possible. – Cory Kleiser May 31 '18 at 21:19
  • 1
    @Jake If you have access to ` – Bergi May 31 '18 at 21:19
  • @CoryKleiser - Oh? Cool! How? I mean, without introducing additional elements (which could be particularly problematic in an environment where the user is editing it). – T.J. Crowder May 31 '18 at 21:19
  • Well yeah, not without introducing a new element. But just wrapping the first character with a span and adding the inline style there would do it. – Cory Kleiser May 31 '18 at 21:21
1

This is how I would do it with JavaScript:

const div = document.querySelector("div");

div.style.color = "grey";

let string = div.textContent;

string = string.trim();

div.innerHTML = `<span style="color: orange">${string.charAt(0)}</span>${string.slice(1)}`;
<div>
  Hello
</div>
Cory Kleiser
  • 1,969
  • 2
  • 13
  • 26
0

You should wrap the first letter with a span and style it.

You can also append a style tag to the document.head and use the ::first-letter psudo-elment, for example:

const style = document.createElement('style');
style.innerHTML = 'div::first-letter { color: red }';
document.head.appendChild(style);
SasoN
  • 152
  • 1
  • 2
  • 11
0

If you only want to use javascript:

const target = document.getElementById("target");
const h = target.children[0];
h.style.color = "orange"
<div id="target">
  <span>H</span>ello
</div>
FoundNil
  • 391
  • 3
  • 15
0

My solution is inspired by this post. You can't style a pseudo-class on a particular element alone, hence my below solution. Now, since you wanted inline JS, maybe you entertained using the onload() event for inline JS. However, onload only works on certain specialized HTML tags, such as <body>, <iframe>, etc, see here. Hence I am using it on the <body> tag. You can also not use inline CSS for pseudo-classes, see here. So, I am guessing this is as close as it gets for inline JS on pseudo-classes.

<!doctype html>
<html lang="en">
<body onload="document.styleSheets[0].insertRule('.firstLetterSpecial:first-letter { color: orange; }', 0);">

    <div class="firstLetterSpecial" >
    Hello Special 1
    </div>
     <div class="firstLetterSpecial" >
    Hello Special 1
    </div>
     <div class="firstLetterSpecial" >
    Hello Special 3
    </div>
     <div >
    Hello Not special
    </div>
</body>
</html>

Now, if you dont have access to the <body> tag, you can sneak in an unused and hidden <iframe>

<!doctype html>
<html lang="en">
<body>

    <!-- I am being mean and sneak an iframe in here just to get the onload().-->
    <iframe style="display:none;"
    onload="document.styleSheets[0].insertRule('.firstLetterSpecial:first-letter { color: orange; }', 0);">
    </iframe>

    <div class="firstLetterSpecial" >
    Hello Special 1
    </div>
     <div class="firstLetterSpecial" >
    Hello Special 1
    </div>
     <div class="firstLetterSpecial" >
    Hello Special 3
    </div>
     <div >
    Hello Not special
    </div>
</body>
</html>
0

A bit iffy solution - just insert a new rule to existing rule set:

<div id="test">Hello</div>

Now lets imagine that you have at least one style sheet defined in your app, so you can simply add rules there, for example:

document.styleSheets[0].insertRule("#test{ color: #00ff00; }")
document.styleSheets[0].insertRule("#test::first-letter{ color: #ffffff; }")

For reference: https://davidwalsh.name/add-rules-stylesheets

though, I cannot imagine using this approach in production.

Vladimir M
  • 4,403
  • 1
  • 19
  • 24