HTML5-Tutorium: JavaScript: Hello World 06: Unterschied zwischen den Versionen

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg
Kowa (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
Kowa (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
 
(32 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 2: Zeile 2:


'''Musterlösung'''<br/>
'''Musterlösung'''<br/>
v01: [https://glossar.hs-augsburg.de/beispiel/tutorium/2024/wk_hello_world/wk_hello_world_06/web_v01/index.html <code>index.html</code>] ([https://validator.nu/?doc=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2024%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb_v01%2Findex.html HTML validate])<br/>
[https://glossar.hs-augsburg.de/beispiel/tutorium/2025/wk_hello_world/wk_hello_world_06/web/index.html <code>index.html</code>] ([https://validator.nu/?doc=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2025%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb%2Findex.html HTML validate], [https://css-validator.org/validator?uri=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2025%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb%2Findex.html&profile=css21&usermedium=all&warning=1&lang=de CSS validate], [https://pagespeed.web.dev/analysis?url=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2025%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb%2Findex.html Google PageSpeed])<br/>
v02: [https://glossar.hs-augsburg.de/beispiel/tutorium/2024/wk_hello_world/wk_hello_world_06/web_v02/index.html <code>index.html</code>] ([https://validator.nu/?doc=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2024%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb_v02%2Findex.html HTML validate]; Modularisierung analog zu [[HTML5-Tutorium: JavaScript: Hello World 04|Hello World 04]] v02)<br/>
v03: [https://glossar.hs-augsburg.de/beispiel/tutorium/2024/wk_hello_world/wk_hello_world_06/web_v03/index.html <code>index.html</code>] ([https://validator.nu/?doc=https%3A%2F%2Fglossar.hs-augsburg.de%2Fbeispiel%2Ftutorium%2F2024%2Fwk_hello_world%2Fwk_hello_world_06%2Fweb_v03%2Findex.html HTML validate]; Konfiguration mittels JSON analog zu [[HTML5-Tutorium: JavaScript: Hello World 04|Hello World 04]] v03)<br/>
[{{Git-Server}}/kowa/wk_hello_world_06.git Git-Repository]
[{{Git-Server}}/kowa/wk_hello_world_06.git Git-Repository]


==Anwendungsfälle (Use Cases)==
== Anwendungsfälle (Use Cases) ==
Gegenüber dem [[HTML5-Tutorium:_JavaScript:_Hello_World_05|dritten, vierten und fünften Teil des Tutoriums]]
Gegenüber dem [[HTML5-Tutorium:_JavaScript:_Hello_World_05|dritten, vierten und fünften Teil des Tutoriums]]
ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor.
ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor.


In diesem Teil des Tutoriums geht es darum, CSS durch SCSS zu ersetzen, um den CSS-Code „[[DRY]] zu machen“.
In diesem Teil des Tutoriums geht es darum, den CSS-Code „[[DRY]] zu machen“.


== Erstellen eines neuen Projekts ==
== Erstellen eines neuen Projekts ==


Erstellen Sie ein neues Projekt <code>hello_world_06</code> als Fork von <code>hello_world_05</code> (siehe [[HTML5-Tutorium: JavaScript: Hello World 02|Hello-World-02-Tutorium]]).
Erstellen Sie ein neues Projekt <code>hello_world_06</code> als Fork von <code>hello_world_05</code>.


==SCSS==
== CSS-Erweiterungen ==


Anstelle von CSS-Dateien verwenden Sie künftig SCSS-Dateien. Das ist zunächst einmal nicht weiter schwer,
CSS bietet heute dieselbe Funktionalität wie Transpiler ([[SASS]], [[Less]] etc.), die früher verwendet wurden, um fehlende Funktionalität in CSS zu integrieren. Ich werde in diesem Semester CSS an Stelle von SCSS einsetzen, so wie es von vite empfohlen wird:
das jede CSS-Datei automatisch auch eine SCSS-Datei ist. Bei der Verwendung von CSS können Sie
allerdings das Prinzip  „[[Don't repeat yourself]]“ (DRY) nicht beachten. Sie müssen für verschiedene Elemente
ständig Informationen wiederholen (gewünschter Font, Hintergrundfarbe, Größenangaben etc.). Deshalb
gibt es mehrere Projekte wie {{zB}} [[LESS]], [[Sass]]/SCSS, [[Stylus]], die den CSS-Standard erweitern, um dieses Problem
zu vermeiden. Sass verwendet allerdings eine ganz andere Syntax als CSS. Allerdings
unterstützt das Sass-Projekt auch die Sprache SCSS, die CSS einfach um weitere syntaktische Elemente ergänzt.
Zum Beispiel kann man in SCSS Konstanten definieren:


<source lang="CSS">
''Because Vite targets modern browsers only, it is recommended to use native CSS variables with PostCSS plugins that implement CSSWG drafts (e.g. postcss-nesting) and author plain, future-standards-compliant CSS.'' (https://vite.dev/guide/features)
$font-family-serif: "Times New Roman", Times, serif;
</source>


Und nun kann man in eine SCSS-Datei anstelle von <code>"Times New Roman", Times, serif</code> stets <code>$font-family-serif</code>
Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren.
schreiben, um den Font von bestimmten Elementen zu definieren.  
Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: <code>math</code>, CSS: <code>calc</code>). Es ist jetzt auch möglich CSS-Elemente zu verschachteln.
Das heißt, die Bedeutung von SCSS, Less etc. schwindet.


<source lang="CSS">
== CSS-Konstanten ==
p
{ font-family: $font-family-serif; }


label
Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren, da man damit CSS-Code [[DRY]] formulieren kann.
{ font-family: $font-family-serif; }
</source>


Wenn man nun diesen Font ändern will,
Wenn eine Konstante definiert wurde, kann man
muss das nicht mehr bei allen Elementen einzeln passieren. Es reicht, die Konstantendefinition abzuändern.
im übrigen CSS-Code mittels <code>var</code> darauf zugreifen (und nicht etwa mittels <code>const</code>, :-( )
Der SCSS-Code ist nun DRY.


==== Weiterentwicklung von CSS ====
<syntaxhighlight lang="CSS">
 
CSS entwickelt sich stetig weiter. Seit einiger Zeit werden auch hier Variablen unterstützt:
 
<source lang="CSS">
:root  
:root  
{ --font-family-serif: "Times New Roman", Times, serif; }
{ --font-family-serif: "Times New Roman", Times, serif; }
Zeile 60: Zeile 41:
label
label
{ font-family: var(--font-family-serif); }
{ font-family: var(--font-family-serif); }
</source>
</syntaxhighlight>


Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: <code>math</code>, CSS: <code>calc</code>).  
Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: <code>math</code>, CSS: <code>calc</code>).  
Das heißt, die Bedeutung von SCSS, Less etc. schwindet. Aber zurzeit bieten sie immer noch genügend mächtige Erweiterungen gegenüber CSS,
Das heißt, die Bedeutung von SCSS, Less etc. schwindet. In diesem Semester verwende ich nicht mehr SCSS, sondern nur noch CSS.
wie {{zB}} die Möglichkeit, CSS-Elemente zu verschachteln, sodass sich der Einsatz von SCSS noch lohnt.


==== Transformation von SCSS in CSS ====
Fügen Sie <code>"config"</code> als Abkürzung für <code>"./src/css/_config.css"</code> in die Datei <code>vite.config.js</code> ein.


Leider unterstützt kein Browser SCSS direkt (im Gegensatz zu CSS). Aber für was gibt es Transpiler, die eine SCSS-Datei
<syntaxhighlight lang="javascript">
automatisch in eine CSS-Datei übersetzen können. Vite unterstützt CSS-Transpiler von Haus aus. Man muss den gewünschten Transpiler lediglich installieren:
...
  resolve:
  { alias:
    { ...
      'config.css': fileURLToPath(new URL('./src/css/_config.css', import.meta.url)),
      ...
    }
  }
...
</syntaxhighlight>


<source lang="bash">
In der Datei <code>_config.css</code> werden Konstanten definiert, die von allen anderen CSS-Dateien verwendet werden können und sollen.
npm i -D sass
</source>


Benennen Sie die Datei <code>src/css/body.css</code> in <code>src/css/body.scss</code> um. Ersetzen Sie außerdem
Das heißt, das DRY-Prinzip „Konstanten gehören nicht in den Code, sondern in Konfigurationsdateien“ wird ab sofort beachtet.
in der Datei <code>src/js/main.js</code> den Import-Befehl


<source lang="javascript">
Wenn man künftig am Layout einen Zeichensatz, eine Farbe, einen Hintergrund oder Ähnliches ändern will,
import '/css/body.css';
reicht es, die entsprechenden Konstanten anzupassen und schon erzeugt Vite automatisch aktualisiere
</source>
CSS-Dateien.


durch
Durch den CSS-Import-Befehl ist es möglich, CSS-Dateien zu modularisieren.
Der Underscore <code>_</code> am Beginn des Dateinamens deutet an, dass diese CSS-Datei nur von anderen CSS-Dateien
aber nicht von HTML- oder JavaScript-Dateien importiert werden sollte.


<source lang="javascript">
'''<code>src/css/_config.css</code>'''
import '/css/body.scss';
<syntaxhighlight lang="CSS">
</source>
:root
{ --background-color:  #C5EFFC;


Wenn Sie Ihren Code nun mittels <code>npm run dev</code> laufen lassen oder mittels <code>npm run build</code> übersetzen,
  --font-family-sans:  Verdana, Helvetica, sans-serif;
sollte die Anwendung noch funktionieren, da der SASS-Loader die neue SCCS-Datei in geeigneten CSS-Code übersetzt.
  --font-family-serif: "Times New Roman", Times, serif;
 
  --font-size-base:    3vw;
  --font-size-factor:  1.25;  /* cmp. https://type-scale.com/ */
 
  --font-size-h5:      calc(pow(var(--font-size-factor),1)*var(--font-size-base));
  --font-size-h4:      calc(pow(var(--font-size-factor),2)*var(--font-size-base));
  --font-size-h3:      calc(pow(var(--font-size-factor),3)*var(--font-size-base));
  --font-size-h2:      calc(pow(var(--font-size-factor),4)*var(--font-size-base));
  --font-size-h1:      calc(pow(var(--font-size-factor),5)*var(--font-size-base));
 
  --font-size-p:      calc(pow(var(--font-size-factor),0)*var(--font-size-base));
  --font-size-p-large: calc(pow(var(--font-size-factor),2)*var(--font-size-base));
 
  --font-size-small:  calc(pow(var(--font-size-factor),-1)*var(--font-size-base));
}
</syntaxhighlight>
In dieser CSS-Datei werden folgende modernen CSS-Konstrukte verwendet:


Schwieriger ist der direkte Import von <code>head.scss</code> in der Datei <code>index.html</code>,
* Definition von Konstanten (die teilweise per Berechnung ermittelt werden)
da diese SCSS-Datei von Vite nicht in CSS transformiert wird. Ein Workaround für dieses Problem wird später vorgestellt.
* Mathematische Berechnungen: <code>calc</code>


===SCSS-Konfiguration===
Konstanten starten in CSS mit zwei Minuszeichen. Sobald eine Konstante definiert wurde,
kann sie in allen weiteren CSS-Konstrukten verwendet werden. In CSS stehen einen Operatoren zur Verfügung wie
<code>+</code>, <code>-</code>, <code>*</code> und <code>/</code>, um Maße zu berechnen. Es gibt
weitere Operatoren zum Vergleichen von Zahlen und Maßen sowie zur Berechnung von Strings und booleschen Werten:
https://sass-lang.com/documentation/operators.<ref>https://sass-lang.com/documentation/operators</ref>


In der Datei <code>_config.scss</code> werden alle von den anderen SCSS-Dateien benötigten Konstanten definiert.
Die Datei <code>_config.css</code> kann nun mit Hilfe des CSS-Befehls <code>@import 'config.css';</code> (ohne Underscore und ohne <code>.css</code>, wegen des zuvor eingeführten Vite-Aliases)
Das heißt, das DRY-Prinzip „Konstanten gehören nicht in den Code, sondern in Konfigurationsdateien“ wird ab sofort beachtet.
in die anderen beiden CSS-Dateien eingefügt werden.  
Wenn man künftig am Layout einen Zeichensatz, eine Farbe, einen Hintergrund oder Ähnliches ändern will,
reicht es, die entsprechenden Konstanten anzupassen und schon erzeugt Vite automatisch aktualisiere
CSS-Dateien.


Der Underscore <code>_</code> am Beginn des Dateinamens deutet an, dass diese SCSS-Datei nur von anderen SCSS-Dateien
=== PostCSS ===
aber nicht von HTML- oder JavaScript-Dateien importiert werden. Durch SCSS-Import-Befehle ist es möglich, auch SCSS-Dateien
zu modularisieren.


'''<code>src/css/_config.scss</code>'''
Der Inhalt der Datei <code>_config.css</code> wird defaultmäßig an den Browser ausgeliefert, obwohl sie nur CSS-Konstanten enthält.
<source lang="CSS">
Beim Einsatz vom SCSS werden Konstanten vom SCSS-Präprozessor auf dem Server während des Build-Prozesses durch ihre Werte ersetzt.
@use 'sass:math';
In CSS muss dies defaultmäßig der Browser übernehmen. Es gibt allerdings ein PostCSS-Plugin [https://www.npmjs.com/package/postcss-var-replace/v/1.0.0 postcss-var-replace], das diese Ersetzungen ebenfalls während des Build-Prozesses vornimmt. Dieses kann man in die Vite-Konfiguration integrieren:


$background-color: #C5EFFC;
Laden sie das Pluging <code>postcss-var-replace</code>:


$font-family-sans:  Verdana, Helvetica, sans-serif;
<syntaxhighlight lang="bash">
$font-family-serif: "Times New Roman", Times, serif;
npm i -D postcss-var-replace
</syntaxhighlight>


$font-size-base:    3vw;
Anschließend aktivieren Sie es in <code>vite.config.js</code>
$font-size-factor:  1.25;  /* cmp. https://type-scale.com/ */
$font-size-h5:      math.pow($font-size-factor,1)*$font-size-base;
$font-size-h4:      math.pow($font-size-factor,2)*$font-size-base;
$font-size-h3:      math.pow($font-size-factor,3)*$font-size-base;
$font-size-h2:      math.pow($font-size-factor,4)*$font-size-base;
$font-size-h1:      math.pow($font-size-factor,5)*$font-size-base;


$font-size-p:      math.pow($font-size-factor,0)*$font-size-base;
<syntaxhighlight lang="javascript">
$font-size-p-large: math.pow($font-size-factor,2)*$font-size-base;
import { postcssVarReplace }  from 'postcss-var-replace';


$font-size-small:  math.pow($font-size-factor,-1)*$font-size-base;
...
</source>
In dieser SCSS-Datei werden folgende SCSS-Erweiterungen verwendet:


* Mathematische Berechnungen: <code>@use 'sass:math';</code>
export default
* Definition von Konstanten (die teilweise per Berechnung ermittelt werden)
{ ...
* Fonts sollten aus designerischen Gründen besser lokal gespeichert und per CSS eingebunden werden.
  css:
 
  { postcss:
Konstanten starten in SCSS mit einem Dollarzeichen. Sobald eine Konstante definiert wurde,
    { plugins:  
kann sie in allen weiteren SCSS-Konstrukten verwendet werden. In SCSS stehen einen Operatoren zur Verfügung wie
      [ postcssVarReplace(),
<code>+</code>, <code>-</code>, <code>*</code> und <code>/</code>, um Maße zu berechnen. Es gibt
      ],
weitere Operatoren zum Vergleichen von Zahlen und Maßen sowie zur Berechnung von Strings und booleschen Werten:
    },
https://sass-lang.com/documentation/operators.<ref>https://sass-lang.com/documentation/operators</ref>
  },
 
  ...
Die Datei <code>_config.scss</code> kann nun mit Hilfe des SCSS-Befehls <code>@import 'config';</code> (ohne Underscore und ohne Endung)
}
in die anderen beiden SCSS-Dateien eingefügt werden. Das Sass-Package
</syntaxhighlight>
kennt diesen Befehl und führt ihn beim Erstellen der zugehörigen CSS-Dateien auch aus.


Der Import-Befehl hat erst dann einen Effekt, wenn in den anderen Dateien auf diese Konstanten zugegriffen wird.
Der Import-Befehl hat ab sofort erst dann einen Effekt, wenn in den anderen Dateien auf diese Konstanten zugegriffen wird.
Aber er schadet auch nicht, wenn auf keine der dort definierten Konstanten zugegriffen wird. Der Import-Befehl selbst
Aber er schadet auch nicht, wenn auf keine der dort definierten Konstanten zugegriffen wird. Der Import-Befehl selbst
taucht ebenso wenig in den generierten CSS-Dateien auf, wie die Konstantendefinitionen. Der Transpiler ersetzt Konstanten  
taucht ebenso wenig in den generierten CSS-Dateien auf, wie die Konstantendefinitionen. Der PostCSS-Transpiler ersetzt Konstanten in CSS-Definitionen durch ihren jeweiligen Wert.
in CSS-Definitionen durch ihren jeweiligen Wert.


Sie können nun beispielsweise in der Datei <code>head.scss</code> die Konstante <code>&#36;background-color</code>
Sie können nun beispielsweise in der Datei <code>head.css</code> die Konstante <code>--background-color</code>
verwenden. In der daraus erzeugten CSS-Datei steht weiterhin der Farbwert <code>#C5EFFC</code>;
verwenden. In dem daraus durch den Build-Befehl <code>npm run build</code> erzeugten CSS-Style-Element steht weiterhin der Farbwert <code>#C5EFFC</code>;


'''<code>src/css/head.scss</code>'''
'''<code>src/css/head.css</code>'''
<source lang="CSS">
<syntaxhighlight lang="CSS">
@import 'config';
@import 'config.css';


body
body
{ background-color: $background-color; }
{ background-color: var(--background-color); }
 
.hidden
.hidden
{ display: none; }
{ display: none; }
</source>
</syntaxhighlight>


Erstellen Sie diese Datei und führen Sie da folgenden Transpiler-Befehl aus:
Die Datei <code>body.css</code> ist deutlich umfangreicher. Daher wird der zugehörige CSS-Code
ja auch erst dynamisch gemeinsam mit der Datei <code>web/js/main.js</code> geladen.


<source lang="bash">
'''<code>src/css/body.css</code>'''
node_modules/sass/sass.js src/css/head.scss
<syntaxhighlight lang="CSS">
</source>
@import 'config.css';
 
In der Konsole sehen Sie den daraus erzeugten zugehörigen CSS-Code.
 
Die Datei <code>body.scss</code> ist deutlich umfangreicher. Daher wird der zugehörige CSS-Code
ja auch erst gemeinsam mit der Datei  <code>web/js/main.js</code> geladen.
 
'''<code>src/css/body.scss</code>'''
<source lang="CSS">
@import 'config';


html
html
Zeile 189: Zeile 176:
   text-align:      center;
   text-align:      center;
   vertical-align:  middle;
   vertical-align:  middle;
  background-color: $background-color;
   font-size:        var(--font-size-base);
   font-size:        $font-size-base !important;
   font-family:      var(--font-family-sans);
   font-family:      $font-family-sans;
}
}


Zeile 197: Zeile 183:
{ padding:  0;
{ padding:  0;
   margin:    0;
   margin:    0;
   font-size: $font-size-h1;
   font-size: var(--font-size-h1);
}
}


p, label
p, label
{ font-family: $font-family-serif;
{ font-family: var(--font-family-serif);
   font-size:  $font-size-p !important;
   font-size:  var(--font-size-p);
}
}


label, input, button
label, input
{ width:      10em;
{ width:      10em;
   font-size:  100%;
   font-size:  100%;
Zeile 228: Zeile 214:
#section_hello
#section_hello
{ p
{ p
   { font-size: $font-size-p-large !important; }
   { font-size: var(--font-size-p-large) !important; }
}
}
</source>
</syntaxhighlight>


In dieser SCSS-Datei werden folgende SCSS-Erweiterungen verwendet:
In dieser CSS-Datei werden folgende modernen CSS-Befehle verwendet:


* Import-Befehl: <code>@import 'config';</code>
* Import-Befehl: <code>@import 'config.css';</code>
* Konstanten:  <code>&#36;font-family-sans</code>, <code>&#36;font-size-base</code> etc. (Es sind noch viele weitere konstante Werte in <code>body.scss</code> enthalten, für die in <code>_config.scss</code> Konstanten definiert werden sollten)
* Konstanten:  <code>--font-family-sans</code>, <code>--font-size-base</code> etc. (Es sind noch viele weitere konstante Werte in <code>body.css</code> enthalten, für die in <code>_config.css</code> Konstanten definiert werden sollten)
* Verschachtelte Anweisungen: {{zB}} <code>h1</code> innerhalb von  <code>#section_form</code>
* Verschachtelte Anweisungen: {{zB}} <code>h1</code> innerhalb von  <code>#section_form</code>


Zeile 244: Zeile 230:
Folgendes geschrieben:
Folgendes geschrieben:


<source lang="CSS">
<syntaxhighlight lang="CSS">
#section_form
#section_form
{ text-align:  center;
{ text-align:  center;
Zeile 253: Zeile 239:
#section_form > h1
#section_form > h1
{ margin-bottom: 0.5ex; }
{ margin-bottom: 0.5ex; }
</source>
</syntaxhighlight>


Die SCSS-Variante ist deutlich strukturierter und prägnanter.
Die modernen CSS-Variante ist deutlich strukturierter und prägnanter.


<source lang="CSS">
<syntaxhighlight lang="CSS">
#section_form
#section_form
{ text-align:  center;
{ text-align:  center;
Zeile 266: Zeile 252:
   { margin-bottom: 0.5ex; }
   { margin-bottom: 0.5ex; }
}
}
</source>
</syntaxhighlight>


Insbesondere bei großen CSS-Dateien erweist sich diese kompaktere Schreibweise als vorteilhaft.
Insbesondere bei großen CSS-Dateien erweist sich diese kompaktere Schreibweise als vorteilhaft.
===Weitere SCSS-Konstrukte===
SCSS ist sehr mächtig. Es gibt neben der Import-Anweisung eine Use-Anweisung (<code>@use</code>)<ref>https://sass-lang.com/documentation/at-rules/use</ref>, die SCSS-Konstrukten im Gegensatz zur Import-Anweisung einen Namespace zuweist. Damit ist es möglich, mehrere SCSS-Module zu verwenden, auch wenn
dieses gleichbenannte Elemente enthalten, ohne dass es zu Namenskollisionen kommt.
Darüber hinaus gibt es Mixins<ref>https://sass-lang.com/documentation/at-rules/mixin</ref> und Funktionen<ref>https://sass-lang.com/documentation/at-rules/function</ref>. Mit Mixins kann man ganze Styleblöcke definieren, um sie mehrfach zu verwenden. Mixins werden mit <code>@include</code> eingebunden. Dabei kann man Argumente an die Mixins übergeben, mit denen die entsprechenden Konstanten innerhalb des Mixins initialisiert werden. Funktionen funktionieren wie Funktionen in anderen Programmiersprachen auch. Es stehen einem If-Anweisungen und Schleifen-Befehle zur Verfügung.
SCSS ist im Prinzip eine vollwertige Programmiersprache, um CSS-Dateien modular zu erstellen.
===<code>head.scss</code>===
Wie bereits erwähnt wurde, kann man die Datei <code>head.scss</code> nicht in die Datei <code>index.html</code> importieren,
da Vite den Sass-Transpiler hier nicht anwendet. Wie wir aber auch gesehen haben, kann man den Sass-Transpiler auch direkt aufrufen,
um die Datei <code>head.css</code> zu generieren. Ergänzen Sie die entsprechenden Befehle im <code>scripts</code>-Objekt in der Datei <code>package.json</code>:
<source lang="JSON">
"scripts": {
  "predev": "sass src/css/head.scss src/css/head.css",
  "dev": "vite",
  "prebuild": "sass src/css/head.scss src/css/head.css",
  "build": "vite build --emptyOutDir",
  "preview": "vite preview"
},
</source>
Wenn Sie nun <code>npm run dev</code> oder <code>npm run build</code> aufrufen, wird von <code>npm</code> jeweils automatisch zuvor
<code>npm run predev</code> bzw. <code>npm run prebuild</code> ausgeführt. in beiden Fällen wird <code>head.scss</code> in <code>head.css</code> transfprmiert.
Die Befehle <code>npm run predev</code> und <code>npm run prebuild</code> könnte man auch direkt ausführen. Das ist aber nur bei <code>npm run preview</code> nötig.
Ein Skript namens <code>view</code> gibt es nicht. Gäbe es es und würde <code>npm run view</code> würde auch in diesem Fall zunächst <code>npm run preview</code> ausgeführt werden.


==Fortsetzung des Tutoriums==
==Fortsetzung des Tutoriums==

Aktuelle Version vom 11. April 2025, 09:25 Uhr

Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:

Korrektheit: 3
(zu größeren Teilen überprüft)
Umfang: 4
(unwichtige Fakten fehlen)
Quellenangaben: 3
(wichtige Quellen vorhanden)
Quellenarten: 5
(ausgezeichnet)
Konformität: 3
(gut)

Vorlesung WebProg

Inhalt | Teil 1 | Teil 2 | Teil 3 | Teil 4 | Teil 5 | Teil 6 | Vue 1 | Vue 2 | Vue 3 | Vue 4 | Vue 5 | Vue 6

Musterlösung
index.html (HTML validate, CSS validate, Google PageSpeed)
Git-Repository

Anwendungsfälle (Use Cases)

Gegenüber dem dritten, vierten und fünften Teil des Tutoriums ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor.

In diesem Teil des Tutoriums geht es darum, den CSS-Code „DRY zu machen“.

Erstellen eines neuen Projekts

Erstellen Sie ein neues Projekt hello_world_06 als Fork von hello_world_05.

CSS-Erweiterungen

CSS bietet heute dieselbe Funktionalität wie Transpiler (SASS, Less etc.), die früher verwendet wurden, um fehlende Funktionalität in CSS zu integrieren. Ich werde in diesem Semester CSS an Stelle von SCSS einsetzen, so wie es von vite empfohlen wird:

Because Vite targets modern browsers only, it is recommended to use native CSS variables with PostCSS plugins that implement CSSWG drafts (e.g. postcss-nesting) and author plain, future-standards-compliant CSS. (https://vite.dev/guide/features)

Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren. Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: math, CSS: calc). Es ist jetzt auch möglich CSS-Elemente zu verschachteln. Das heißt, die Bedeutung von SCSS, Less etc. schwindet.

CSS-Konstanten

Eine ganz wesentliche Erweiterung ist die Möglichkeit Konstanten zu definieren, da man damit CSS-Code DRY formulieren kann.

Wenn eine Konstante definiert wurde, kann man im übrigen CSS-Code mittels var darauf zugreifen (und nicht etwa mittels const, :-( )

:root 
{ --font-family-serif: "Times New Roman", Times, serif; }

p
{ font-family: var(--font-family-serif); }

label
{ font-family: var(--font-family-serif); }

Auch die Möglichkeit, Werte zu berechnen, gibt es in der Zwischenzeit (SCSS: math, CSS: calc). Das heißt, die Bedeutung von SCSS, Less etc. schwindet. In diesem Semester verwende ich nicht mehr SCSS, sondern nur noch CSS.

Fügen Sie "config" als Abkürzung für "./src/css/_config.css" in die Datei vite.config.js ein.

...
  resolve:
  { alias:
    { ...
      'config.css': fileURLToPath(new URL('./src/css/_config.css', import.meta.url)),
      ...
    }
  }
...

In der Datei _config.css werden Konstanten definiert, die von allen anderen CSS-Dateien verwendet werden können und sollen.

Das heißt, das DRY-Prinzip „Konstanten gehören nicht in den Code, sondern in Konfigurationsdateien“ wird ab sofort beachtet.

Wenn man künftig am Layout einen Zeichensatz, eine Farbe, einen Hintergrund oder Ähnliches ändern will, reicht es, die entsprechenden Konstanten anzupassen und schon erzeugt Vite automatisch aktualisiere CSS-Dateien.

Durch den CSS-Import-Befehl ist es möglich, CSS-Dateien zu modularisieren. Der Underscore _ am Beginn des Dateinamens deutet an, dass diese CSS-Datei nur von anderen CSS-Dateien aber nicht von HTML- oder JavaScript-Dateien importiert werden sollte.

src/css/_config.css

:root
{ --background-color:  #C5EFFC;

  --font-family-sans:  Verdana, Helvetica, sans-serif;
  --font-family-serif: "Times New Roman", Times, serif;
  
  --font-size-base:    3vw;
  --font-size-factor:  1.25;  /* cmp. https://type-scale.com/ */
   
  --font-size-h5:      calc(pow(var(--font-size-factor),1)*var(--font-size-base));
  --font-size-h4:      calc(pow(var(--font-size-factor),2)*var(--font-size-base));
  --font-size-h3:      calc(pow(var(--font-size-factor),3)*var(--font-size-base));
  --font-size-h2:      calc(pow(var(--font-size-factor),4)*var(--font-size-base));
  --font-size-h1:      calc(pow(var(--font-size-factor),5)*var(--font-size-base));
  
  --font-size-p:       calc(pow(var(--font-size-factor),0)*var(--font-size-base));
  --font-size-p-large: calc(pow(var(--font-size-factor),2)*var(--font-size-base));
  
  --font-size-small:   calc(pow(var(--font-size-factor),-1)*var(--font-size-base));
}

In dieser CSS-Datei werden folgende modernen CSS-Konstrukte verwendet:

  • Definition von Konstanten (die teilweise per Berechnung ermittelt werden)
  • Mathematische Berechnungen: calc

Konstanten starten in CSS mit zwei Minuszeichen. Sobald eine Konstante definiert wurde, kann sie in allen weiteren CSS-Konstrukten verwendet werden. In CSS stehen einen Operatoren zur Verfügung wie +, -, * und /, um Maße zu berechnen. Es gibt weitere Operatoren zum Vergleichen von Zahlen und Maßen sowie zur Berechnung von Strings und booleschen Werten: https://sass-lang.com/documentation/operators.[1]

Die Datei _config.css kann nun mit Hilfe des CSS-Befehls @import 'config.css'; (ohne Underscore und ohne .css, wegen des zuvor eingeführten Vite-Aliases) in die anderen beiden CSS-Dateien eingefügt werden.

PostCSS

Der Inhalt der Datei _config.css wird defaultmäßig an den Browser ausgeliefert, obwohl sie nur CSS-Konstanten enthält. Beim Einsatz vom SCSS werden Konstanten vom SCSS-Präprozessor auf dem Server während des Build-Prozesses durch ihre Werte ersetzt. In CSS muss dies defaultmäßig der Browser übernehmen. Es gibt allerdings ein PostCSS-Plugin postcss-var-replace, das diese Ersetzungen ebenfalls während des Build-Prozesses vornimmt. Dieses kann man in die Vite-Konfiguration integrieren:

Laden sie das Pluging postcss-var-replace:

npm i -D postcss-var-replace

Anschließend aktivieren Sie es in vite.config.js

import { postcssVarReplace }  from 'postcss-var-replace';

...

export default
{ ...
  css:
  { postcss:
    { plugins: 
      [ postcssVarReplace(),
      ],
    },
  },
  ...
}

Der Import-Befehl hat ab sofort erst dann einen Effekt, wenn in den anderen Dateien auf diese Konstanten zugegriffen wird. Aber er schadet auch nicht, wenn auf keine der dort definierten Konstanten zugegriffen wird. Der Import-Befehl selbst taucht ebenso wenig in den generierten CSS-Dateien auf, wie die Konstantendefinitionen. Der PostCSS-Transpiler ersetzt Konstanten in CSS-Definitionen durch ihren jeweiligen Wert.

Sie können nun beispielsweise in der Datei head.css die Konstante --background-color verwenden. In dem daraus durch den Build-Befehl npm run build erzeugten CSS-Style-Element steht weiterhin der Farbwert #C5EFFC;

src/css/head.css

@import 'config.css';

body
{ background-color: var(--background-color); }
 
.hidden
{ display: none; }

Die Datei body.css ist deutlich umfangreicher. Daher wird der zugehörige CSS-Code ja auch erst dynamisch gemeinsam mit der Datei web/js/main.js geladen.

src/css/body.css

@import 'config.css';

html
{ height:  100%;
  width:   100%;
  display: table;
}

body
{ display:          table-cell;
  text-align:       center;
  vertical-align:   middle;
  font-size:        var(--font-size-base);
  font-family:      var(--font-family-sans);
}

h1
{ padding:   0;
  margin:    0;
  font-size: var(--font-size-h1);
}

p, label
{ font-family: var(--font-family-serif);
  font-size:   var(--font-size-p);
}

label, input
{ width:      10em;
  font-size:  100%;
  display:    inline-block;
  box-sizing: border-box;
  margin:     0.5ex;
}

label
{ text-align: right;
}

#section_form
{ text-align:   center;
  margin-left:  auto;
  margin-right: auto;

  h1
  { margin-bottom: 0.5ex; }
}

#section_hello
{ p
  { font-size: var(--font-size-p-large) !important; }
}

In dieser CSS-Datei werden folgende modernen CSS-Befehle verwendet:

  • Import-Befehl: @import 'config.css';
  • Konstanten: --font-family-sans, --font-size-base etc. (Es sind noch viele weitere konstante Werte in body.css enthalten, für die in _config.css Konstanten definiert werden sollten)
  • Verschachtelte Anweisungen: z. B. h1 innerhalb von #section_form

Die verschachtelten Anweisungen strukturieren den CSS-Code deutlich besser. Es ist nicht mehr notwendig, einen Selektor wie #section_form mehrfach zu verwenden.

Sehen Sie sich den Unterschied an. In der Datei src/css/body.css der Musterlösungen vom dritten Teil des Tutoriums hatte ich Folgendes geschrieben:

#section_form
{ text-align:   center;
  margin-left:  auto;
  margin-right: auto;
}

#section_form > h1
{ margin-bottom: 0.5ex; }

Die modernen CSS-Variante ist deutlich strukturierter und prägnanter.

#section_form
{ text-align:   center;
  margin-left:  auto;
  margin-right: auto;

  h1
  { margin-bottom: 0.5ex; }
}

Insbesondere bei großen CSS-Dateien erweist sich diese kompaktere Schreibweise als vorteilhaft.

Fortsetzung des Tutoriums

Sie sollten nun Teil 1 des Vue-Tutoriums bearbeiten. In diesem Teil des Tutoriums wird die oben erstelle Variante in das Vue-Framework transferiert.

Quellen

  1. Kowarschick (WebProg): Wolfgang Kowarschick; Vorlesung „Web-Programmierung“; Hochschule: Hochschule Augsburg; Adresse: Augsburg; Web-Link; 2024; Quellengüte: 3 (Vorlesung)