# Javascript: CSS Parsen um herauszufinden ob relativer Schriftgrößen verwendet werden



## marlem (7. Feb 2020)

Hallo,

egal ob das CSS im HTML eingebettet wurde oder eine CSS-Datei verwendet wird.
Ich möchte mit Javascript herausfinden ob die Schriftgröße in em oder % angegeben wurde.
Hat jemand eine Idee wie das geht?


----------



## mihe7 (7. Feb 2020)

Was heißt "die" Schriftgröße? Allein die Stylesheets auf der Seite hier enthalten 290 Angaben zur Schriftgröße...


----------



## marlem (8. Feb 2020)

> Was heißt "die" Schriftgröße?




```
body{font-size: 110%;}
body{font-size: 2.5em;}
```


----------



## marlem (8. Feb 2020)

Editieren geht nicht, deswegen Ergänzung:

```
body{font-size: 110%;}
body{font-size: 2.5em;}
body{font-size: 10.0pt;}
body{font-size: 10.0px;}
```

% und em sind skalierbar, pt und px nicht und genau das möchte ich herausfinden.
Ist die Schriftgröße relativ oder fest angegeben.


----------



## mihe7 (8. Feb 2020)

OK, ich formuliere mal anders:

Willst Du willst wissen, ob im CSS irgendwo eine bestimmte Einheit für die Schriftgröße verwendet wurde oder willst Du wissen, ob für ein Element effektiv eine relative oder feste Schriftgröße gilt?


----------



## marlem (8. Feb 2020)

> ob im CSS irgendwo eine bestimmte Einheit für die Schriftgröße verwendet



Richtig! Ich möchte wissen ob im CSS die Einheiten pt oder px verwendet werden für die Schriftgröße,
weil dann ist die Schrift nicht skalierbar und somit auch nicht barrierefrei.


----------



## mihe7 (8. Feb 2020)

Gut, dann musst Du einmal über die Elemente gehen (style-Attribut des Elements für inline-CSS) und einmal über die Stylesheets (styleSheets-Attribut von document). 

Quick & Dirty für alle Stylesheets (mit Arrow-Functions und flatMap ließe sich das schöner schreiben):

```
var units = Array.from(new Set(Array.from(document.styleSheets)
    .map(function(sheet) { return Array.from(sheet.cssRules) })
    .reduce(function(arr,x) { return arr.concat(x, []) })
    .filter(function(e) { return e.style })
    .map(function(e) { return e.style.getPropertyValue('font-size') })
    .filter(function(fs) { return fs !== '' })
    .filter(function(fs) { return /^\d+[^0-9]+$/.test(fs) })
    .map(function(fs) { return fs.match(/[^0-9]+$/) })
    .reduce(function(arr, x) { return arr.concat(x, []) })))
```

Analog dann für alle Elemente.


----------



## marlem (8. Feb 2020)

Danke! Eigentlich habe ich gedacht, ich kenne mich mit Javascript inzwischen ganz gut aus, aber Dein Code ist für mich chinessisch rückwärts


----------



## mihe7 (8. Feb 2020)

Das sieht wilder aus als es ist: document.styleSheets ist eine Liste, die erstmal zu einem Array umgewandelt wird, um filter/map/reduce verwenden zu können. Von jedem Stylesheet werden dann die cssRules genommen (wieder als Array), so dass ein Array entsteht, das Arrays enthält. Das reduce sorgt dann dafür, dass alle Elemente aller Arrays zu einem Array zusammengefasst werden. D. h. nach dem reduce hat man ein Array, das alle CSS-Regeln enthält.

Mit dem anschließenden filter werden nur solche Regeln betrachtet, die ein style-Attribut haben. Von diesen wird die font-size-Property genommen. Anschließend wird wieder gefiltert, damit nur nicht-leere font-size-Strings betrachtet werden (die Zeile kann eigentlich raus). Dann nochmals filtern: nur solche font-size Strings, die mit Ziffern beginnen und ohne Ziffern enden. Von diesen Strings wird dann nur das alphanumerische Ende genommen. Da durch beim match wieder Arrays entstehen, folgt am Ende nochmal ein reduce.

Da jetzt alle Einheiten ggf. zigfach auftreten würden, wird der ganze Spaß noch in ein Set umgewandelt, womit die Duplikate rausfliegen und zum Abschluss dieses Set wieder in ein Array.

BTW: es kann sein, dass das alles viel schöner und einfacher geht. Ich bin kein Browser-Profi.


----------



## marlem (8. Feb 2020)

Vielen Dank für Deine tolle Erklärung.


----------



## marlem (8. Feb 2020)

Mit diesem Code:

```
vHTML = document.getElementsByTagName("*");
```

Bekomme ich alle HTML-Tags einer Webseite.
Wenn ich aber versuche von dem HTML-Tag die Fontsize zu bekommen in der Console bei den Developer-Tools 
klappt das warum auch immer nicht!

Weiß jemand warum?


----------



## mihe7 (9. Feb 2020)

Was heißt "von *dem* HTML-Tag"? Du bekommst ja eine Liste von HTML-Elementen. 

Hier der Code von oben, angepasst auf die Elemente (JavaScript ist, wie ich festgestellt habe, sehr nachsichtig... Du könntest oben den Code entsprechend kürzen):

```
var units = Array.from(new Set(Array.from(document.getElementsByTagName("*"))
    .map(function(e) { return e.style.getPropertyValue('font-size') })
    .filter(function(fs) { return /^\d+[^0-9]+$/.test(fs) })
    .map(function(fs) { return fs.match(/[^0-9]+$/)[0] })))
```
oder mit Arrow-Functions:

