Specificity – Die Rangordnung im CSS

Bevor wir genauer auf das Thema eingehen stellen wir uns einmal folgende Frage:

Wie wird das Resultat bei folgendem DOM/CSS aussehen?

<style>
  main p {
    color: red;
  }
  main p {
    color: green;
  }
</style>
<main>
  <p>Text 1</p>
</main>
<p>Text 2</p>

Hier haben wir 2 mal den gleichen Selektor aber unterschiedliche Properties innerhalb dieser Selektoren.

Jedoch wie Screenshot zu sehen wird der 2 Selektor angewandt, nicht der erste.

Grund dahinter ist, dass immer die zuletzt definierten Stylings angewendet werden, die für einen Selektor definiert wurden. Egal ob die Datei über eine extra .css Datei eingebunden wurde oder ob das CSS in der .html definiert wurde.

Elemente, Klassen, IDs und Inline Styling

Element-Selektoren

Element-Selektoren haben KEINEN Prefix und bestehen somit nur aus dem Namen des HTML-Tags ohne die <>

main {
  color: red;
}
<main></main>

Klassen-Selektoren

Klassen-Selektoren haben den Prefix . und greifen auf alle HTML-Tags mit der definierten Klasse.

.my-class {
  color: green;
}
<div class="my-class"></div>
<main class="my-class"></div>
<p class="my-class"></p>

ID-Selektoren

ID-Selektoren haben den Prefix # und greifen auf alle HTML-Tags mit der definierten ID.
Jedoch muss hier dazu gesagt werden, dass laut HTML Spezifikation eine vergebene ID nur einmal im DOM vorkommen darf und nicht mehrmals vergeben werden darf!

#my-id {
  color: teal;
}
<div id="my-id"></div>

Die Rangordnung

Nun zum wichtigsten Thema in diesem Bereich: Wann greift welcher Selektor?

Wie in den vorherigen Beiträgen schon kurz beschrieben wird immer der zuletzt definierte Selektor angewendet. Jedoch was machen wir, wenn wir nicht an letzter Stelle im DOM sind für unser Styling?

Problem

<style>
  p {
    color: red;
  }
  <!-- PLUGIN CSS START -->
  p {
    color: green;
  }
  <!-- PLUGIN CSS END -->
</style>
<main>
  <p>Text 1</p>
</main>

Hier haben wir ein DOM, welches den Text innerhalb des Paragraphs nun grün anzeigt da die 2 Selektoren gleichwertig sind.

Wie aber in den HTML Kommentaren zu sehen, ist der 2 Selektor von einem Plugin eingefügt worden und daher sollten wir diesen nicht anpassen. Wir wollen aber, dass die Textfarbe rot ist und nicht grün.

Lösung

Die „Specificity“ von unserem Selektor erhöhen.

<style>
  main p {
    color: red;
  }
  <!-- PLUGIN CSS START -->
  p {
    color: green;
  }
  <!-- PLUGIN CSS END -->
</style>
<main>
  <p>Text 1</p>
</main>

Wie funktioniert das?

Der Browser vergibt jedem Selektor ein „Ranking“ mit dem definiert wird, wie „spezifisch“ ein Selektor definiert wird.

Dieses Ranking baut sich wie folgt zusammen:

Hier ein paar Beispiele:

SelektorSpecificity
p0001
main p0002
.active a0011
#menu .active0110
ul#menu li.active a0113
body.ie11 .col-3 h20022

Der Browser vergleicht dann die „Specificity“ zwischen den Selektoren und derjenige Selektor, der die höchste „Specificity“ für ein Element hat, wird angewendet.

Das böse !important

Zu jedem Property kann am Ende vor dem Strichpunkt ein !important hinzugefügt werden um sozusagen dieses Property „unbedingt“ anzuwenden.

.my-class {
  color: red !important;
}

#my-id {
  color: green;
}
<div class="my-class" id="my-id"></div>

Durch das !important wird die „Specificity“ des ersten Selektors zusätzlich um 10000 erhöht (also ganz am Anfang noch eine 1 dazu) und dadurch wird der Text in diesem <div> nun rot angezeigt und nicht grün.

