Die CSS Working Group des W3C gibt uns oft brillante CSS-Funktionen zum Experimentieren. Manchmal stoßen wir auf etwas so Cooles, dass es uns ein Grinsen ins Gesicht zaubert, aber es verschwindet sofort wieder, weil wir denken: "Das ist großartig, aber was mache ich damit?" Die element() Funktion war für mich so. Es ist eine CSS-Funktion, die ein Element auf der Seite nimmt und es als Bild darstellt, das auf dem Bildschirm angezeigt wird. Beeindruckend, aber exzentrisch.
Unten ist ein einfaches Beispiel, wie es funktioniert. Es wird derzeit nur in Firefox unterstützt, was ich weiß, ist ein Wermutstropfen. Aber bleib bei mir und sieh, wie nützlich es sein kann.
<div id="ele">
<p>Hello World! how're you?<br>I'm not doing that<br>great. Got a cold 😷</p>
</div>
<div id="eleImg"></div>
#eleImg {
background: -moz-element(#ele) no-repeat center / contain; /* vendor prefixed */
}
Die element() Funktion (mit Browser-Präfix) nimmt den id Wert des Elements, das sie in ein Bild übersetzt. Die Ausgabe sieht identisch mit der Darstellung des gegebenen Elements auf dem Bildschirm aus.

Wenn ich an die Ausgabe von element() denke, denke ich an das Wort **Vorschau**. Ich denke, das ist die Art von Anwendungsfall, die das Beste daraus macht: wo wir ein Element vorschauen können, bevor es auf der Seite angezeigt wird. Zum Beispiel die nächste Folie in einer Diashow, der versteckte Tab oder das nächste Foto in einer Galerie. Oder... eine Miniaturkarte!
Eine **Miniaturkarte** ist eine kleine Vorschau eines langen Dokuments oder einer Seite, die normalerweise auf einer Seite des Bildschirms oder auf einer anderen Seite angezeigt wird und zum Navigieren zu einem entsprechenden Punkt in diesem Dokument verwendet wird.
Sie haben sie vielleicht in Code-Editoren wie Sublime Text gesehen.

CSS element() ist nützlich, um den "Vorschau"-Teil der Miniaturkarte zu erstellen.
Unten ist die Demo für die Miniaturkarte, und wir werden den Code danach durchgehen. Ich empfehle Ihnen jedoch, die Vollbild-Demo anzusehen, da Miniaturkarten für *lange* Dokumente auf *großen* Bildschirmen sehr nützlich sind.
Wenn Sie ein Smartphone verwenden, denken Sie daran, dass Miniaturkarten nach der Relativitätstheorie auf Minibildschirmen super klein werden; und nein, das ist nicht wirklich das, was die Relativitätstheorie sagt, aber Sie verstehen meinen Punkt.
Siehe den Pen Minimap mit CSS element() & HTML Input Range von Preethi Sam (@rpsthecoder) auf CodePen.

