2

I want to set the global font with JS.

currently css:

* {
    font-family: 'Lato'
}

It only works when I use *. using body instead does not work

I could change if for body like this:

document.body.style.fontFamily = "Lato"

But I want a js version for the * selector.

Chris
  • 13,100
  • 23
  • 79
  • 162
  • Why isn't `body` work in your css? –  Feb 06 '18 at 13:42
  • they vote me down for the answer you are searching for...`var elements = document.getElementsByTagName("*");` https://stackoverflow.com/questions/16518015/select-all-elements-on-a-page – messerbill Feb 06 '18 at 13:44
  • 1
    Yep, same for me messerbill. I answered that too. Clearly people think that that's the wrong approach, even though it's what the OP asked literally considering the last sentence of his question. I can agree on that though. You don't want to use JS to set the font of all your elements. – Jon Koeter Feb 06 '18 at 13:54
  • @messerbill @Jon - Its probably because you have answered `document.getElementsByTagName("*").style.fontFamily = "Lato";` whereas the correct answer is `document.getElementsByTagName("*")[0].style.fontFamily = "Lato";`. Please do recheck before you post an answer. – Gibin Ealias Feb 06 '18 at 13:56
  • @Gibin Ealias I corrected it. The downvoters could've done that too. – Jon Koeter Feb 06 '18 at 14:00
  • @GibinEalias: That would only change the *first* of them. – T.J. Crowder Feb 06 '18 at 14:02
  • @jon koeter - Done :) – Gibin Ealias Feb 06 '18 at 14:02
  • @GibinEalias no. I iterated over the Collection `var elements = document.getElementsByTagName("*"); for (var i = 0; i < elements.length; i++) { elements[i].style.fontFamily = "Lato" }` ..... rediclious – messerbill Feb 06 '18 at 14:06
  • `Please do recheck before you post an answer` Please read the answers before downvoting them – messerbill Feb 06 '18 at 14:08
  • 1
    @messerbill: Indeed, yours (I can see deleted answers thanks to >10k rep) was the only answer that *correctly* showed applying it to all elements directly. I don't think that's a good idea, but it did correctly do what you wanted it to do (and would work provided nothing on the page ever changed afterward), unlike the others posted in a similar vein... – T.J. Crowder Feb 06 '18 at 14:13

1 Answers1

3

You'll need to append a style element to do this reasonably. (To do it unreasonably, spin through every element on the page and set it via .style. See below.)

It's easy enough to do:

var style = document.createElement("style");
style.type = "text/css";
style.appendChild(
    document.createTextNode("* { font-family: 'Lato' }")
);
document.head.appendChild(style);

Of course, all the normal CSS rules apply. An element with a more-specific rule setting font-family, or a .style property setting it, will still use that more-specific setting.

This has the advantage that it applies to new elements added after you've done it as well as existing elements.


If you wanted to visit every element on the page to set .style.fontFamily explicitly on each, the quick-and-dirty version on modern browsers is:

Array.prototype.forEach.call(document.getElementsByTagName("*"), function(el) {
    el.style.fontFamily = "Lato";
});

getElementsByTagName("*") will access the browser's list of all elements in the document, if it already has one; and build it if not. (This is in contrast to querySelectorAll, which is required to always build a new one.) Then we loop over it by borrowing forEach from Array.prototype. (See the "array-like objects" part of my answer here for details.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875