Das Problem besteht hier nur darin, dass es im Nachhinein nur mehr sehr mühsam möglich ist weitere Styling-Anpassungen für dieses Element bzw. diese Property durchzuführen.

Best Practises für Specificity

Prinzipiell sollte das Styling für Elemente von der „Specificity“ her sehr niedrig gehalten werden.

Daher wird empfohlen nur mit Elementen und Klassen zu arbeiten keine IDs, Inline Style Attribute oder !important zu verwenden.

Als CSS-Klassen-Struktur ist hier z.B. das BEM-Model eine Möglichkeit eine erweiterbare CSS-Klassen-Struktur aufrecht zu erhalten.

Source: https://css-tricks.com/specifics-on-css-specificity/

CSS – Styling für HTML

Cascading Style Sheets sind für das Styling und damit für das „Look&Feel“ von Webseiten zuständig.

Wie funktioniert CSS?

Gehen wir von folgendem Beispiel aus:

<!doctype html>
<html lang="de">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Beschreibung der Seite</title>
    <style>
        p {
          color: red;
        }
    </style>
  </head>
  <body>
    <p>Dieser Text ist nun rot.</p>
    <p>Dieser Text ist auch rot.</p>
  </body>
</html>

Hier haben wir also 2 Paragraphs im Body, die über das im Head-Bereich eingefügte CSS rot eingefärbt werden:

Das Beispiel zeigt uns aber auch, dass das CSS nicht nur auf das erste Element angewendet wird, auf das es zutrifft, sondern auf alle, die im DOM vorhanden sind.

Was sind Selektoren und Properties?

Selektoren sind „Wegbeschreibungen“ die zutreffen müssen um ein gewisses Styling durchzuführen.
Properties sind die anzuwendenden Stylings innerhalb eines Selektors.

Beispiel 1

p {
  color: red;
}

p ist hier der Selektor und wird auf alle Paragraphs (<p>) angewendet.
color: red; ist die Property, die gesetzt wird.

D.h. alle <p> im DOM werden mit roter Schriftfarbe angezeigt.

Beispiel 2

main > p {
  color: red;
}

Hier haben wir nun den Selektor angepasst, sodass die rote Schriftfarbe nur auf Paragraphs angewendet wird, die direkt nach einem <main> Element vorhanden sind.

D.h. bei folgendem DOM erhalten wir folgendes Ergebnis:

<!doctype html>
<html lang="de">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Beschreibung der Seite</title>
  <style>
    main > p {
      color: red;
    }
  </style>
</head>
<body>
<main>
  <p>Dieser Text ist nun rot.</p>
  <div>
    <p>Dieser Text ist nicht rot.</p>
  </div>
</main>
<p>Dieser Text ist nicht rot.</p>
</body>
</html>

Beispiel 3

main p {
  color: red;
}

Dieses Beispiel sieht fast gleich aus wie Beispiel 2, jedoch fehlt hier der > zwischen main und p. Dies verursacht, dass alle <p> innerhalb eines <main> Elements eine rote Schriftfarbe bekommen, egal wie tief dieser <p> innerhalb des <main> Elements geschachtelt wird.

<!doctype html>
<html lang="de">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Beschreibung der Seite</title>
  <style>
    main p {
      color: red;
    }
  </style>
</head>
<body>
<main>
  <p>Dieser Text ist nun rot.</p>
  <div>
    <div>
      <div>
        <div>
          <p>Dieser Text ist auch rot.</p>
        </div>
      </div>
    </div>
  </div>
</main>
<p>Dieser Text ist nicht rot.</p>
</body>
</html>

Welche Arten von Selektoren gibt es?

Es gibt 3 Hauptarten von Selektoren

  • Element-Selektoren wie z.B. main greifen nur auf HTML-Elemente <main>
  • Klassen-Selektoren wie z.B. .my-class greifen auf alle HTML-Elemente mit der Klasse class="my-class"
  • ID-Selektoren wie z.B. #my-id greifen auf alle HTML-Elemente mit der ID id="my-id"

Wie genau diese aber verbunden sind wird im Beitrag Specificity – Die Rangordnung im CSS genauer beschrieben.

