Mit CSS ist es möglich, Benutzer daran zu hindern, Text innerhalb eines Elements auszuwählen, indem user-select: none verwendet wird. Nun, es ist verständlich, warum dies als „kontrovers“ angesehen werden könnte. Ich meine, *sollten* wir Standardverhalten von Benutzern deaktivieren? Im Allgemeinen nein, sollten wir das nicht tun. Aber hat das Deaktivieren der Textauswahl einige legitime (wenn auch seltene) Anwendungsfälle? Ich denke schon.
In diesem Artikel werden wir diese Anwendungsfälle untersuchen und uns ansehen, wie wir user-select: none verwenden können, um die Benutzererfahrung zu verbessern (nicht zu behindern). Es ist auch erwähnenswert, dass die user-select-Eigenschaft neben none auch andere Werte hat, die das Verhalten der Textauswahl ändern anstatt es vollständig zu deaktivieren, und einen weiteren Wert, der die Textauswahl sogar erzwingt, daher werden wir uns auch diese ansehen.
Mögliche user-select-Werte
Beginnen wir mit der Durchsicht der verschiedenen user-select-Werte und ihrer Funktionen.
Die Anwendung von user-select: none; auf ein Element bedeutet, dass sein Textinhalt und verschachtelter Textinhalt funktionell nicht auswählbar oder visuell nicht auswählbar sind (d. h. ::selection funktioniert nicht). Wenn Sie eine Auswahl treffen würden, die nicht auswählbare Inhalte enthält, würden die nicht auswählbaren Inhalte von der Auswahl ausgeschlossen, daher ist sie recht gut implementiert. Und die Unterstützung ist großartig.
Diese Browser-Support-Daten stammen von Caniuse, wo es mehr Details gibt. Eine Zahl zeigt an, dass der Browser das Feature ab dieser Version unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 4* | 2* | 10* | 12* | 3.1* |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 127 | 127 | 2.1* | 3.2* |
Umgekehrt macht user-select: text den Inhalt auswählbar. Sie würden diesen Wert verwenden, um user-select: none zu überschreiben.
user-select: contain ist interessant. Die Anwendung bedeutet, dass, wenn eine Auswahl innerhalb des Elements beginnt, sie auch dort enden muss und es somit enthält. Dies gilt seltsamerweise nicht, wenn die Auswahl *vor* dem Element beginnt, was wahrscheinlich der Grund ist, warum kein Browser es derzeit unterstützt. (Internet Explorer und frühere Versionen von Microsoft Edge unterstützten es zuvor unter dem Namen user-select: element.)
Mit user-select: all führt die Auswahl eines Teils des Inhalts des Elements automatisch dazu, dass der gesamte Inhalt ausgewählt wird. Es ist alles oder nichts, was sehr kompromisslos, aber in Situationen nützlich ist, in denen Benutzer Inhalte wahrscheinlich in ihre Zwischenablage kopieren (z. B. Freigabe- und Einbettungslinks, Code-Schnipsel usw.). Anstatt doppelt zu klicken, müssen Benutzer nur einmal klicken, damit der Inhalt automatisch ausgewählt wird.
Seien Sie jedoch vorsichtig, da dies nicht immer das Feature ist, das Sie denken. Was ist, wenn Benutzer nur *einen Teil* des Inhalts auswählen möchten (z. B. nur den Schriftteil eines Google Fonts-Snippets oder einen Teil eines Code-Snippets)? In vielen Szenarien ist es immer noch besser, „in die Zwischenablage kopieren“ mit JavaScript zu handhaben.
Eine bessere Anwendung von user-select: all besteht darin, sicherzustellen, dass Zitate vollständig und genau kopiert werden.
Das Verhalten von user-select: auto (der ursprüngliche Wert von user-select) hängt vom Element und seiner Verwendung ab. Mehr dazu erfahren Sie in unserem Almanach.
Wenden wir uns nun der Untersuchung von Anwendungsfällen für user-select: none zu…
Entfernen von Nicht-Text-Elementen aus der Auswahl
Wenn Sie Inhalte von einer Webseite kopieren, dann wahrscheinlich von einem Artikel oder einer anderen Art von langformigem Inhalt, richtig? Sie möchten wahrscheinlich nicht, dass Ihre Auswahl Bilder, Emojis (die manchmal als Text kopiert werden können, z. B. „:thinkingface:“) und andere Dinge enthält, die Sie möglicherweise in einem <aside>-Element finden (z. B. In-Artikel-Aufrufe zum Handeln, Anzeigen oder etwas anderes, das nicht Teil des Hauptinhalts ist).
Um zu verhindern, dass etwas in Auswahlen enthalten ist, stellen Sie sicher, dass es in einem HTML-Element umschlossen ist, und wenden Sie dann user-select: none darauf an.
<p>lorem <span style="user-select: none">🤔</span> ipsum</p>
<aside style="user-select: none">
<h1>Heading</h1>
<p>Paragraph</p>
<a>Call to action</a>
</aside>
In solchen Szenarien deaktivieren wir nicht die Auswahl, sondern *optimieren* sie. Es ist auch erwähnenswert, dass Auswahl nicht unbedingt Kopieren bedeutet – viele Leser (mich eingeschlossen) wählen gerne Inhalte aus, während sie sie lesen, damit sie sich erinnern können, wo sie sind (wie ein Lesezeichen), ein weiterer Grund, stattdessen zu optimieren, anstatt vollständig zu deaktivieren.
Verhindern versehentlicher Auswahl
Wenden Sie user-select: none auf Links an, die wie Buttons aussehen (z. B. <a href="/whatever" class="button">Click Me!</a>).
Es ist nicht möglich, den Textinhalt eines <button> oder <input type="submit"> auszuwählen, denn warum sollte man das auch? Dieses Verhalten gilt jedoch nicht für Links, da sie traditionell Teil eines Absatzes sind, der auswählbar sein sollte.
Einverstanden.
Man könnte argumentieren, dass Links, die wie Buttons aussehen, ein Anti-Pattern sind, aber egal. Es macht das Internet nicht kaputt, oder? Dieses Schiff ist sowieso abgefahren, also wenn Sie Links verwenden, die wie Buttons gestaltet sind, sollten sie das Verhalten von Buttons nachahmen, nicht nur aus Konsistenzgründen, sondern um zu verhindern, dass Benutzer versehentlich den Inhalt auswählen, anstatt die Interaktion auszulösen.
Ich neige sicherlich dazu, Dinge versehentlich auszuwählen, da ich meinen Laptop im Bett mehr benutze, als ich zugeben möchte. Außerdem gibt es mehrere medizinische Zustände, die Kontrolle und Koordination beeinträchtigen können, wodurch ein beabsichtigter Klick zu einem unbeabsichtigten Ziehen/Auswählen wird, so dass es auch Zugänglichkeitsbedenken gibt, die mit user-select angegangen werden können.
Interaktionen, die Ziehen (absichtlich) erfordern, existieren natürlich auch (z. B. in Browser-Spielen), aber diese sind selten. Dennoch zeigt dies nur, dass user-select tatsächlich einige Anwendungsfälle hat.
Vermeidung von Diebstahl von Paywall-Inhalten
Paywall-Inhalte erhalten viel Hass, aber wenn Sie der Meinung sind, dass Sie Ihre Inhalte schützen müssen, dann sind es Ihre Inhalte – niemand hat das Recht, sie zu stehlen, nur weil er nicht glaubt, dass er dafür bezahlen sollte.
Wenn Sie diesen Weg gehen möchten, gibt es viele Möglichkeiten, es Benutzern zu erschweren, Paywalls zu umgehen (oder ähnlich, urheberrechtlich geschützte Inhalte wie die veröffentlichten Werke anderer zu kopieren).
Inhalte mit CSS verwischen
article { filter: blur(<radius>); }
Deaktivieren der Tastenkombinationen für DevTools
document.addEventListener("keydown", function (e) {
if (e.keyCode == 123) e.preventDefault();
else if ((e.ctrlKey || e.metaKey) && e.altKey && e.keyCode == 73) e.preventDefault();
else if ((e.ctrlKey || e.metaKey) && e.altKey && e.keyCode == 74) e.preventDefault();
else if ((e.ctrlKey || e.metaKey) && e.altKey && e.keyCode == 85) e.preventDefault();
});
Deaktivieren des Zugriffs auf DevTools über das Kontextmenü durch Deaktivieren des Kontextmenüs selbst
document.addEventListener("contextmenu", e => e.preventDefault())
Und natürlich, um zu verhindern, dass Benutzer Inhalte kopieren, wenn sie sie nicht lesen dürfen, wenden Sie user-select: none an.
<article style="user-select: none">
Gibt es andere Anwendungsfälle?
Das sind die drei Anwendungsfälle, die mir für die Verhinderung der Textauswahl einfielen. Mehrere andere kamen mir in den Sinn, aber sie schienen alle ein wenig weit hergeholt. Aber was ist mit Ihnen? Mussten Sie die Textauswahl bei etwas deaktivieren? Ich würde es gerne wissen!
Der Teil über die Blockierung von Benutzern am „Diebstahl“ von Paywall-Inhalten trifft nicht wirklich zu. Ein Benutzer kann immer noch die DevTools öffnen und den Text durch Auswahl der Elemente kopieren; selbst wenn man Klassen und Divs randomisiert und automatisch generiert, um den Inhalt zu verschlüsseln, kann dies immer noch mit einem OCR-Programm überschrieben werden.
Ja, natürlich, aber das setzt nur voraus, dass der Benutzer überhaupt weiß, was DevTools ist (die meisten nicht).
Kumpel, wenn du Paywall-Inhalte über das Netz sendest, wird ein bisschen Anti-User-CSS sie nicht schützen. Du musst sie gar nicht senden, denn die von dir aufgeführten Gegenmaßnahmen sind ziemlich nutzlos.
Selbst wenn ich die DevTools nicht über das Menü des Browsers öffnen kann (was ich kann), gibt es curl. Wenn es *so* wichtig ist, deine Inhalte geheim zu halten, musst du sie tatsächlich geheim halten, sie nicht im Quellcode einer öffentlichen URL verfügbar machen.
Außer, dass der durchschnittliche Besucher keine Ahnung hat, was DevTools/curl/usw. ist.
lmao. Der durchschnittliche Besucher wird deine Inhalte sowieso nicht stehlen.
Leute, die deine Inhalte stehlen wollen, wissen, wie sie rankommen. Wenn du das nicht willst, mach sie nicht unter einer öffentlichen URL verfügbar.
Außerdem scheitern all deine kleinen Tricks, sobald ich in den Lesemodus wechsle und all dein schickes CSS und JavaScript entferne – buchstäblich per Knopfdruck.
Betreff: Vermeidung von Diebstahl von Paywall-Inhalten
Strg-L Strg-A Strg-C – Ich habe die URL
Strg-W Strg-T – Ich habe einen neuen Tab, leer
Strg-Shift-I – Ich habe DevTools geöffnet
Strg-L Strg-V Enter – Ich habe Ihre kostbare Seite mit geöffneten DevTools geöffnet.
Der Versuch, Leute daran zu hindern, Inhalte zu erhalten, die sie buchstäblich bereits sehen, ist zum Scheitern verurteilt. Es gibt zu viele Möglichkeiten, an die Inhalte zu gelangen. Dies ist also kein gültiger Anwendungsfall.
Danke für die Erinnerung bezüglich der Tastenkombinationen (ich hatte cmd-l vergessen).
Es ist jedoch ein gültiger Anwendungsfall für die Mehrheit, die nicht so technisch versiert ist wie wir.
Leider habe ich Websites gesehen, die DevTools erkennen und das Laden von Inhalten überhaupt verhindern, wenn DevTools geöffnet sind. :(
Ich wünschte, es gäbe eine Art „unsichtbaren Modus“ für DevTools, der sie unerkennbar macht. Wahrscheinlich würden nicht alle Funktionen funktionieren, aber es wäre trotzdem sehr nützlich.
Deaktivierung für ziehbare Elemente kann angemessen sein.
Ja! Spiele zum Beispiel. Persönlich bin ich ansonsten kein großer Fan von komplexen Interaktionen.
Ich sehe das ganz anders. Ich möchte das Benutzererlebnis steuern und unerwünschte Hervorhebungen auf Elementen, wenn Benutzer die Website aus irgendeinem Grund verwenden, sind nicht erwünscht. Daher erhöhe ich user-select:none; für den Body und füge es dann wieder für Elemente wie Seiteninhalte hinzu, die Benutzer möglicherweise kopieren möchten. Ich möchte nicht, dass sie die Überschrift der Seitenleiste kopieren. Ich möchte keine Hervorhebungsfelder auf zufälligen Elementen, weil ein Benutzer ein wenig gezogen hat. Das Entfernen der Benutzerauswahl war eine meiner Lieblingsentdeckungen und ich betrachte die Verwaltung dieses Verhaltens als Teil dessen, was ich gut mache.
Ich denke, ich stimme diesem Ansatz zu, mache mir aber Sorgen, dass ich vergessen würde, die Auswahl für Elemente zu aktivieren, die sie benötigen. Ich frage mich, ob die Art und Weise, wie Browser die Auswahl handhaben, falsch ist und dieses Verhalten Standard sein sollte.
Behauptung: Deaktivieren von Unschärfefiltern und JS-Ereignishandlern, um Inhalte auf meinem Computer anzuzeigen, wie es der Herausgeber nicht möchte => Diebstahl.
Gegenbehauptung: Platzieren von unlesbaren Inhalten auf meinem Computer ohne meine Erlaubnis oder Zustimmung => Hausfriedensbruch.
Ich hatte tatsächlich einmal einen guten Grund dafür.
Ich arbeitete an einer Zeichen-App und als ich mit einem iPad zu zeichnen versuchte, wurde der Zeichenbereich einfach als etwas zum Kopieren ausgewählt.
Die Verwendung von user-select none hat das behoben.
Das einzige Mal, dass ich
user-select: none;verwende, ist, um die Benutzererfahrung zu *verbessern*.Ein Codebeispiel könnte die Zeilennummern als nicht auswählbar haben, damit der Code direkt kopiert werden kann, ohne dass Zeilennummern entfernt werden müssen.
Ein Kommandozeilenbeispiel könnte den Prompt-String als nicht auswählbar haben, was es einfacher macht, die Befehle zu kopieren, die der Benutzer ausführen möchte.
Ein Stück Inhalt, das aus Gründen des visuellen Effekts dupliziert wurde, könnte eine Kopie als nicht auswählbar markiert haben, damit das Kopieren keine Duplikate enthält.
Man könnte die Vorteile von nicht auswählbaren
<aside>-Elementen diskutieren, da sie die Auswahl des Haupttextes stören könnten, aber oft ist der Inhalt eines<aside>gerade dort, weil er wertvolles Material enthält, das ein Benutzer möglicherweise kopieren möchte. Daher rate ich dringend davon ab.Aber eine kleine Geschwindigkeitsbegrenzung einzubauen, um Benutzer vom Kopieren von Inhalten abzuhalten? Und Tastaturinteraktionen durcheinanderzubringen? Bitte sei nicht so benutzerfeindlich.
Ich bin neugierig, was du als feindselig betrachtest? DRM? CCTV? Passwörter? Das sind nur notwendige Vorsichtsmaßnahmen zum Schutz von Eigentum.
Aber bei allem anderen stimme ich dir total zu, du hast einige großartige Beispiele dafür geliefert, wann man es verwenden sollte und wann man es bei
<aside>vielleicht nicht verwenden möchte.Im März habe ich ein Bookmarklet erstellt, um die Deaktivierung der Textauswahl durch Websites zu überschreiben (jemand auf Twitter schlug vor, wie man verhindert, dass Benutzer Text kopieren können, und einfach nein).
https://adrianroselli.com/2022/03/youre-unselectable.html
Da WCAG 2.2 kurz vor der Fertigstellung steht, identifizieren sowohl Erfolgskriterium 3.3.7: Zugängliche Authentifizierung als auch Erfolgskriterium 3.3.9: Redundanter Eintrag die Fähigkeit des Benutzers, Text auszuwählen und zu kopieren, als Methode zur Erfüllung dieser Kriterien. Die Deaktivierung der Fähigkeit zur Textauswahl kann zusätzlich zur Nutzerfeindlichkeit auch WCAG-Fehler in einigen Kontexten verursachen.
Was ist, wenn der Text unscharf ist, eindeutig nicht zugänglich sein soll (weil er nicht kostenlos ist oder was auch immer), Links nicht fokussierbar sind usw.? Sollte er trotzdem als Text gelten? Sollte er als *irgendetwas* gelten?
Ich verstehe das Feindseligkeitsding einfach nicht. Wenn jemand versucht, durch Hacking zu umgehen, nicht für etwas zu bezahlen, womit sollte er dann rechnen, wenn nicht mit Feindseligkeit?
Daniel, wenn der Text nicht zugänglich sein soll, dann hindert das Unschärfen ihn nicht daran, zugänglich zu sein. Dev Tools oder Quelltextansicht werden das ziemlich schnell umgehen. Screenreader würden ihn immer noch ohne den geringsten Hinweis darauf, dass er unscharf ist, erreichen und immer noch diese nicht fokussierbaren Links finden (abgesehen von einigen ARIA-Tricksereien).
Wenn er über das Netz gesendet wird, dann ist er für den Benutzer bestimmt. Wenn eine Website möchte, dass der Benutzer für diese Inhalte bezahlt, dann senden Sie diese Inhalte nicht an seinen Computer. Verschwenden Sie nicht die Bandbreite und CPU-Zyklen des Benutzers, nur um ihm vorzuwerfen, er würde „hacken“, was Sie ihm bereits gesendet haben.
Ich baue viele SPAs und ein Teil meines minimalen Boilerplates ist body {user-select: none;} d.h. Textauswahl standardmäßig deaktiviert.
Dann füge ich sie wieder hinzu, wenn ich speziell möchte, dass der Benutzer Inhalte auswählen kann… was ich nicht allzu häufig finde.
Dieser Paywall-Schnipsel ist großartig! Es ist eine Fünf-Minuten-Lösung, die für 99% der Anwendungsfälle funktioniert. Danke.
Ja, ich würde sagen, etwa 99% der Anwendungsfälle sind korrekt. Entwickler können Paywalls leicht umgehen, aber sie sind eine kleine Minderheit.
Ich finde, ich verwende oft user-select: none, wenn ich eine App mit Electron entwickle, um das Verhalten einer nativen Anwendung zu erzielen, anstatt des üblichen Internetverhaltens, bei dem alles auf dem Bildschirm ausgewählt werden kann.
Zum Beispiel für Text, der Teil der eigenen Benutzeroberfläche der Anwendung ist (wie eine Toolbar oder ein Seitenmenü), denke ich, es ist in Ordnung, den Text nicht auswählbar zu machen.
Aber für andere Bereiche wie den Nachrichtenfeed einer Chat-Anwendung zum Beispiel würde ich meinen Benutzern erlauben, den Text auszuwählen.
Macht perfekt Sinn! :)
user-select: noneist keine Kopierschutzmaßnahme, bei weitem nicht.Das Einzige, was es tun kann, ist, Ihre potenziellen Kunden zu ärgern, indem es völlig legitime Browserfunktionen deaktiviert.
Eine Paywall sollte serverseitig implementiert werden und Sie sollten die Paywall-Inhalte nicht an alle über das Netz senden. Wenn Sie in einem Team arbeiten, sollten Sie dies mit den Backend-Leuten besprechen. Wenn Sie versuchen, die Inhalte auf Ihrer eigenen Website zu schützen und den Server nicht selbst ändern können, ziehen Sie in Erwägung, jemanden zu beauftragen, der dies kann, oder verwenden Sie Patreon oder ähnliche Seiten, um Ihre bezahlten Inhalte zu hosten.
Wenn Sie per Design eine unscharfe Vorschau der Paywall-Inhalte bereitstellen möchten, gibt es Möglichkeiten, dies zu tun, ohne die tatsächlichen Inhalte an alle zu senden. (Rendern Sie ein unscharfes Bild serverseitig/senden Sie bedeutungslose Texte anstelle der tatsächlichen Inhalte/usw. Jetzt können Sie
user-select: nonedarauf anwenden, da das Auswählen und Kopieren sowieso keinen Sinn ergeben wird).Auf jeden Fall sollten Sie „Kopierschutz“ nicht nur im Frontend implementieren, das funktioniert nicht. Es gibt einen Grund, warum große Unternehmen Milliarden von Dollar für eine komplexe Technologie wie Widevine ausgeben (die immer noch einen Server benötigt). CSS und JS können nicht verwendet werden, um DRM in einem Browser zu implementieren.
Das Kontextmenü enthält viele weitere Funktionen als nur „Kopieren“. Es aus irgendeinem Grund zu deaktivieren, außer es durch ein eigenes Kontextmenü mit für Ihre App relevanten Funktionen zu ersetzen, ist benutzerfeindlich.
Die Verwendung von
user-select: noneallein ist meistens eine schlechte Idee und führt zu kaputten Websites und Apps.Es wird kurz erwähnt, dass „Auswählen nicht unbedingt Kopieren bedeutet“, aber Sie haben keine Ahnung. Spontan fällt mir ein, dass die Verhinderung der Textauswahl es schwieriger macht, ein Wort in einem Wörterbuch nachzuschlagen oder es zu suchen (weil Sie das Wort oder die Phrase selbst neu eingeben müssten).
Ich schon, und wenn ich Dinge kopiere (in eine private Notiz-App), möchte ich sie normalerweise so wörtlich wie möglich. Bilder, Emojis usw. sind alles Teile des Inhalts. Ich überlasse es der empfangenden App zu entscheiden, was sie unterstützt.
Und Dinge wie „Links als Buttons sind ein Anti-Pattern oder was auch immer, also machen wir sie noch schwieriger zu benutzen“ sind, gelinde gesagt, schockierend.