Wenn Sie die Miniaturkarte für die gesamte Seite entwerfen, z. B. für eine Single-Page-Website, können Sie das Dokumenten-Body-Element für das Bild verwenden. Andernfalls funktioniert auch die Auswahl des Hauptinhalts, wie der Artikel in meiner Demo.
<div id="minimap"></div>
<div id="article"> <!-- content --> </div>
#minimap {
background: rgba(254,213,70,.1) -moz-element(#article) no-repeat center / contain;
position: fixed; right: 10px; top: 10px; /* more style */
}
Als Hintergrundbild der Miniaturkarte übergeben wir die id des Artikels als Parameter von element() und, wie bei den meisten Hintergrundbildern, wird es so gestylt, dass es sich nicht wiederholt (no-repeat), in die Box passt (contain) und in der Mitte der Box (center) angezeigt wird, in der es dargestellt wird.
Die Miniaturkarte ist auch am oberen rechten Rand des Viewports auf dem Bildschirm fixiert.
Sobald der Hintergrund fertig ist, können wir einen Schieberegler darüber legen, der zum Bedienen des Scrollens der Miniaturkarte dient. Für den Schieberegler habe ich input: range gewählt, den ursprünglichen, unkomplizierten und einfachen HTML-Schieberegler.
<div id="minimap">
<input id="minimap-range" type="range" max="100" value="0">
</div>
#minimap-range {
/* Rotating the default horizontal slider to vertical */
transform: translateY(-100%) rotate(90deg);
transform-origin: bottom left;
background-color: transparent; /* more style */
}
#minimap-range::-moz-range-thumb {
background-color: dodgerblue;
cursor: pointer; /* more style */
}
#minimap-range::-moz-range-track{
background-color: transparent;
}
Nicht *ganz* unkompliziert, da er etwas Feintuning brauchte. Ich habe den Schieberegler aufrecht gestellt, um zur Miniaturkarte zu passen, und einige Stile auf seine Pseudo-Elemente (speziell den Thumb und die Spur) angewendet, um ihre Standardstile zu ersetzen. Wiederum konzentrieren wir uns im Moment nur auf Firefox, da wir mit begrenzter Unterstützung arbeiten.
Alles, was noch zu tun ist, ist, den Wert des Schiebereglers mit einem entsprechenden Scrollpunkt auf der Seite zu verknüpfen, wenn der Wert vom Benutzer geändert wird. Das erfordert eine Prise JavaScript, die so aussieht:
onload = () => {
const minimapRange = document.querySelector("#minimap-range");
const minimap = document.querySelector("#minimap");
const article = document.querySelector("#article");
const $ = getComputedStyle.bind();
// Get the minimap range width multiplied by the article height, then divide by the article width, all in pixels.
minimapRange.style.width = minimap.style.height =
parseInt($(minimapRange).width) * parseInt($(article).height) / parseInt($(article).width) + "px";
// When the range changes, scroll to the relative percentage of the article height
minimapRange.onchange = evt =>
scrollTo(0, parseInt($(article).height) * (evt.target.value / 100));
};
Das Dollarzeichen ($) ist lediglich ein Alias für getComputedStyle(), die Methode zum Abrufen der CSS-Werte eines Elements.
Es ist erwähnenswert, dass die Breite der Miniaturkarte bereits im CSS festgelegt ist, sodass wir wirklich nur ihre Höhe berechnen müssen. Wir beschäftigen uns also mit der Höhe der Miniaturkarte und der Breite des Schiebereglers, denn denken Sie daran, der Schieberegler ist tatsächlich nach oben gedreht.
Hier ist, wie die Gleichung im Skript bestimmt wurde, beginnend mit den Variablen:
- x1 = Höhe der Miniaturkarte (sowie die Breite des Schiebereglers darin)
- y1 = Breite der Miniaturkarte
- x2 = Höhe des Artikels
- y2 = Breite des Artikels
x1/y1 = x2/y2
x1 = y1 * x2/y2
height of minimap = width of minimap * height of article / width of article
Und wenn sich der Wert des Schiebereglers ändert (minimapRange.onchange), wird die ScrollTo() Methode aufgerufen, um die Seite zu ihrem entsprechenden Wert im Artikel zu scrollen. 💥
Fallback-Lösungen! Wir brauchen Fallback-Lösungen!
Offensichtlich wird es *viele* Fälle geben, in denen element() nicht unterstützt wird, wenn wir dies im Moment verwenden würden, also möchten wir die Miniaturkarte in diesen Fällen möglicherweise ausblenden.
Wir prüfen auf Funktionsunterstützung in CSS
@supports (background: element(#article)) or (background: -moz-element(#article)){
/* fallback style */
}
... oder in JavaScript
if(!CSS.supports('(background: element(#article)) or (background: -moz-element(#article))')){
/* fallback code */
}
Wenn es Ihnen nichts ausmacht, dass das Hintergrundbild fehlt, können Sie den Schieberegler trotzdem beibehalten und ihm einen anderen Stil geben.
Es gibt andere schicke Möglichkeiten, Miniaturkarten zu erstellen, die im Umlauf sind (und mehr Browser-Unterstützung haben). Hier ist ein toller Pen von Shaw
Siehe den Pen
Mini-map Progress Tracker & Scroll Control von Shaw (@shshaw)
auf CodePen.
Es gibt auch Tools wie pagemap und xivimap, die helfen können. Die element() Funktion ist derzeit in W3Cs CSS Image Values and Replaced Content Module Level 4 spezifiziert. Definitiv lesenswert, um die Absicht und den Gedanken dahinter vollständig zu erfassen.
Diese Browser-Support-Daten stammen von Caniuse, das weitere Details hat. Eine Zahl gibt an, dass der Browser die Funktion ab dieser Version und aufwärts unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| Nein | 4* | Nein | Nein | Nein |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| Nein | 127* | Nein | Nein |
Psst! Haben Sie versucht, den Artikeltext in der Demo auszuwählen? Sehen Sie, was auf der Miniaturkarte passiert. 😉
Eine weitere Sache, für die es wirklich nützlich wäre – verschwommene Overlays.
Was passiert, wenn das Bild innerhalb des erfassten Elements verwendet wird?
Das Universum explodiert.
Erstaunlich! Ich habe von element() gehört, es aber nie implementiert, weil ich keinen guten Anwendungsfall finden konnte. Ich liebe diese Miniaturkarte!
Ich habe den Pen bearbeitet, um ein YouTube-Video in einem iFrame einzubetten. Es funktionierte nicht nur, sondern das Ergebnis war seidig glatt und ohne sichtbare Verzögerung!