Welche Möglichkeiten gibt es Selektoren miteinander zu verbinden – aka „Combinators“?

Wie in den oberen Beispielen schon kurz erwähnt hängt es davon ab, wie man mehrere Selektoren miteinander verbindet um unterschiedliche Elemente im DOM zu selektieren.

  • main > p
    • Hier werden alle p Elemente selektiert, die als direkten Parent ein main Element haben
  • main + p
    • Hier wird NUR 1 p Elemente selektiert, das parallel zu einem main Element liegt UND von der DOM Position nach diesem main Element liegt.
  • main ~ p
    • Hier werden ALLE p Elemente selektiert, die parallel zu einem main Element liegen UND von der DOM Position nach diesem main Element liegt.
  • main p
    • Hier werden alle p Elemente innerhalb eines main Elements selektiert, egal wieviele Ebenen innerhalb das p Element im main Element liegt

Siehe https://www.w3schools.com/css/css_combinators.asp für Beispiele

Wie wird CSS in HTML eingebunden?

Typischerweise sollte CSS im Head-Bereich wie folgt eingebunden werden:

<link rel="stylesheet" type="text/css" href="style.css" />

D.h. im Dateisystem liegt parallel zu einer index.html die style.css

Jedoch, wie im oberen Beispiel schon zu sehen, ist es auch möglich direkt in der HTML-Datei CSS zu schreiben (egal ob im Head oder Body-Bereich)

<style>
  ...
</style>

Der Viewport – Das Blickfenster des Browsers

Wie im Beitrag HTML – Die Struktur von Webseiten schon erwähnt ist der Viewport dafür zuständig die Webseite an die Größe des jeweiligen Endgerätes anzupassen.

Was ist der Viewport?

Der Viewport ist der für den Endbenutzer ersichtliche Bereich einer Webseite.

Dieser ist pro Endgerät immer unterschiedlich, da es einerseits auf die Bildschirmgröße als auch auf die verwendete Auflösung ankommt.

Hier die Startseite von devguide.at mit Viewport Meta-Tag als mobiles Endgerät:

Und hier ohne Viewport Meta-Tag

Wie stellt man den Viewport ein?

Essentiell dafür ist der folgende Meta-Tag im Head-Bereich:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

HTML – Die Struktur von Webseiten

Die Hypertext Markup Language (kurz HTML) ist eine textbasierte Sprache mit der (meistens) Webseiten-Strukturen aufgebaut und beschrieben werden.

HTML an sich ist KEINE Programmiersprache, da rein in HTML keine Prozesse bzw. Logik implementiert werden kann.

Einfaches Beispiel einer HTML-Datei

<!doctype html>
<html lang="de">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Beschreibung der Seite</title>
  </head>
  <body>
    <p>Dieser Text wird im Browserfenster angezeigt.</p>
  </body>
</html>

Was wird hier definiert?

  • <!doctype html>
    • Es ist eine HTML5
  • <head>
    • Startet den Head-Bereich der Webseite
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">
    • Der Viewport der Webseite passt sich an die Größe des Gerätes an
    • Was genau der Viewport der Webseite ist wird HIER erklärt.
  • <title>Beschreibung der Seite</title>
    • Dieser Text erscheint in der Titelzeile des Browsers
  • </head>
    • Endet den Head-Bereich der Webseite
  • <body>
    • Startet den Body-Bereich der Webseite
  • <p>Dieser Text wird im Browserfenster angezeigt.</p>
    • Zeigt einen „Paragraph“ mit Text auf der Webseite an
  • </body>
    • Endet den Head-Bereich der Webseite
  • </html>
    • Endet den HTML-Bereich der Webseite

Resultat

Was sind HTML-Tags?

Prinzipiell besteht eine Webseite aus Tags, die sich aus einem Start- und einem End-Tag zusammenbauen: <tag></tag>

Beispiele hierfür sind:

  • <html></html>
  • <head></head>
  • <body></body>
  • <p></p>

Jeder „Tag“ hat eine spezielle Aufgabe bzw. einen gewissen Einsatzbereich. Die wichtigsten HTML-Tags können hier nachgesehen werden: https://www.w3schools.com/tags/ref_byfunc.asp

