mirror of
https://github.com/TheTaz25/denis.ergin.git
synced 2025-07-06 21:58:48 +00:00
feat(slides): add slides for advanced css selectors
This commit is contained in:
parent
b65ca0cc4c
commit
48333ff207
8 changed files with 1086 additions and 0 deletions
128
src/components/slides/css-selectors-advanced/advanced.astro
Normal file
128
src/components/slides/css-selectors-advanced/advanced.astro
Normal file
|
@ -0,0 +1,128 @@
|
|||
<section>
|
||||
<section>
|
||||
<h2>Erweiterte Selektoren</h2>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Soweit haben wir "einfache" Selektoren gesehen, die verwendet werden um Elemente anhand des Element-Types (z.B. <code>span, p, div</code>), oder dessen Attribute auszuwählen.</p>
|
||||
<p>Dies ist aber nicht immer ausreichend, um alle Fälle in der Alltagsarbeit abzudecken.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Child Selektierung</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>In der HTML Dokumentenstruktur kann es häufig vorkommen, dass Elemente innereinander verschachtelt sind und Kindes-Elemente öfters den gleichen Klassennamen erhalten.</p>
|
||||
<p>Mit einer einfachen Selektierung der Klasse kann es deshalb dazu kommen, das Elemente gestyled werden, die man eigentlich "nicht anfassen will".</p>
|
||||
<p>Hierfür gibt es die Möglichkeit, Eltern-Elemente mit einer bestimmten Klassen zu definieren und Kinder mit bestimmten Klassen darin modifizieren/selektieren.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
// Style das Element mit der Klasse "inner"
|
||||
// das sich innerhalb eines Elementes mit
|
||||
// der Klasse "zwei befindet"
|
||||
.eins .inner {
|
||||
background-color: #bfc; // Hellgrün
|
||||
}
|
||||
|
||||
.zwei .inner {
|
||||
background-color: #9ff; // Hellrot
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles child-selector">
|
||||
<div class="eins">
|
||||
<div class="inner">.eins .inner (erscheint Hellgrün)</div>
|
||||
</div>
|
||||
|
||||
<div class="zwei">
|
||||
<div class="inner">.zwei .inner (erscheint Hellrot)</div>
|
||||
</div>
|
||||
|
||||
<div class="inner">
|
||||
.inner (hat keine Hintergrundfarbe)
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Die Reihenfolge ist hierbei wichtig, eine beliebige Tiefe mit mehreren Kindes-Kindern ist auch möglich.</p>
|
||||
<p>Es macht keinen Unterschied, ob das Kind-Element direktes Kind, oder verschachteltes Kind ist:</p>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles child-selector">
|
||||
<div class="eins">
|
||||
<div class="level-1">
|
||||
<div class="level-2">
|
||||
<div class="inner">
|
||||
.eins .level-1 .level-2 .inner (erscheint Hellgrün)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Wenn eine strengere Bindung notwendig ist, kann man dies mithilfe des "Child Combinator" Selektors tun.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Child Combinator</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Der Child-Kombinator restriktiert die Selektion in dem Maß, dass ein Element ein direktes Child-Element zu einem Parent sein muss</p>
|
||||
<p>Reduziert nochmals die Problematik, dass es zu ungewollten Selektionen von Elementen kommt</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
.parent > .child {
|
||||
background-color: #f99;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles child-combinator">
|
||||
<div class="parent">
|
||||
<div class="child">
|
||||
.parent > .child (roter Hintergrund)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="parent">
|
||||
<div>
|
||||
<div class="child">
|
||||
.parent > div > .child
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Sibling-Selektor</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Mithilfe des Sibling-Selektors, lassen sich Elemente, die direkt nach einem anderen Element im Dokument erscheinen, selektieren.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
.first + .second {
|
||||
background-color: #f99;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles sibling">
|
||||
<div class="first">
|
||||
div.first
|
||||
</div>
|
||||
<div class="second">
|
||||
div.second
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
228
src/components/slides/css-selectors-advanced/index.astro
Normal file
228
src/components/slides/css-selectors-advanced/index.astro
Normal file
|
@ -0,0 +1,228 @@
|
|||
---
|
||||
import Title from "./title.astro";
|
||||
import Introduction from './introduction.astro';
|
||||
import Pseudo from './pseudo.astro';
|
||||
import Advanced from "./advanced.astro";
|
||||
import MediaQueries from './media-queries.astro';
|
||||
---
|
||||
|
||||
<div class="slides">
|
||||
<Title />
|
||||
<Introduction />
|
||||
<Advanced />
|
||||
<Pseudo />
|
||||
<MediaQueries />
|
||||
</div>
|
||||
|
||||
<style is:global lang="scss">
|
||||
.reveal pre code {
|
||||
max-height: unset;
|
||||
}
|
||||
.apply-styles {
|
||||
&.pseudo {
|
||||
.container.first :first-child {
|
||||
border: 4px solid #E58F65;
|
||||
}
|
||||
.container.first :first-letter {
|
||||
color: red;
|
||||
}
|
||||
.container.second:first-line {
|
||||
color: deeppink;
|
||||
}
|
||||
|
||||
.container.third p:first-of-type {
|
||||
font-weight: bold;
|
||||
color: royalblue;
|
||||
}
|
||||
|
||||
.container.fourth .child:nth-child(2) {
|
||||
background-color: #E58F65;
|
||||
}
|
||||
.container.fourth :nth-child(4 of .child) {
|
||||
background-color: #E58F65;
|
||||
}
|
||||
|
||||
.container.fifth {
|
||||
:nth-child(even of .child) {
|
||||
background-color: #E58F65;
|
||||
}
|
||||
:nth-child(odd of .child) {
|
||||
background-color: rgb(126, 154, 240);
|
||||
}
|
||||
}
|
||||
|
||||
.container.sixth {
|
||||
.before-and-after {
|
||||
&::before {
|
||||
content: '>>before<<';
|
||||
background-color: rgb(255, 255, 172);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '>>after<<';
|
||||
background-color: rgb(255, 194, 201);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container.seventh {
|
||||
.arrow-box {
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
background: #88b7d5;
|
||||
border: 4px solid #c2e1f5;
|
||||
}
|
||||
.arrow-box:after, .arrow-box:before {
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: "";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.arrow-box:after {
|
||||
border-color: rgba(136, 183, 213, 0);
|
||||
border-top-color: #88b7d5;
|
||||
border-width: 30px;
|
||||
margin-left: -30px;
|
||||
}
|
||||
.arrow-box:before {
|
||||
border-color: rgba(194, 225, 245, 0);
|
||||
border-top-color: #c2e1f5;
|
||||
border-width: 36px;
|
||||
margin-left: -36px;
|
||||
}
|
||||
}
|
||||
|
||||
.container.eighth {
|
||||
button {
|
||||
padding: 1rem 2rem;
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: white;
|
||||
border: 4px solid black;
|
||||
border-radius: 1rem;
|
||||
font-size: xx-large;
|
||||
cursor: pointer;
|
||||
box-shadow: 24px 24px 0 black;
|
||||
transition:
|
||||
box-shadow 50ms ease-in-out,
|
||||
transform 50ms ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
button:active {
|
||||
box-shadow: 12px 12px 0 black;
|
||||
transform: translateY(4px);
|
||||
}
|
||||
}
|
||||
|
||||
.container.ninth {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.card {
|
||||
border: 4px solid black;
|
||||
max-width: 300px;
|
||||
padding: 2rem;
|
||||
border-radius: 2rem;
|
||||
box-shadow: 6px 6px 10px #0006;
|
||||
transition: box-shadow 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 24px 24px 16px #0006;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.not {
|
||||
p:not(.important) {
|
||||
background-color: #282;
|
||||
color: white;
|
||||
}
|
||||
|
||||
p.important {
|
||||
background-color: #822;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&.not-where {
|
||||
ul,ol {color: darkblue;}
|
||||
ul,ol ul { color: darkred; }
|
||||
ul,ol ol { color: darkred; }
|
||||
ul,ol ul ol { color: darkgreen; }
|
||||
}
|
||||
|
||||
&.where {
|
||||
:where(ol, ul) { color: darkblue; }
|
||||
:where(ol, ul) :where(ol, ul) { color: darkred; }
|
||||
:where(ol, ul) :where(ol, ul) :where(ol, ul) { color: darkgreen; }
|
||||
}
|
||||
|
||||
&.where-specifity {
|
||||
p:where(.test) {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
p {
|
||||
background-color: #002;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-specifity {
|
||||
p:is(.test) {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
p {
|
||||
background-color: #002;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&.child-selector {
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
|
||||
.eins .inner {
|
||||
background-color: #bfc;
|
||||
}
|
||||
|
||||
.zwei .inner {
|
||||
background-color: #f99;
|
||||
}
|
||||
}
|
||||
|
||||
&.child-combinator {
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
|
||||
.parent > .child {
|
||||
background-color: #f99;
|
||||
}
|
||||
}
|
||||
|
||||
&.sibling {
|
||||
font-family: monospace;
|
||||
|
||||
.first + .second {
|
||||
background-color: #f99;
|
||||
}
|
||||
}
|
||||
|
||||
&.mq-first {
|
||||
@media (width <= 900px) {
|
||||
div.small-styled {
|
||||
background-color: #f99;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,8 @@
|
|||
<section>
|
||||
<p>
|
||||
Die bisher vorgestellten CSS-Selektoren, waren nur ein paar der Verfügbaren Methoden, um HTML-Elemente zu selektieren.
|
||||
</p>
|
||||
<p>
|
||||
Die folgenden Slides erläutern die weiteren Methoden um komplexere Fälle abzudecken.
|
||||
</p>
|
||||
</section>
|
196
src/components/slides/css-selectors-advanced/media-queries.astro
Normal file
196
src/components/slides/css-selectors-advanced/media-queries.astro
Normal file
|
@ -0,0 +1,196 @@
|
|||
<section>
|
||||
<section>
|
||||
<h2>Media Queries</h2>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Media Queries bilden einen Elementaren Bestandteil moderner Webentwicklung</p>
|
||||
<p>Sie sorgen dafür, dass Elemente auf einer Website für mehrere "Viewports" angepasst werden.</p>
|
||||
<p>Dadurch werden die Webseiten von heute "mobile Friendly". Sie sehen auf jedem Bildschirm gut aus (zumindest so die Theorie)</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Aber was machen Media Queries nun?</p>
|
||||
<p>Am ehesten kann man Media Queries wie eine if-Abfrage für bestimmte Medien-Typen und Features funktionieren.</p>
|
||||
<p><code>Wenn Bildschirm nicht breiter ist als 500px, dann "erwäge" folgende Selektoren und Styles...</code></p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
// Wenn Verfügbare Breite kleiner gleich 900 pixel ist...
|
||||
@media (width <= 900px) {
|
||||
// style div's mit Klasse "small-styled"...
|
||||
div.small-styled {
|
||||
background-color: #f99;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles mq-first">
|
||||
<div class="small-styled">
|
||||
Unter 900px habe ich einen roten Hintergrund!
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Das ganze geht auch für eine Reihe von weitere Features:</p>
|
||||
<ul>
|
||||
<li>hover</li>
|
||||
<li>prefers-color-scheme</li>
|
||||
<li>width & height</li>
|
||||
<li>orientation</li>
|
||||
<li>Type</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Hover</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Dient zur Feststellung, ob das Gerät ein einfaches hovern zulässt.</p>
|
||||
<p>Dies ist Normal der Fall, wenn das Gerät einen Mauszeiger besitzt.</p>
|
||||
<p>Geräte mit Toucheingabe fallen nicht in diese Kategorie.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
@media (hover: hover) {
|
||||
// Geräte, die ein "präzises" hovern zulassen,
|
||||
// werden von Selektoren erfasst.
|
||||
}
|
||||
@media (hover: none) { ... }
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Touch-Geräte haben auch ein Gewisses "Hover"-Feature. Das hovern wird dabei ausgelöst wenn das Element angetippt wird und gleichzeitig der Finger vom Element wegbewegt wird.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>prefers-color-scheme</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Dieses Feature dient als Kommunikations-Schnittstelle zum Betriebssystem.</p>
|
||||
<p>Im Betriebssystem kann heutzutage eingestellt werden, ob ein Light-Theme oder Dark-Theme in den Betriebssystem-Fenstern verwendet werden soll.</p>
|
||||
<p>Mit <code>prefers-color-scheme</code> kann das abgefragt werden und Styles angewandt werden.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
@media (prefers-color-scheme: light) {
|
||||
// Betriebssystem-Standard-Einstellung
|
||||
// Definiere Farben für helle Oberflächen (Light-Theme)
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
// Definiere Farben für dunkle Oberflächen (Dark-Theme)
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>width & height</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Wie vorhin bereits vorgestellt. Es lassen sich Unter- und Obergrenzen für breite und/oder Höhe definieren.</p>
|
||||
<p>Es können auch mehrere Abfragen für verschiedene Display-Breiten (auch Viewports genannt) definieren</p>
|
||||
<p>Mobile, Tablet, Small-Desktop, Large-Desktop sind "gängige" Benamungen</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
@media (width < 600px) {
|
||||
// 599px und kleiner (mobile)
|
||||
}
|
||||
@media (600px =< width < 950px) {
|
||||
// 600px bis 949px (tablet)
|
||||
}
|
||||
@media (950px =< width) {
|
||||
// 950px und breiter (Desktop)
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h4>Mobile First!?</h4>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Eine gängige Taktik um Website-Inhalte zu implementieren, ist es "mobile-first" vorzugehen.</p>
|
||||
<p>Dabei wird in der Implementierung zuerst die kleinste Viewport-Größe beachtet, sodass die Website auch auf kleinsten Geräten funktioniert.</p>
|
||||
<p>Aktuelle Weiterentwicklung im Bereich der Webentwicklung deutet auf "Smallest Size First" hin.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Bei Smalles-Size-First, wird mit neueren Queries (Container-Queries) die Verfügbare Breite eines Elementes (anstatt der gesamte Viewport) abgefragt.</p>
|
||||
<p>Je nachdem wie viel Breite zur Verfügung steht können so Inhalte innerhalb eines Elementes unterschiedlich gestyled werden.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>orientation</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Besonders für Mobile Geräte interessant (wenn auch ein Computer-Bildschrim in Portrait dargestellt werden kann).</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
@media (orientation: portrait) {
|
||||
// Hochkant (z.B. Normal gehaltenes Smartphone)
|
||||
}
|
||||
|
||||
@media (orientation: landscape) {
|
||||
// Querformat (z.B. Computer-Bildschirm; Breiter als Höher)
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Screen-Type</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Die Definition des Screen-Types ist nur noch wichtig, wenn man seine Website als PDF generieren lassen will (bzw. Ausdruckbar machen will)</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
@media screen {
|
||||
// Standard-Mäßige Darstellung von Inhalten
|
||||
// Auf einem PC-Bildschirm
|
||||
}
|
||||
@media print {
|
||||
// Spezielle Stylings für Druck-Inhalte (CMD+P oder CTRL+P)
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
Für ein Praxis-Beispiel, dient diese Webseite. Die Slides können auch als PDF exportiert werden.
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Verknüpfungen mehrerer Media-Queries</h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Manchmal ist es auch notwendig, mehrere Queries miteinander zu verknüpfen, man kann so komplexere Szenarien abbilden.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
@media screen and (width <= 500px) {
|
||||
// Kleine Bildschirme
|
||||
}
|
||||
|
||||
@media (500px <= width), screen and (orientation: portrait) {
|
||||
// Kleine Breiten ODER Bildschirme im Hochkant-Modus
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
</section>
|
33
src/components/slides/css-selectors-advanced/nth-box.astro
Normal file
33
src/components/slides/css-selectors-advanced/nth-box.astro
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
interface Props {
|
||||
amount: number
|
||||
}
|
||||
|
||||
const { amount } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="flex">
|
||||
{ new Array(amount).fill(0).map((_, index) => (
|
||||
<div class="child">
|
||||
{ index + 1 }
|
||||
</div>
|
||||
)) }
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.child {
|
||||
background: lightgray;
|
||||
min-height: 150px;
|
||||
min-width: 150px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
482
src/components/slides/css-selectors-advanced/pseudo.astro
Normal file
482
src/components/slides/css-selectors-advanced/pseudo.astro
Normal file
|
@ -0,0 +1,482 @@
|
|||
---
|
||||
import NthBox from "./nth-box.astro"
|
||||
---
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h2>Pseudo-Klassen</h2>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Pseudo-Klassen werden dazu verwendet, HTML-Elemente mit einem Bestimmten Zustand zu selektieren.</p>
|
||||
<p>Ein paar Beispiele dieser Zustände sind: Erstes Element eines bestimmten Typs, Maus-Hover, und weitere.</p>
|
||||
<p>Pseudo-Selektoren zeichnen sich dadurch aus, dass sie mit einem Doppelpunkt (":hover") gekennzeichnet sind.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p><strong>first-child & first-letter</strong></p>
|
||||
<p><code>first-child</code> selektiert das erste Vorkommende Kind innerhalb eines Element dar.</p>
|
||||
<p><code>first-letter</code> selektiert den ersten Buchstaben innerhalb der Kinder eines Containers.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
// Selektiere das erste Kind-Element innerhalb von .container
|
||||
.container :first-child {
|
||||
border: 4px solid #E58F65;
|
||||
}
|
||||
.container :first-letter {
|
||||
color: red;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<p>Die Besten Programmiersprachen (nicht sortiert?):</p>
|
||||
<ul class="container first">
|
||||
<li>
|
||||
Javascript
|
||||
<ul>
|
||||
<li>TypeScript</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Rust</li>
|
||||
<li>Python</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p><code>:first-line</code></p>
|
||||
<p>Mithilfe von Firstline, kann die erste Zeile (zum Beispiel in einem Paragraphen) gesondert gestyled werden</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
// Selektiere die erste Zeile im "container"
|
||||
.container:first-line {
|
||||
color: deeppink;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<p class="container second">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempora sint, iure magnam, praesentium accusamus, fugit animi laboriosam aut ullam commodi nihil alias! Id provident numquam minus tempora ducimus ad natus.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>
|
||||
<code>:first-of-type</code>
|
||||
</p>
|
||||
<p>Mit diesem Pseudoselektor lässt sich ein bestimmtes Element innerhalb eines Containers selektieren</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
.container.third p:first-of-type {
|
||||
font-weight: bold;
|
||||
color: royalblue;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<div class="container third">
|
||||
<p>Erster Paragraph</p>
|
||||
<p>Zweiter Paragraph</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Nicht nur das erste Element selektieren: <code>nth</code>-Selektoren</p>
|
||||
<p><code>first-child und first-of-type</code> lassen sich auch für Elemente an anderer als erster Stelle definieren:</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<ul>
|
||||
<li>:nth-child()</li>
|
||||
<li>:nth-last-child() (wie child, zählt aber vom Ende)</li>
|
||||
<li>:nth-of-type()</li>
|
||||
<li>:nth-last-of-type() (wie of-type, zählt aber vom Ende)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Es wird aufgefallen sein: <code>:nth-child()</code> sowie die anderen <code>:nth-*()</code> Varianten haben am Ende Runde Klammern, die diesen Selektor so aussehen lassen, als werde eine Funktion (oder ähnlich) aufgerufen.</p>
|
||||
<p>Innerhalb der Klammer wird Angegeben in welchen Abständen die Elemente selektiert werden.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Beispiel-"Grid", jede einzelne Box hat die Klasse "child", der Parent-Container hat die Klasse "flex"</p>
|
||||
<NthBox amount={5} />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
// Selektiere das 2. Element mit der Klasse "child"
|
||||
.child:nth-child(2) {
|
||||
background-color: #E58F65;
|
||||
}
|
||||
|
||||
// Alternative Schreibweise mit "of"-Keyword
|
||||
// (diesmal das 4. Kind)
|
||||
:nth-child(4 of .child) {
|
||||
background-color: #E58F65;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<p>Jetzt sind alle geraden Kind-Elemente "selektiert"</p>
|
||||
<div class="container fourth">
|
||||
<NthBox amount={5} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Aber das geht auch einfacher:</p>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
// Selektiert alle gerad-zahligen Vorkommnisse von "child"
|
||||
:nth-child(even of .child) {
|
||||
background-color: #E58F65
|
||||
}
|
||||
|
||||
// Selektiert alle ungerad-zahligen Vorkommnisse von "child"
|
||||
:nth-child(odd of .child) {
|
||||
background-color: rgb(126, 154, 240);
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<div class="container fifth">
|
||||
<NthBox amount={5} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Nun etwas Mathe</p>
|
||||
<p>der <code>nth</code>-Selektor lässt auch eine Formel zu:</p>
|
||||
<p><code>An+B</code>, dabei ist <code>n</code> "gedanklich" eine natürliche Zahl</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Beispiele:</p>
|
||||
<hr>
|
||||
<p><code>:nth-child(2n)</code> <br>- Selektiert jedes 2. Element (even)</p>
|
||||
<hr>
|
||||
<p><code>:nth-child(2n + 1)</code> <br>- Selektiert jedes 2. Element, beginnend ab dem 1. Element (odd)</p>
|
||||
<hr>
|
||||
<p><code>(n+7)</code> <br>- Selektiert das 7. und alle darauffolgenden Elemente</p>
|
||||
<hr>
|
||||
<p><code>(-n+3)</code> <br>- Selektiert die ersten drei Elemente</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Ein <code>before & after</code></h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Jedes Element hat 2 Pseudo-Elemente die zusätzliches Styling für dieses Element zulassen.</p>
|
||||
<p>Diese Pseudeo Elemente befinden sich "vor" und "nach" dem eigentlichen Element und werden mit <code>::before</code> und <code>::after</code> selektiert und modifiziert.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
.before-and-after::before {
|
||||
content: '>>before<<';
|
||||
background-color: rgb(255, 255, 172);
|
||||
}
|
||||
|
||||
.before-and-after::after {
|
||||
content: '>>after<<';
|
||||
background-color: rgb(255, 194, 201);
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<p>Beispiel</p>
|
||||
<div class="container sixth">
|
||||
<span class="before-and-after">
|
||||
Ich bin nicht alleine...
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Der Text in <code>content</code> wird entsprechend angezeigt, dies ist aber nicht der einzige Use-Case.</p>
|
||||
<p>Tools wie <a href="https://cssarrowplease.com" target="_blank" rel="noopener noreferrer">CSS Arrow Please!</a> nutzen before und after, um z.B. eine "Sprechblase" zu erstellen</p>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<div class="container seventh">
|
||||
<div class="arrow-box">
|
||||
CSS Arrow Please!
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Aktivierter Zustand mit <code>:active</code></h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Es gibt paar Pseudo-Klassen die einen Interaktiven Zustand von bestimmten Elementen stylen</p>
|
||||
<p>Die erste Pseudo-Klasse dieser Art ist <code>:active</code>. Dieser Zustand wird für <code>button</code> und <code>a</code> Elemente verwendet.</p>
|
||||
<p>Der "active" Zustand herrscht typischerweise, solange der Nutzer die (Primäre) Maustaste gedrückt hält.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers="1-14|16-19" is:raw>
|
||||
button {
|
||||
padding: 1rem 2rem;
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: white;
|
||||
border: 4px solid black;
|
||||
border-radius: 1rem;
|
||||
font-size: xx-large;
|
||||
cursor: pointer;
|
||||
box-shadow: 24px 24px 0 black;
|
||||
transition:
|
||||
box-shadow 333ms ease-in-out,
|
||||
transform 333ms ease-in-out;
|
||||
}
|
||||
|
||||
button:active {
|
||||
box-shadow: 12px 12px 0 black;
|
||||
transform: translateY(4px);
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<div class="container eighth">
|
||||
<button>Drück mich!</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Wenn der Mauszeiger über einem Element ist: <code>:hover</code></h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Mit <code>:hover</code> können wir auf den Zustand reagieren, wenn der Nutzer mit dem Mauszeiger über einem Element "schwebt".</p>
|
||||
<p>Mit dieser Pseudo-Klasse lässt sich sehr schnell ein Interaktives Element für den Nutzer identifizieren.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers="1-8|10-12" is:raw>
|
||||
.card {
|
||||
border: 4px solid black;
|
||||
max-width: 300px;
|
||||
padding: 2rem;
|
||||
border-radius: 2rem;
|
||||
box-shadow: 6px 6px 10px #0006;
|
||||
transition: box-shadow 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 24px 24px 16px #0006;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles pseudo">
|
||||
<div class="container ninth">
|
||||
<div class="card">
|
||||
Hallo, ich bin eine "typische" Karte die einen Inhalt anzeigen soll!
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Die Negierung von Selektoren mit <code>:not()</code></h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p><code>:not(...)</code> ist eine Pseudoklassen-Funktion. Innerhalb der Klassen kann ein CSS-Selektor beschrieben werden und die Selektion wird dadurch negiert</p>
|
||||
<p>Nach der Idee "Selektiere alle Elemente die folgendes nicht haben..."</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
p:not(.important) {
|
||||
background-color: #282; // Grün
|
||||
color: white;
|
||||
}
|
||||
|
||||
p.important {
|
||||
background-color: #822; // Rot
|
||||
color: white;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles not">
|
||||
<p class="important">Ich bin <code>.important</code></p>
|
||||
<p class="normal">Ich bin <code>.normal</code></p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3><code>:where() & :is()</code></h3>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Folgendes Szenario</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="html"><code data-trim data-line-numbers>
|
||||
<ol>
|
||||
<li>Level 1 - Item 1</li>
|
||||
<li><ul>
|
||||
<li>Level 2 - Item 1</li>
|
||||
<li>Level 2 - Item 2</li>
|
||||
<li>
|
||||
<ol>
|
||||
<li>Level 3 - Item 1</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<ol>
|
||||
<li>Level 1 - Item 1</li>
|
||||
<li><ul>
|
||||
<li>Level 2 - Item 1</li>
|
||||
<li>Level 2 - Item 2</li>
|
||||
<li>
|
||||
<ol>
|
||||
<li>Level 3 - Item 1</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Wir haben also ineinander verschachtelte Listen (mit unterschiedlichen Listen-Typen)</p>
|
||||
<p>Nehmen wir nun an, dass es auch sein kann, dass wir nicht sicher sein können ob die "Reihenfolge" der Listentypen immer gleich sein wird</p>
|
||||
<p>Wie müssten CSS-Styles aussehen, um alle Fälle abdecken zu können?</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
ul,ol {...} // Level 1 Styles
|
||||
ul,ol ul {...} // Level 2 Styles
|
||||
ul,ol ol {...} // Level 2 Styles
|
||||
ul,ol ul ul {...} // Level 3 Styles
|
||||
ul,ol ul ol {...} // Level 3 Styles
|
||||
ul,ol ol ul {...} // Level 3 Styles
|
||||
ul,ol ol ol {...} // Level 3 Styles
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles not-where">
|
||||
<ol>
|
||||
<li>Level 1 - Item 1</li>
|
||||
<li><ul>
|
||||
<li>Level 2 - Item 1</li>
|
||||
<li>Level 2 - Item 2</li>
|
||||
<li>
|
||||
<ol>
|
||||
<li>Level 3 - Item 1</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
:where(ul, ol) {} // Level 1 Styles
|
||||
:where(ul, ol) :where(ul, ol) {} // Level 2 Styles
|
||||
:where(ul, ol) :where(ul, ol) :where(ul, ol) {} // Level 3 Styles
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles where">
|
||||
<ol>
|
||||
<li>Level 1 - Item 1</li>
|
||||
<li><ul>
|
||||
<li>Level 2 - Item 1</li>
|
||||
<li>Level 2 - Item 2</li>
|
||||
<li>
|
||||
<ol>
|
||||
<li>Level 3 - Item 1</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Welche Schlüsse ziehen wir hieraus?</p>
|
||||
<ol>
|
||||
<li>Lange, komplexe (geschachtelte) Queries benötigen viele "Iterationen"</li>
|
||||
<li>Die Erweiterbarkeit kann darunter leiden</li>
|
||||
<li>Grund für viele Bugs in Bezug auf CSS-Stylings</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p><code>:where & :is</code> verhalten sich nach außen gleich. Wir können eine Komma-separierte Liste an CSS-Selektoren hinein kippen, wenn einer davon "matched" reicht das aus um die Stylings anzuwenden.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Wo sind dann die Unterschieden zwischen <code>where & is</code>?</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
Matches mit <code>where</code>, zählen nicht zur "Spezifität" des selektierten Elementes, <code>is</code> zählt die am besten passende Spezifität.
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="html"><code data-trim data-line-numbers>
|
||||
<p class="test">Hier steht ein Text!</p>
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
p:where(.test) {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
p {
|
||||
background-color: #002;
|
||||
color: white;
|
||||
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles where-specifity">
|
||||
<p class="test">Hier steht ein Text!</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<pre class="css"><code data-trim data-line-numbers is:raw>
|
||||
p:is(.test) {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
p {
|
||||
background-color: #002;
|
||||
color: white;
|
||||
}
|
||||
</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="apply-styles is-specifity">
|
||||
<p class="test">Hier steht ein Text!</p>
|
||||
</section>
|
||||
</section>
|
3
src/components/slides/css-selectors-advanced/title.astro
Normal file
3
src/components/slides/css-selectors-advanced/title.astro
Normal file
|
@ -0,0 +1,3 @@
|
|||
<section>
|
||||
<h1>CSS Selektoren - Erweitert</h1>
|
||||
</section>
|
8
src/pages/slides/css-selectors-advanced.astro
Normal file
8
src/pages/slides/css-selectors-advanced.astro
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
import Reveal from "../../layouts/Reveal.astro";
|
||||
import Slides from '../../components/slides/css-selectors-advanced/index.astro';
|
||||
---
|
||||
|
||||
<Reveal title="CSS Selectors, Teil 2">
|
||||
<Slides />
|
||||
</Reveal>
|
Loading…
Add table
Add a link
Reference in a new issue