```
var units = Array.from(new Set(Array.from(document.getElementsByTagName("*"))
    .map(e => e.style.getPropertyValue('font-size'))
    .filter(fs => /^\d+[^0-9]+$/.test(fs))
    .map(fs => fs.match(/[^0-9]+$/)[0])))
```


----------



## marlem (9. Feb 2020)

Wenn ich 

```
var units = Array.from(new Set(Array.from(document.getElementsByTagName("*"))
    .map(function(e) { return e.style.getPropertyValue('font-size') })
    .filter(function(fs) { return /^\d+[^0-9]+$/.test(fs) })
    .map(function(fs) { return fs.match(/[^0-9]+$/)[0] })))
```

In der Console ausgebe und danach mir units anzeigen lasse

```
console.log(units)
```

Bekomme ich diese Liste:


> 0: "%"
> length: 1
> __proto__: Array(0)
> 
> ...


Was kann ich nun mit diesem Ergebnis machen, damit ich die fontsize auslesen kann?


----------



## mihe7 (9. Feb 2020)

mihe7 hat gesagt.:


> Bekomme ich diese Liste:


Die kommt bei mir nur, wenn ich console.dir(units) ausführe. Kurz: das Array enthält ein Element nämlich units[0] und das ist "%".



marlem hat gesagt.:


> Was kann ich nun mit diesem Ergebnis machen, damit ich die fontsize auslesen kann?


Es ist ein Array, das die Einheiten enthält. Mach damit, was immer Du willst  

Unabhängig vom gezeigten Code: wenn Du die font-size eines Elements e haben willst: e.style.getPropertyValue("font-size")


----------



## marlem (9. Feb 2020)

Also, ich habe in meiner HTML-Datei folgendes gesetzt:

```
<style>
    body{font-size: 110%;}
    </style>
```

Wenn ich nun in der Console das hier teste:

```
var vTag = document.getElementsByTagName("body");
[B]console.log(vTag[0].style.fontSize);[/B]
```

bekomme ich nichts zurück obwohl ich die fontsize gesetzt habe.

Wenn ich das hier mache:

```
var vTag = document.getElementsByTagName("body");
undefined
vTag[0].style.fontSize = '150%';
"150%"
[B]console.log(vTag[0].style.fontSize);[/B]
150%
```

wird die 150%, die ich gesetzt habe ausgegeben.

Frage:
Warum muss ich per Javascript erst die CSS-Fontsize setzen, damit ich sie auslesen kann?


----------



## mihe7 (9. Feb 2020)

S. Kommentar #7. 

Inline-Style:

```
<elem style="font-size: 150%"/>
```
Hier bekommst Du den Stil über elem.style.fontSize zurück ("150%"). 

Dagegen musst Du für

```
elem {
  font-size: 150%;
}
```
über die Stylesheets gehen.


----------



## marlem (9. Feb 2020)

okay, habe meinen Fehler verstanden!


----------



## marlem (9. Feb 2020)

Diese Lösung funktioniert fast:

```
const body = document.querySelector('body');
const bodyFontSize = getComputedStyle(body).fontSize;
console.log(bodyFontSize);
```

Problem von der Lösung:
Ich setze die Fontsize in *Prozent* und die Lösung gibt *Pixel *zurück.


----------



## mihe7 (9. Feb 2020)

Daher die Frage in Kommentar #5


----------



## marlem (9. Feb 2020)

Habe einen guten Link entdeckt:
https://javascript.info/styles-and-classes 

Aber irgendwie liest es sich so, dass das was ich vor habe gar nicht geht!
Muss wahrscheinlich doch html und css-Datei parsen


----------



## mihe7 (9. Feb 2020)

Deine Antwort auf #5 war:


marlem hat gesagt.:


> Ich möchte wissen ob im CSS die Einheiten pt oder px verwendet werden für die Schriftgröße,


Mit dem gezeigten Code kannst Du feststellen, welche Einheiten im CSS (sowohl im Stylesheet als auch im inline Style) verwendet werden, also auch ob pt oder px.

Wenn Du jetzt etwas anderes willst, müsstest Du erklären, was.


----------



## marlem (10. Feb 2020)

> Mit dem gezeigten Code kannst Du feststellen, welche Einheiten im CSS (sowohl im Stylesheet als auch im inline Style) verwendet werden, also auch ob pt oder px.




```
<style>
    body{font-size: 110%;}
    h1{font-size: 110px;}
    </style>
```

Ich habe jetzt also % und px.

Dein Code:

```
var units = Array.from(new Set(Array.from(document.getElementsByTagName("*"))
    .map(function(e) { return e.style.getPropertyValue('font-size') })
    .filter(function(fs) { return /^\d+[^0-9]+$/.test(fs) })
    .map(function(fs) { return fs.match(/[^0-9]+$/)[0] })))
```

Ergebnis:


> ["%"]
> 0: "%"



Das ich px verwendet habe zeigt das Ergebnis nicht.


----------



## mihe7 (10. Feb 2020)

marlem hat gesagt.:


> Das ich px verwendet habe zeigt das Ergebnis nicht.


Ja, der Code von Dir verwendete Code zeigt die Einheiten, die im style-Attribut der Elemente auftreten. 

Wenn Du also im HTML z. B. schreibst `<h1 style="font-size: 12px;">`, würde Dir der Code die px anzeigen. Die Angaben aus dem Stylesheet findest Du dagegen mit dem Code aus Kommentar #7.


----------



## marlem (10. Feb 2020)

Also gut, irgendwie bin ich in Javascript noch nicht so weit, dass ich das verstehe!
Wir lassen es! Danke für Deine Bemühungen!


----------