Jedoch gibt es auch Ausnahmen, wo kein End-Tag ausgegeben wird. Beispiele:

  • <meta />
  • <img />
  • <input />
  • <br />
  • <hr />

Was sind Attribute?

Attribute sind zusätzliche Informationen, die zu einem HTML-Tag hinzugefügt werden können.

Beispiele hierfür sind:

  • href bei <a> Tags
  • src bei <img> Tags
  • type bei <input> Tags

Hier hängt es aber sehr von dem jeweiligen HTML-Tag ab welche Attribute vorausgesetzt sind und welche optional sind.

Universell einsetzbare Attribute für alle HTML-Tags sind z.B.

  • class
  • id
  • style
  • tabindex

class, id und style sind primär für das Styling zuständig, siehe den Beitrag Specificity – Die Rangordnung im CSS für eine genauere Beschreibung.

Siehe die komplette Liste an „global“ verwendbaren Attributen hier:
https://www.w3schools.com/tags/ref_standardattributes.asp

Was ist das DOM?

Das Document Object Model (kur DOM) ist die Baum-Struktur die vom HTML definiert wird.

W3Schools hat hier eine recht einfache und schöne Visualisierung von einem DOM:

Dieses „Document“ Object ganz am Anfang ist ebenso im JavaScript verfügbar und genau über dieses Object können DOM Änderungen über JS durchgeführt werden.

Bei einem invaliden DOM (z.B. ein <div> wird „geöffnet“ aber nicht mehr mit </div> geschlossen) versucht natürlich der Browser dies so gut wie möglich zu kompensieren bzw. auszubessern aber bei zu vielen Fehlern können sehr eigenartige Fehler auf der Webseite entstehen.

Daher ist es immer gut während der Entwicklung von Webseiten über den W3C Validator (https://validator.w3.org/) das aktuelle DOM zu überprüfen und mögliche Fehler auszubessern.

React Library Beispiel mit mehreren Components

Im vorherigen Beispiel wurde die Grundstruktur von React erklärt. Hier nun ein Beispiel, in dem mehrere Components gerendert werden.

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>App Layout Demo</title>
</head>

<body>
  <div id="root"></div>
  <script src="https://unpkg.com/react/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>

  <script src="https://unpkg.com/babel-standalone"></script>

  <script src="Hello.js" type="text/jsx"></script>
  <script src="NumPicker.js" type="text/jsx"></script>
  <script src="index.js" type="text/jsx"></script>

</body>

</html>

Hello.js

class Hello extends React.Component {
  render() {
    return <h1>Hello There!!!</h1>
  }
}

NumPicker.js

function getNum() {
  return Math.floor(Math.random() * 10) + 1;
}
class NumPicker extends React.Component {
  render() {
    const num = getNum();
    let msg;
    if (num === 7) {
      msg = <h2>CONGRATS YOU WIN!</h2>
    } else {
      msg = <p>Sorry, you lose!</p>
    }
    return (
      <div>
        <h1>Your number is: {num} </h1>
        {msg}
      </div>
    );
  }
}

index.js

class App extends React.Component {
  render() {
    return (
      <div>
        <Hello />
        <NumPicker />
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

Gestartet wird alles zusammen über die letzte Zeile in der index.js

Hier wird die Component <App /> in das Element mit der ID „root“ gerendert.

Die Component <App /> beinhaltet aber sowohl die <Hello /> als auch die <NumPicker /> Component. Diese müssen vorher definiert sein bevor das rendern der Components durchgeführt werden kann. Daher die Reihenfolge der JS Dateien in der index.html

Damit erhalten wir folgenden Output:

Bzw. bei der Zahl 7

Simples React Library Beispiel

React kann über ein paar JS Dateien von CDNs relativ einfach lokal ohne eine lokal laufende Node.js Instanz laufen.

Dateien

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>First Component</title>
</head>
<body>
  <div id="root"></div>

  <script src="https://unpkg.com/react/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>

  <script src="https://unpkg.com/babel-standalone"></script>
  <script src="index.js" type="text/jsx"></script>
</body>
</html>

Wie hier zu sehen beinhaltet die index.html nicht sehr viele aufregende Elemente:

  • Der <head> beinhaltet nur standard HTML5 Meta-Tags und den Title der Seite, nichts React spezifisches.
  • Direkt nach dem <body> sehen wir unser „root“ Element über den wir unsere React-App aufbauen werden.
  • Vor dem </body> sehen wir einige JS Dateien die extern und eine Datei die lokal eingebunden wird:
    • react.development.js: Basis React-Library
    • react-dom.development.js: React-DOM Erweiterung um mit dem DOM interagieren zu können
    • babel-standalone: Babel ist für die JSX und damit die Javascript-Umwandlung verantwortlich
    • index.js: unsere React-App

index.js

class Hello extends React.Component {
	render() {
		return (
			<div>
				<h1>Hello there!</h1>
				<p>I am a React Component!</p>
			</div>
		);
	}
}

ReactDOM.render(<Hello />, document.getElementById('root'));

Hier definieren wir eine Component mit dem Namen „Hello„.
D.h. sie kann über „<Hello />“ gerenderd werden.
In dieser Component beinhaltet sich nur eine render() Funktion, die definiert, was beim rendern dieser Component an DOM ausgegeben wird.

Am Ende wird lediglich definiert, dass die Componente „<Hello />“ in das Element mit der ID „root“ gerendered wird.

Dadurch erhalten wir beim Aufruf der index.html folgenden Output

Wichtig hierbei ist, dass die index.html wirklich über einen Web-Server aufgerufen wird da wegen CORS Einschränkungen das lokale einbinden von weiteren JS-Dateien nicht erlaubt ist.

Alternativ kann natürlich der JS React Code direkt in die index.html geschrieben werden, jedoch wird dies bei größeren und komplexeren Projekten mit mehreren Components nicht wartbar. Tipp hier von mir wäre z.B. der „Live Server“ vom Visual Studio Code Editor.

Virtuelles DOM und JSX

Virtuelles DOM

Ein Hauptgrund für JS Frontend Libraries und Frameworks ist das „virtuelle DOM“. Jedoch was ist das virtuelle DOM und wieso ist es performanter als das „reguläre DOM“?

Jede Änderung im „reguläre DOM“ triggered im Browser ein neu zeichnen des gesamten DOMs was sehr aufwändig und ressourcenintensiv ist.

Anstelle aber bei jeder Änderung direkt mit dem „reguläre DOM“ zu arbeiten werden Änderungen im „virtuellen DOM“ rein im JS durchgeführt und nur die Unterschiede zwischen dem alten „virtuellen DOM“ und dem neuen „virtuellen DOM“ berechnet und im „regulären DOM“ durchgeführt.

Ebenso wird nicht jede Änderung separat vom Browser ausgeführt sondern alle Änderungen werden gesammelt auf einmal ausgeführt was ebenso einen Performance-Gewinn bringt.

vdom
Source: https://reactjs.de/artikel/vdom-react/

JSX

JSX ist die Abkürzung für Javascript XML oder Javascript Syntax Extension und ist eine Erweiterung der üblichen Javascript-Grammatik für React.

Diese erlaubt es HTML in JavaScript zu schreiben:

function render() {
  return <p>Hi everyone!</p>;
}

Normalerweise würde natives JavaScript hier Fehler produzieren.

Uncaught SyntaxError: Unexpected token <

JSX erlaubt es uns aber genau dies zu tun.

Am Beispiel von „React“ kann über den Online Babel Compiler direkt „React“ HTML-Code in JavaScript Code umgewandelt werden.

D.h. es wird HTML nicht in .html Dateien geschrieben sondern HTML in .js Dateien geschrieben.

Siehe JSX in depth für mehr Details.

JS Frontend Libraries & Frameworks

Library vs Framework

Prinzipiell sollte einmal klar gestellt werden was der Unterschied zwischen einer „Library“ und einem „Framework“ ist.

Libraries sind meist „kleinere“ Code-Bündel, die es einem Entwickler erlauben gewisse Funktionalitäten leichter in einer schon vorhandenen Applikation durchzuführen. Beispiele hierfür sind Moment.js, jQuery oder Data-Driven Documents.

Frameworks sind meist „größer“ und bieten eine vorgegebene Struktur wie Daten gespeichert werden bzw. mit Daten umgegangen werden soll. Oft bieten diese wiederverwendbare Blöcke aber auch schon implementierte Sicherheitsfeatures wie XSS Protection und CSRF Tokens.

Wieso gibt es JS Frontend Libraries/Frameworks?

Gründe für JS Frontend Libraries/Frameworks gibt es unterschiedliche:

  • Performance
  • Komplette Trennung von Frontend und Backend Logik
  • Neuere Technologie / Entwickler will nicht mit alten Web-Technologien arbeiten

Was ist das Prinzip hinter JS Frontend Libraries/Frameworks?

Gehen wir einmal vom Beispiel PHP aus.

  1. Browser ruft Webseite auf
  2. Web-Server bekommt Anfrage von Browser und sucht nach dem eingestellten Document-Root
  3. Wenn es eine PHP-Datei ist wird diese Datei von dem Web-Server oder vom verbundenen PHP-FPM Prozess interpretiert
  4. Hier werden auch alle Datenbank-Queries durchgeführt, die theoretisch viel Zeit in Anspruch nehmen können
  5. Das daraus resultierende HTML und die damit verbundenen CSS und JS werden dem Browser zurückgeschickt

Wichtig hierbei ist eben der Punkt 4. bei dem Datenbank Queries beim initialen Request schon ausgeführt werden.

Im Vergleich hier der Ablauf von JS Frontend Frameworks

  1. Browser ruft Webseite auf
  2. Web-Server bekommt Anfrage von Browser und sucht nach dem eingestellten Document-Root
  3. Web-Server liefert die HTML, CSS und JS zurück ohne jegliche DB Queries zu machen
  4. Der Browser rendered das HTML und CSS und fängt an das JS zu interpretieren
  5. Im JS werden vom Client aus asynchrone AJAX Aufruf zu einer vordefinierten API durchgeführt um die aktuellen dynamischen Daten anzuzeigen

D.h. das initiale HTML ist wesentlich geringer, da das DOM typischerweise nur 1 „root“-Element beinhaltet, in welches das JS dann den dynamischen Inhalt erst einfügt.

Hauptunterschied zu PHP ist hier, dass der dynamische Inhalt erst Clientseitig eingefügt wird, nicht vorher am Server!

Dies erzeugt einen wesentlichen Performance-Gewinn beim Pagespeed was sich auch auf das Google Search Ranking auswirkt.

Ebenso wird der Backend-Code für die Verwaltung der dynamischen Daten nicht mit dem Frontend-Code zur Darstellung der dynamischen Daten vermischt.

Aktuell bekannteste JS Libraries/Frameworks (September 2019)

  • React
  • VueJS
  • Angular

Prinzipiell gibt es kein „ultimatives“ Framework welches für alle Zwecke und Projekt-Größen perfekt ist, jedoch vereinfacht gesagt kann von folgenden Aussagen ausgegangen werden:

React ist eine „leichte“ Library/Framework, welche nur ein paar Grundprinzipien (wie z.B. „Components“) zur Verfügung stellt auf dem das Projekt aufgebaut wird. Der Einstieg ist relativ einfach da es sehr viele Beschreibungen und Videos online zur Verfügung stehen die diese Grundprinzipien schnell und einfach beschreiben.

React kann im Prinzip rein als Library verwendet werden (siehe HIER), aber am Beispiel von Next.js sehen wir ein Framework, welches auf React aufgebaut ist.

VueJS beinhaltet im Prinzip die gleichen Features wie React. Ein wichtiger Unterschied zu React ist, dass VueJS standardmäßig das virtuelle DOM nicht mit JSX aufbaut. Siehe HIER für eine Beschreibung was das virtuelles DOM und JSX ist.

Angular ist wesentlich „größer“ und bietet viel mehr Funktionalität von Haus aus an. Damit ist es prinzipiell für größere Projekte besser geeignet, da viele Funktionalitäten schon zur Verfügung stehen und nicht selber implementiert werden müssen. Jedoch ist sowohl der Einstieg als auch die Wartung des Frameworks aufwändiger.