Man verwendet es, äh, wenn man einen Button auf seiner Seite haben möchte, den Benutzer anklicken können, richtig? Nun, leider ist es etwas komplizierter als das. Aber nicht zu schlimm, lass es uns herausfinden.
Es sieht so aus
<button>
Do Something
</button>
Was ist das häufigste Ergebnis, wenn man auf etwas auf einer Website klickt? Man gelangt zu einer neuen URL, so wie man es beim Klicken auf einen Link (ein <a href="/example/"></a>) Element tun würde).
Das <button> Element kann das allein nicht. Es gab im Laufe der Jahre verschiedene Gespräche darüber, ob man „href überall“ zulassen sollte, aber nichts ist daraus geworden.
Das Klicken auf einen Button bewirkt jedoch etwas, wenn er in seiner natürlichen Umgebung verwendet wird…
Button ist ein Formularelement
Webformulare haben Submit-Buttons. Man könnte das so sehen:
<form action="/" method="post">
<input type="submit" value="Submit">
</form>
Ein <button> Element in einem <form> verhält sich standardmäßig **identisch** zu dem obigen Submit-Input.
<form action="/" method="post">
<button>Submit</button>
</form>
So schlimm die UX auch sein mag, Formulare können auch Reset-Buttons haben. Man kann dieses Verhalten duplizieren, indem man den Standard-Submit-Typ auf Reset ändert.
<form action="/" method="post">
<button type="reset">Reset</button>
</form>
Das Klicken auf diesen Button löscht alle anderen Eingaben (und Textbereiche) im übergeordneten <form>.
Buttons können Inhalt haben
Der Hauptgrund für die Verwendung eines <button> ist, dass es sowohl ein öffnendes als auch ein schließendes Tag (</button>) hat. Das bedeutet, dass sich *etwas* darin befinden kann. Ein üblicher Anwendungsfall wäre etwas wie
<button>
<img src="tiny_birthday_cake.png" alt="">
Submit
</button>
Während ein Input <input type="image"> sein kann, wäre dieser gemischte Inhalt schwer umzusetzen.
Man kann wahrscheinlich damit durchkommen, beliebigen HTML in einen Button zu packen, aber MDN weist darauf hin, dass der „erlaubte Inhalt“ eines Buttons auf „Phrasing Content“ beschränkt ist. Phrasing Content ist eine begrenzte Teilmenge von HTML-Elementen, die „den Text und die darin enthaltene Auszeichnung definiert. Abfolgen von Phrasing Content bilden Absätze.“
Pseudo-Elemente können ebenfalls verwendet werden.
Lassen wir die Gestaltung von <button>s für einen anderen Tag, aber verschiedene Browser wenden im Allgemeinen einen speziellen Stil auf Buttons an. Man wird entweder diesen Stil beibehalten wollen, damit der Standard durchkommt, oder ihn gründlich entfernen, damit die eigene neue Gestaltung browserübergreifend konsistent ist.
Betrachten wir: „Wenn ein Button keinen sinnvollen href hat, ist es ein <button>“
Ich habe kürzlich gesagt, dass ich dieses Sentiment mochte. Das hat diesen Artikel für mich angestoßen. Damals dachte ich darüber nach, wie sehr ich die Semantik davon mochte. Zum Beispiel:
<a href="#0">
I'm kinda sick of doing this for buttons.
</a>
Da gibt es keinen sinnvollen href. Die 0 ist nur da, damit die Seite nicht springt, weil IDs nicht mit einer Zahl beginnen können.
Wahrscheinlich bedeutet HTML wie oben: *Ich werde das Klicken darauf etwas mit JavaScript bewirken lassen.* Irgendwie fühlt sich das besser an als ein <div>, weil man die Cursor-Änderung und andere Standardstile bekommt.
Wenn man diese bedeutungslosen hrefs nicht mag, kann ein <button> eine gute Alternative sein. Aber leider ist ein <button> außerhalb des Kontexts eines <form> genauso bedeutungslos.
<button>
Outside of a <form>, I'm just as useless.
</button>
Aber <button> fühlt sich trotzdem besser an
Auch wenn ein <button> außerhalb eines Formulars ohne JavaScript nichts bewirkt, fühlt er sich für *Dinge, die man anklicken kann und die etwas anderes tun als Seiten zu wechseln* besser an. Ein leerer Link fühlt sich definitiv nicht richtig an.
Gut. Dann fügen wir es mit JavaScript ein.
Das ist wahrscheinlich die beste Lösung. Wenn JavaScript erforderlich ist, damit das klickbare Element überhaupt etwas tut, könnte es genauso gut gar nicht da sein, es sei denn, JavaScript läuft. Wir können tun
// 1. Create the button
var button = document.createElement("button");
button.innerHTML = "Do Something";
// 2. Append somewhere
var body = document.getElementsByTagName("body")[0];
body.appendChild(button);
// 3. Add event handler
button.addEventListener ("click", function() {
alert("did something");
});
Das Hinzufügen von „Button“ könnte problemlos Teil Ihres JavaScript-Workflows sein.
Wann Links mehr Sinn ergeben
Wenn es irgendeine Art von href gibt, die Sie diesem Link geben können und die Sinn ergibt, dann verwenden Sie auf jeden Fall einen Anker. Auch wenn Sie dieses Verhalten mit JavaScript überschreiben. Das ist progressive Enhancement in seiner besten Form. Zum Beispiel
- Ein Suchbutton löst normalerweise eine Art von Auto-Search-Dingens aus – aber der href könnte einfach auf eine /search/-Seite verweisen.
- Ein Veröffentlichungsbutton löst die nächste Stufe der Veröffentlichung von etwas aus, das ein Benutzer erstellt hat – aber der href könnte einfach auf eine /publish/-Seite verweisen.
- Ein Thumbnail-Button öffnet eine Lightbox mit einer größeren Version – aber der href könnte einfach auf die URL dieser größeren Version verweisen.
Wenn nichts Sinn ergibt, fügen Sie den Button mit JavaScript ein.
Zugänglichkeitsbedenken
Nehmen wir an, die Verwendung eines Anker-Links ergibt Sinn. Nachdem Sie sich selbst ein kleines Schulterklopfen dafür gegeben haben, dass Sie gut in der progressiven Verbesserung sind, muss auch die Zugänglichkeit berücksichtigt werden.
Sie denken vielleicht: Ich hab's!
<a href="#meaningful" class="button" role="button">
I'm good
</a>
Aber Sie sind noch nicht aus dem Gröbsten raus. MDN behandelt es gut
Warnung: Seien Sie vorsichtig, wenn Sie Links mit der Button-Rolle kennzeichnen. Buttons werden erwartet, mit der Leertaste ausgelöst zu werden, während Links erwartet werden, über die Enter-Taste ausgelöst zu werden. Mit anderen Worten, wenn Links dazu verwendet werden, sich wie Buttons zu verhalten, ist das Hinzufügen von role="button" allein nicht ausreichend. Es wird auch notwendig sein, einen Key-Event-Handler hinzuzufügen, der auf die Leertaste reagiert, um mit nativen Buttons konsistent zu sein.
Haben Sie das verstanden? Sie aktivieren Links und Buttons mit unterschiedlichen Tasten, also bedenken Sie das.
Gehen Sie hinaus und äh, machen Sie klickbare Dinge richtig.
Guter Artikel. Auch ich ertappe mich dabei,
<a>-Tags mit toten Links viel zu oft zu verwenden, wenn ich stattdessen leicht eine<button>verwenden könnte, besonders im Hinblick auf die mobile Entwicklung.Abgesehen von der Verwendung von Buttons mit Formularen, wie erwähnt, sehe ich in den meisten Fällen keinen Vorteil, es sei denn, man sucht nach der Standardformatierung, die damit einhergeht (oder mag die Semantik der Verwendung von <button>-Tags für Buttons).
Mir gefällt die Idee hinter „Wenn ein Button keinen sinnvollen href hat, ist es ein <button>“, aber normalerweise verwende ich stattdessen <div> statt <button> in diesen Fällen. Der einzige Nachteil, den ich beim Verwenden von <div> für Buttons bemerkt habe, ist, dass man CSS auf „cursor:pointer“ setzen muss, sonst ist er auf einigen Mobilgeräten wie dem iPhone nicht klickbar. Dennoch ziehe ich es vor, <div> meistens gegenüber button zu verwenden, da ich die Standardformatierung des Buttons nicht zurücksetzen muss.
Greg,
Die Verwendung eines Div ist völlig unzugänglich. Es ist nicht per Tastatur fokussierbar und wird von assistiven Technologien nicht als Button angekündigt. Divs sind bedeutungslos und für viele Benutzer unbrauchbar.
Dann sollten Sie auch role=button und einen gültigen „tabindex“ zu allen Ihren „button div“ hinzufügen, um sie wirklich wie einen Button zu verhalten (z. B. für Tastaturnutzer zugänglich machen, etc…)
Und Sie haben immer noch keinen Zugriff auf CSS-Eigenschaften wie :active…
Lohnt sich das wirklich?
Ich stimme Flunch zu. Die korrekte Nachahmung der Funktionalität eines nativen <button> dauert in der Regel länger, als das Zurücksetzen von Stilen gekostet hätte, und es ist auch wahrscheinlicher, dass sie ohne Ihr Wissen kaputt geht. Ich denke, das gilt für die meisten nativen Elemente, mit denen ein Benutzer auf irgendeine Weise interagieren kann. Wenn Sie nicht bereit sind, alle Barrierefreiheitsimplikationen zu recherchieren und zu testen, ob Ihr Hack browser-, geräte- und assistivtechnologieübergreifend funktioniert, ist es wahrscheinlich besser, das semantische Element zu stylen (auch wenn das auch seine Herausforderungen birgt).
Das ist ein toller Tipp, danke! Alle Fälle, in denen ich ein <div> verwendet habe, um :hover/:active-Zustände hinzuzufügen, waren nie ein Problem, weil ich diese Zustände sowieso stylen wollte (Textfarbe ändern, Box-Shadow hinzufügen etc.). Bei <a>-Tags war das jedoch ein Problem, da ich dann die Unterstreichung, die blaue Farbe, die rote Farbe bei Aktivierung und die violette Farbe bei besuchtem Link entfernen muss. Der :visited-Selektor ist das Einzige, was Links im Gegensatz zu <div> zu bieten haben, und das ist kein Problem, da es dem Benutzer in Situationen, in denen ich diesen Ansatz verwende, keinen Nutzen bringt.
Bei <button> müsste ich auch andere Stile zurücksetzen, plus lustige browserübergreifende Eigenheiten wie diese: http://doctype.com/submit-element-text-moves-over-few-points-active-firefox-only, die eine Freude zum Fehlersuchen sind.
Fügen Sie außerdem **sowohl** die Leertaste als auch die Eingabetaste zum Ausführen der Funktion hinzu.
Und selbst wenn Sie all diese zusätzliche Arbeit leisten, wird die Sprachsteuerungssoftware Nuance Natural Speak den „Button“ nicht erkennen, da sie die Accessibility API nicht liest und sich nicht um ARIA (role=button) kümmert. Sie liest nur das DOM und sucht nach entweder Button- oder a-Elementen.
Bitte verwenden Sie die
<button>!Solange dies ein Problem ist: http://stackoverflow.com/questions/3110564/remove-the-complete-styling-of-an-html-button- ist <button> keine akzeptable Option, es sei denn, Sie sind mit diesem Verhalten einverstanden (ich bin es nicht). Ich werde jedoch in Betracht ziehen, stattdessen <a>-Tags zu verwenden, wenn nötig, wie im Artikel vorgeschlagen. Ich bin damit einverstanden, ‚all die zusätzliche Arbeit‘ zu leisten, wenn es bedeutet, dass ich die Kontrolle darüber habe, wie ein Element browserübergreifend funktioniert. Und auf die Gefahr hin, unsensibel zu klingen (wahrscheinlich zu spät), wie kommt es, dass Nuance Natural Speak die Accessibility API und role=button nicht erkennt, ist die Schuld des Entwicklers? Sollte die Schuld nicht bei ihnen liegen, weil sie ihren kostenpflichtigen Dienst nicht verbessern?
Nur eine Nebenbemerkung zum Kommentar: „IDs dürfen nicht mit einer Zahl beginnen“… Jetzt mit HTML5 können IDs beliebige Nicht-Leerzeichen-Zeichen sein und können mit beliebigem gewünschten Zeichen beginnen.
Das mag für Standards gelten, aber ich bin kürzlich auf Sass-Fehler gestoßen, als ich versuchte, CSS zu kompilieren, das IDs enthielt, die mit Zahlen begannen.
Nur zur Info.
Das stimmt, aber wenn Sie CSS verwenden möchten, um dieses Element nach seiner ID zu gestalten, haben Sie Pech gehabt. Die ID in einem CSS-ID-Selektor kann nicht mit einer Ziffer beginnen.
Was es wert ist, es wäre unklug, Variablennamen oder IDs oder Namen von irgendetwas zu erstellen, das mit Zahlen beginnt, in **irgendeiner** Sprache.
T.J. Crowder schrieb
Glücklicherweise haben Sie das nicht.
Wenn Sie den von Ihnen verlinkten Abschnitt in der Spezifikation sorgfältig lesen, werden Sie feststellen, dass dort beschrieben wird, was in diesen Fällen zu tun ist
Wie immer bei Zeichen, die in einem bestimmten Kontext eine besondere Bedeutung haben, müssen Sie sie escapen, wie MaxArt bereits darauf hingewiesen hat.
Aus praktischen Gründen kann es jedoch eine gute Empfehlung sein, einen Bezeichner mit einem Buchstaben zu beginnen.
Römische Ziffern FTW.
Sehr schöner Artikel, ziemlich clever die Art, wie du den Unterschied zwischen einem Tag und einem Button-Tag erklärst.
Zu den Barrierefreiheitsbedenken von Links und Buttons ist dies ein relevanter und sehr gründlicher Beitrag
http://www.csskarma.com/blog/polybutton/
Dies ist ein guter Artikel mit einem überaus irreführenden Anfang. Buttons existieren in HTML, um entweder ein Formular zu senden oder Skriptfunktionalität auszulösen, was beides nicht die Aufgabe eines Anker-Elements ist. Das bedeutet, einen Button wie einen Link zu verwenden, geschieht wegen seines Aussehens und nicht wegen seiner semantischen Bedeutung.
Betrachten Sie BUTTON als das DIV der Interaktion. Es hat keine vordefinierte Funktionsweise – Sie müssen diese hinzufügen, indem Sie es entweder in einem Formular verwenden oder einen Event-Handler anwenden, damit es ein Skript aufruft. Einen Button für einen href zu verwenden, wäre genauso schlimm, wie einen Link mit einem javascript: href zu verwenden.
Ich habe ihn mehrmals durchgelesen. Es ergibt Sinn für mich. Ich habe das Gefühl, dass ich genau die gleichen Punkte machen will wie Sie. Aber entschuldigen Sie, wenn ich das Internet ruiniere oder so etwas.
Greg: ein DIV ist auch nicht per Tastatur zugänglich – etwas, das Links und Buttons standardmäßig haben.
Ah, gut zu wissen. Ich frage mich, wie viele Anwendungsfälle es gibt, bei denen das ein Problem ist. Ich habe die Tabulatortaste auf meiner Tastatur nicht mehr benutzt, um eine Seite zu navigieren, seit mir meine Computermäuse als Kind weggenommen wurden.
Wie habe ich bisher ohne dieses
href="#0"Ding gelebt?Danke für diesen Artikel! Ich zögere jedes Mal deswegen...
Man kann auch href=”#nogo” verwenden :)
href="#?"ist auch ein Goodie! Ich mag es, weil es wie ein vertrauter Freund in der URL-Leiste ist.Ich bevorzuge den unattraktiven <a href=”javascript:;”></a>-Ansatz
Greg, dann haben Sie Glück, dass Sie keine Behinderung haben, die Sie daran hindert, eine Maus zu benutzen. „Funktioniert für mich“ ist nicht, wie Barrierefreiheit funktioniert.
Greg sollte vielleicht das hier lesen: http://webaim.org/articles/visual/blind
Greg wird den Artikel lesen. Sie können auf den Kommentar antworten, anstatt einen neuen zu erstellen, was verhindern würde, dass ich jedes Mal meinen Namen referenzieren muss. Mir ist bewusst, dass es auch Screenreader gibt, ich hätte mich vielleicht anders ausdrücken können. Ich glaube, es gibt Websites, die existieren und die nicht für alle Parteien zugänglich gemacht werden können, egal wie viele Alt-Tags Sie zu Bildern hinzufügen usw. Für Nachrichtenseiten, Blogs usw., die dem Benutzer genügend Inhalte bieten, damit es für Blinde interessant ist, ja, Barrierefreiheit ist definitiv ein Anliegen. Andere Seiten wie codepen.io, ich bezweifle, dass dies ein Problem wäre, da es höchst unwahrscheinlich ist, dass die Seite für sie in irgendeiner Weise nützlich wäre, dass es sich lohnen würde, sie für Screenreader zugänglich zu machen.
Ein weiterer sehr beunruhigender Hinweis hier ist die Verwendung von Links zur Auslösung von Formularübermittlungen wie ein Speicherbutton. Jede Formularübermittlung mittels GET (was ein Link wie save/ wäre) ist ein massives Sicherheitsproblem, da nichts mich davon abhalten würde, das von der CLI anstelle Ihrer Seite zu tun. Deshalb gibt es Buttons in den meisten CMS.
Hinsichtlich der Formularübermittlung mittels GET, könnte dies zu Problemen mit Browsern führen, die vorhandene Links auf der Seite vorab laden. Soweit ich weiß, wäre dies kein Problem, wenn Sie einen Button verwenden.
Genau, Mike. Ich erinnere mich, als Google die Web Accelerator Toolbar für IE und Firefox hatte (vor langer Zeit), die Links vorab geladen hat. Das Öffnen eines alten WordPress hat Ihre gesamte Datenbank gelöscht, da „Beitrag löschen“ nur ein Link war.
Das ist fair. Es ist im Allgemeinen keine gute Idee, eine Speicheraktion als GET zu behandeln. Ich werde es zu etwas Realistischerem ändern. Aber ich denke, der Punkt bleibt bestehen, es geht um hrefs, die auf etwas verweisen, das das Gleiche tun würde wie die JavaScript-gesteuerte Aktion.
Ein Button hat keinen href und war nie dafür gedacht, einen zu haben. Das ist die Verwirrung hier. Wir haben ständig vermischt, wofür Buttons und wofür Anker sind
Anker: Bieten einen Link zu einem anderen Ort, verweisen auf ein anderes Dokument oder ein Ziel auf der Seite.
Buttons: Senden entweder Formulardaten und definieren, welche Aktion mit den Daten durchgeführt werden soll, sobald sie gesendet werden (d. h. hinzufügen, löschen, aktualisieren, alles im selben Formular) oder sind ein Interaktionselement, das JavaScript benötigt.
Einen href mit vielen GET-Parametern zu haben, ist eine sehr schlechte Idee, da Links indiziert werden. Deshalb sind A-Elemente schreckliche Buttons.
Einen Button einfach zu einer anderen Seite umzuleiten bedeutet entweder, dass Sie die URL in einem Formularfeld definieren müssen, oder dass Sie JavaScript und document.location verwenden müssen.
Sowohl Buttons als auch Anker sind großartig für die Barrierefreiheit, da sie eine Vielzahl von Eingabeformaten unterstützen (Touch, Klick, Tastatur). Buttons sind **dafür gedacht**, das zu verwenden, wenn Sie Skriptfunktionalität auf zugängliche Weise in HTML auslösen möchten – es gibt kein anderes Element, das dafür da ist.
All dies wäre keine Frage, wenn
a) OldIE beim Stylen von Buttons oder der Unterstützung derselben ohne die Doppel-Submit-Eigenheiten nicht absolut beschissen gewesen wäre
b) Anker keine Scheiße wie Inline-Event-Handler oder „javascript:“ Pseudo-Protokolle zulassen würden.
Ich wollte nur hinzufügen, dass Chrome auf IOS die Option hat, Seiten vorab zu laden.
Siehe hier: Bandbreitenmanagement auf Chrome für Mobilgeräte
Großartig. Ich verwende seit langem
<button>in meinen Projekten, um Icons usw. verwenden zu können. Aus meinen eigenen Tests bin ich zu denselben Schlussfolgerungen gekommen, und es hat immer in IE7+ funktioniert, aber ich bin froh, dass es jetzt offiziell ist :).Das ist ein Fall…hihihi :D
Seien Sie nur vorsichtig, wenn Sie im .NET Framework arbeiten. Die meisten Seiten sind alle Formulare und die Verwendung eines Buttons verursacht einen Callback, es sei denn, Sie verhindern dies ausdrücklich in Ihrer Button-Click-Aktion. Das macht mir immer zu schaffen bei der SharePoint-Entwicklung.
Nur wenn Sie ASP.NET WebForms verwenden. MVC und Razor Pages brauchen nicht diese umständliche Web-zerstörende Bastelei von früher…
Hallo Eric, ich denke, der einfachste Weg, das Standardverhalten (ASP.NET-Formular übermitteln) zu überschreiben, ist die Verwendung von
Wenn Sie möchten, dass es für progressive Verbesserung zu „Submit“ zurückfällt, sollten Sie das nicht tun, aber ich mag es für den Button-Typ „etwas mit JS tun“, den Chris beschreibt. Ich finde das etwas einfacher, als immer default zu verhindern.empêcher dans les actions de clic.
Rodney hat es unten als Fix für Buttons außerhalb von Formularen erwähnt, aber es löst auch unser .NET-Problem.
Was ist, wenn ich type=”submit” verwenden möchte, aber auch Buttons in meinem Formularblock habe, die andere Dinge tun… werden diese zusätzlichen Buttons wie Submit-Buttons wirken?
Z.B. ein Formular mit einer dynamischen Anzahl von Eingabezeilen, wie beim Klicken auf einen Button, um eine weitere Browse-Box für den Upload mehrerer Dateien hinzuzufügen.
Wenn Ihre Buttons alle innerhalb eines Formulars liegen, aber einige nicht zum Absenden dienen, verwenden Sie bei diesen
type=button. Dies unterdrückt das Absende-Verhalten.Testen in CSS
content: „Warnung…“;
@Heydon, danke.
Bedeutet das, wir sollen schreiben: <button type=”button” role=”button” … das erscheint seltsam, es ist verdammt nochmal ein Button-Element.
Wenn das der Fall ist, wäre es für mich viel einfacher, einfach ein JS-Skript zu haben, das diese Attribute automatisch zu jedem <button>-Element auf der Seite hinzufügt, es sei denn, es hat speziell type submit. Oder, in die Codierkonvention für das Team aufnehmen.
Ich habe oft ein Formular, das als Teil einer jQuery-Funktion gesendet wird, daher macht ein Button mehr Sinn, um die Standardaktion SUBMIT zu vermeiden. Das Button-Element ist auch ein schöner Auslöser für ein Akkordeon oder andere Javascript-Steuerungen.
Erstens stimme ich voll und ganz dem zu, was Chris H in seinen Kommentaren sagt, und zweitens ist es
role="button", nichtaria-role="button":)Danke, ich habe das korrigiert. Das kann verwirrend sein, da sie allgemein als „ARIA-Rollen“ bezeichnet werden und viele der Attribute mit
aria-beginnen, aber eben nichtrole.Soweit ich weiß, gibt es keine Grenze, welche Art von Inhalt man in einen Button packen kann…
button-Elemente können Phrasing Content enthalten, also gibt es viele Dinge, die man nicht hineinpacken kann. Zum Beispiel beliebiger Flow Content, wieblockquote,div,p,nav,hr, …Okay, der erste Absatz oben wurde als Blockquote formatiert, aber das wird oben nicht angezeigt.
Es *gibt* eine Grenze, die genau dort angegeben ist, wo Sie verlinkt haben: „Es dürfen keine interaktiven Inhaltselemente enthalten sein.“
Hey, Chris, ich weiß, es ist ein bisschen off-topic, aber es gibt eine andere Möglichkeit, einen Selektor für Elemente mit einer ID zu erstellen, die mit einer Zahl beginnt
Dies passt zu allen Elementen mit der ID „123hello“. Zusätzlich zu dem anderen, das Sie im verlinkten Artikel vorgeschlagen haben
Aber es sollte auch von IE6 unterstützt werden… für diejenigen, die immer noch damit zu kämpfen haben! (Ich bete für ihre Seelen.)
Übrigens verwende ich in letzter Zeit immer mehr
<button>s, aber das Problem ist, dass sie von Browsern standardmäßig stark gestylt werden, sodass man nie weiß, welche Stile verwendet werden und zurückgesetzt werden sollen. Bis dieappearance-Stileigenschaft universell übernommen wird. Uff.Eine Sache, die in Diskussionen über Links oder Buttons nicht auftaucht, sind Zustände. Ich mag die Möglichkeit, ein Trigger-Element unter bestimmten Umständen einfach zu deaktivieren. Das mit Links zu tun, erfordert mehr Code, der weniger leicht zu warten ist.
Ein Link sollte verwendet werden, wenn es ein Link ist. Ein Button, wenn es kein Link ist.
Bitte beachten Sie, dass der Standardtyp von
<button>„submit“ ist. Wenn Sie einen<button>verwenden möchten, um etwas anderes als das Absenden / Zurücksetzen eines Formulars auszulösen, geben Sie ihn bitte richtig an:<button type="button">.Internet Explorer (zumindest bis Version 9, habe neuere Versionen nicht geprüft) wird Dinge durcheinanderbringen, wenn er einen Submit-
<button>außerhalb eines<form>antrifft. Er wird versuchen, das vorherige Formular (falls vorhanden) zu übermitteln, wenn der Button geklickt wird. Das kann ärgerlich zum Debuggen sein.Ah, Sie waren schneller…
Referenz
In HTML5 ist die Verwendung eines Elements außerhalb eines Formulars völlig gültig und eine viel bessere Wahl für die Tabulatorreihenfolge, Barrierefreiheit usw. Null-Links sind semantisch irreführend.
Wichtig! Sie müssen unbedingt ein type-Attribut angeben (normalerweise type=”button”), da IE8- annimmt, dass es sich um einen Submit handelt, wenn Sie dies nicht tun…
Ich mag diesen Ansatz
Aber jetzt gibt es Inhalte, die in die JavaScript-Struktur gehören! Wie wäre es mit Übersetzungen? Von CMS bearbeitbare Button-Beschriftungen? Was gilt als bewährte Praxis, um das zu lösen? Strings als JS-Variablen in der Markup-Struktur ausgeben?
Wahrscheinlich JavaScript-Templating, besonders wenn Sie viel davon machen.
Hallo Chris
Sie sagen „IDs können nicht mit einer Zahl beginnen“, aber ich denke, das ist etwas ungenau.
Jeder CSS-Selektor kann nicht mit einer Zahl in den Style-Sheets oder im HTML-Style-Element beginnen, ja.
Aber in das HTML-Attribut (id=” oder class=”) ja.
Ihr Beispiel-HTML-Code ist also in Ordnung und gültig (kein Fehler im Validator)
und dafür haben wir das Escape-Zeichen in CSS:
# {/* nice styles */}Ich glaube
Entschuldigung, ich habe das Escape-Zeichen
#im CSS-Selektor verlorenGibt es einen bestimmten Grund, warum
var body = document.getElementsByTagName("body")[0]gespeichert wird, anstattdocument.bodydirekt aufzurufen?Ich habe kurz darüber nachgedacht und konnte mich dann nicht mehr erinnern, ob es eine Möglichkeit gab, direkt auf das
bodyzuzugreifen, ohne es abzufragen oder nicht. Mein Verständnis des DOM ist NEULING. Ich bin mir sicher, dassdocument.bodybesser ist.In neueren Browsern gibt es auch
document.head. Schade, dass dies von IE8 (oder Firefox 3.x, aber egal) nicht unterstützt wird.document.bodywird stattdessen schon immer unterstützt. Denken Sie nur daran, dass es je nach Bereitschaftszustand des Dokuments möglicherweise noch nicht definiert ist.Hey CHRIS, schöner Artikel!
Ich benutze auch „button“ für Aktionen auf derselben Seite und „a“ für Links.
; )
Auf einer kürzlich erstellten Website hatten wir
<button>-Elemente mit Inhalt darin, der beim Klicken auf den Button angezeigt wurde. Ein sinnvoller Anwendungsfall, da wir wollten, dass die gesamte Inhaltskachel klickbar ist.Es funktionierte überall, wo es getestet wurde, korrekt, aber ein Link, der innerhalb des Buttons verschachtelt war, war nur im Internet Explorer 8 nicht klickbar. IE8 (und wahrscheinlich darunter) registriert keine Klickereignisse auf Elementen innerhalb eines
<button>, und daher werden Links innerhalb eines Buttons nicht unterstützt.Beispielcode
Ich habe versucht, das Ziel des Klicks zu verfolgen, aber IE8 registrierte nur den Klick auf den Button. Ich bin sogar so weit gegangen, die Koordinaten des Klicks zu erfassen und sie mit den Koordinaten der Links innerhalb des Buttons zu vergleichen. Die einfachste Lösung war jedoch,
<button>durch<div>zu ersetzen.Ich hinterlasse das hier nur für den Fall, dass jemand anderes bei diesem Problem festhängt.
Ich finde, es ergibt irgendwie Sinn. Sie haben ein klickbares Element in einem anderen klickbaren Element. Auch wenn Sie vielleicht Ihre Gründe dafür haben, sieht es eher nach einer fehlerhaften Benutzeroberfläche aus.
Und bei Microsoft dachte man, es sei in Ordnung, das Standardverhalten zu verändern. Kann man sich denken.
@Chris
Nehmen wir an, wir haben folgendes Button-Element in einem Formular
<button name="test" value="val1">val2</button>welchen Wert wird die Variable test halten:
val1oderval2?Guter Artikel, Chris. Er hat meine immerwährende Überzeugung bestätigt: „Die Verwendung nativer HTML-Elemente wird ARIA-Rollen vorgezogen“. Wenn Sie also einen Button haben, machen Sie ihn zu einem Button, und platzieren Sie keinen Link mit role="button", das ist sowohl semantisch als auch leistungsmäßig besser.
Was ist mit
<button onclick="ajaxload(this.firstChild.getAttribute('href'))"><a href="/stuff">Go to stuff</a></button>?:D
Danke für die Info, Chris! Ich habe oft dieselbe Diskussion mit mir selbst geführt, aber Sie haben noch mehr Tiefe und Informationen hinzugefügt. Ich kannte die verschiedenen Tastaturauslöser nicht, was ziemlich wichtig ist.
Ich wollte auch etwas teilen, das mir heute aufgefallen ist. In IE 8 (möglicherweise auch in anderen – habe ich nicht ausprobiert) fügt ein Button im
:active-Zustand einige Formatierungen hinzu, um diesen „3D-Druck“-Effekt zu erzielen, indem der Text 1 Pixel nach rechts und unten verschoben und die Hintergrundposition 1 Pixel nach links und oben verschoben wird. Es scheint auch etwas Rand hinzuzufügen. Die einzige Möglichkeit, dies sauber zu umgehen, ist die Verwendung eines<a>anstelle dessen. (Sie könnten einige Stile aufbutton:activeanwenden, um einige davon rückgängig zu machen, aber das funktionierte in meinem Fall nicht, da ich ein:afterhatte, das ebenfalls durcheinander geriet).Da ich die Buttons zum Auslösen von Aktionen auf der Seite verwende, anstatt zur Navigation, wollte ich einen
<button>verwenden, aber da ich wechseln musste, denke ich darüber nach, sie in eine<menu>-Liste für etwas mehr Semantik zu verpacken.Wahre Geschichte
In meinen HTML-Mockups mache ich:
<button class="btn">Search Products</button>.Ich übergebe die HTMLs an die Offshore-Entwickler und jetzt ist der Button:
<input type="submit" value="Search Products" class="btn">¬¬
Alter!
Toller Artikel. Ich frage mich immer noch, was die für viele Entwickler so attraktiv macht ^^
Ich frage mich immer noch, was das
<input type="submit">für viele Entwickler so attraktiv macht ^^ (vergessen, den Inline-Code zu verwenden)Weil sie nicht wussten, dass es ein HTML-Element namens
<button>gibt, und deshalb weiterhin das Einzige verwendeten, das sie kannten (und viele kennen bis heute **nur**),<input type="submit">.Nun, Buttons können mit der Leertaste oder der Enter-Taste ausgelöst werden, richtig?
@Brecht
Die Bevorzugung von
<input type="submit">ist üblich, da<button>in Internet Explorer notorisch fehlerhaft war.Ich erinnere mich nicht an größere Fehler/Probleme mit
<button>in alten IEs.Doch, gab es. Siehe den Abschnitt „Hinweise“ hier: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button
In der Tat, ich sehe es jetzt. Die Webprogrammierer, mit denen ich gearbeitet habe, haben nichts davon erwähnt.
Ich bin mir nicht sicher, ob diese Informationen auf MDN vor 8 Jahren (und länger) dokumentiert waren. Das wäre damals sehr hilfreich gewesen.
Ihr Hinweis zum „Reset“-Button ist etwas irreführend
<
Formular>.
Der Reset-Button ist tatsächlich ein ziemlich mächtiges Werkzeug, wenn er richtig eingesetzt wird – er setzt das Formular in den geladenen Zustand zurück. Wenn ich also ein bestehendes Formular mit vorhandenen Werten bearbeite (denken Sie an die Bearbeitung eines vorhandenen Datenbankeintrags), setzt das Klicken auf „Reset“ die Werte auf die Originale zurück – NICHT leer. Auch hier kann dies, wenn es richtig eingesetzt wird, Benutzern helfen, wenn sie Fehler in einem Formular machen.
Jedes Mal, wenn ich einen Reset-Button neben einem Submit-Button sehe, bete ich zu den Göttern der Benutzererfahrung, Benutzerfreundlichkeit und des Interaktionsdesigns, dass sie die Benutzer erleuchten, damit sie mit ihren Cursorn und dicken Fingern den glorreichen Submit-Button korrekt anvisieren und anklicken.
Um zu verhindern, dass ein Button-Element innerhalb eines Formulars wie ein Button fungiert, können Sie auch Folgendes tun:
<button type="button>action</button>Dadurch wird verhindert, dass versucht wird, Ihr Formular abzuschicken, und es ist viel schneller als das Hinzufügen der jQuery-Methode
preventDefault();.Ein Punkt, der mir im Artikel fehlt, ist, dass es (für mich) mehr Sinn macht, Buttons in Formularen zu verwenden, da sie mir erlauben, einen Wert anzugeben, der sich von dem Text unterscheidet, der auf dem Button angezeigt wird. Man könnte also etwas wie das hier tun
Dies funktioniert, weil nur der Wert des verwendeten Buttons an den Server gesendet wird. Ich bin mir nicht sicher, ob es so verwendet werden sollte, aber es hat sich für mich als sehr nützlich erwiesen. Dies ist nicht nur mit
inputs unmöglich zu tun, sondern erleichtert die Programmierung des Backends erheblich, da Sie den Button-Text neu formulieren können, ohne den an den Server gesendeten Code zu beeinträchtigen. Auch in mehrsprachigen Umgebungen sehr nützlich.Ich habe einen neuen Trick gelernt. Danke!
Gern geschehen!
Toller Artikel, Chris! Was ist, wenn wir unsere Buttons nicht durch Javascript erstellen, sondern sie einfach mit einem „no-js“-Body-Klassen-Ansatz „display:none“ machen? Denkst du, das kann Probleme verursachen?
Chris, ich glaube nicht, dass es eine gute Idee ist, die Inhaltsebene (HTML) und die Verhaltensebene (JS) zu mischen, oder zumindest nicht die beste Lösung, wie Sie es sagen. Außerdem skaliert es nicht gut. Wenn Sie sich um Barrierefreiheit sorgen, sollten Sie sich auch um Leute sorgen, die kein JavaScript aktiviert haben.
Ich denke, während sich das Web weiterentwickelt, müssen nicht alle HTML-Elemente ein vordefiniertes Verhalten haben. Sagen wir, nicht alle Buttons müssen etwas tun, ohne JS zu benötigen, d.h. submit, reset, …
Ich glaube, Sie sind zu dogmatisch, was die Rolle von JavaScript angeht. Wir sprechen hier über einen Button, der keinerlei Funktionalität hat, wenn nicht durch JavaScript. Ihn überhaupt auf der Seite zu haben, ist schlecht für die Barrierefreiheit. Und was das Skalieren angeht, bin ich mir nicht sicher, was Sie damit meinen. Ich kann mir sehr gut eine JavaScript-Datei in meiner App vorstellen, die die Einfügung von Buttons an den Stellen übernimmt, an denen sie benötigt werden, und dabei eine schöne, erweiterbare Vorlage verwendet.
Manchmal kann man als Webprogrammierer wirklich Kopfschmerzen bekommen, und das Button-Tag war lange Zeit eine Plage für viele. Hoffentlich, während sich die Webstandards weiterentwickeln (versuchen Sie, Schritt zu halten, Microsoft), werden die Probleme mit Buttons nicht mehr so weit verbreitet sein, wie sie es waren.
Mit responsivem Design, wie es heute ist, sollten sie ein Aspekt sein, der die Benutzererfahrung mit wenig oder gar keinem Aufwand für den Website-Entwickler verbessert – wir sollten solche Dinge heutzutage nicht mehr hacken und debuggen müssen, oder?
HAFTUNGSAUSSCHLUSS: Ich muss mich nicht um IE8 und älter kümmern.
Ich entwickle für das mobile Web für alle mobilen Geräte [alle Smartphones und Tablets außer Blackberry und Opera Mini]. Aus dem Code, den ich vor über einem Jahr geerbt habe, konvertierten Links, die wie Buttons funktionierten, zu button type=button, reduzierten den Code und viele gerätespezifische Probleme verschwanden, und seitdem läuft es sehr reibungslos.
Ja, das
<button>-Tag funktioniert nicht für ältere IE-Browser, und das von Greg verlinkte Problem bezog sich speziell auf<input type="button">, was NICHT dasselbe ist wie<button type="button">. Sie müssen oft den Typ definieren, wie Chris im Kontext eines Formulars erwähnt:<button>wird standardmäßig zu type=submit, sodass das Drücken von Enter irgendwo im Formular Konsequenzen hat.Alle meine Buttons werden nativ per Klick, Tippen, Leertaste und Enter ausgelöst, sind alle fokussierbar, per Tab erreichbar, ohne tabindex. Ich muss keine Keypress abhören oder Defaults verhindern, wie ich es bei einem Link tun müsste, der als Button gestaltet ist und als Button fungiert.
Ich empfehle es sehr, wenn Sie keine älteren Browser unterstützen müssen, und wenn ich Unterstützung sage, meine ich, dass es genau gleich aussieht. Die meisten Kunden lassen sich jetzt leichter davon überzeugen, dass eine Website auf einem Tablet gut und funktional aussieht, als IE8 und älter gut aussehen zu lassen [wie].
Und ja, Button-Stile müssen wahrscheinlich mit CSS zurückgesetzt werden, das sollte kein großes Problem sein.
Es ist auch erwähnenswert, dass Sie sich vielleicht nicht um die 508er-Compliance kümmern müssen, aber wenn Sie dies tun, wird die Unterstützung aller verschiedenen Geräte überraschenderweise einfacher.
Wenn ich sage einfacher, meine ich zum Beispiel, dass ich nicht auf Tippen hören muss. Alles, was ich tue, ist klicken, Tastendruck ruft klicken auf, Tippen ruft klicken auf, vorausgesetzt, ich verwende das richtige Element [und die richtigen Attribute] für die Aufgabe.
Einer der Schätze, die ich kürzlich gelernt habe, war, dass ich auf iOS-Geräten keinen Sound automatisch abspielen konnte. Er musste vom Benutzer ausgelöst werden, um den Ton beim ersten Mal abzuspielen, Sie konnten keinen Klick per JavaScript aufrufen, er musste vom Benutzer kommen, was gut für 508 ist, da der Benutzer die Chance bekommt, den Screenreader zu nutzen, und dann auswählen kann, zu klicken.
Ein gut getimter Artikel für mich. Einige Dinge, über die ich noch nachdenken musste. Ich habe gerade erst angefangen,
<button>zu verwenden, und musste ein paar Dinge lernen. Ich geriet in Panik, als es in IE8 nicht funktionierte, aber das war leicht zu beheben. Abgesehen von all den praktischen Gründen, die genannt wurden, fühlt es sich einfach viel besser an als die Verwendung von Inputs oder gestylten Anker-Tags.Danke, Chris. Ich stimme den meisten Punkten zu, über die Sie geschrieben haben. Obwohl ich von einer der Dinge, die Sie im Abschnitt „Wann Links mehr Sinn machen“ beschreiben, ziemlich überrascht bin.
Ich bezweifle ernsthaft, dass dies auf ein Link-Tag zutrifft, auch wenn Sie versuchen, ihm einen aussagekräftigen href zu geben. Können Sie diesen Teil bitte etwas klarstellen? Er ist ein wenig irreführend :)
Das
action-Attribut desform-Tags enthält normalerweise die URL, und der Browser lädt diese URL nach dem Absenden standardmäßig.Richtig, das ist kein gutes Beispiel, Entschuldigung dafür. Das Beispiel sollte ein Ajax-Suchfeld mit Typ-Ahead sein, dessen Aktionen durch einen Submit-Button ausgelöst werden, aber es ist als echtes
<form>(wie Sie vorschlagen) mit einemaction-Attribut aufgebaut, das zu einer Seite führt, die serverseitig das tut, was sie tun muss, und eine nützliche Seite rendert. Der Posterboy für progressive Enhancement, wirklich.Ich habe gerade Ihren verlinkten Artikel „ID’s dürfen nicht mit einer Zahl beginnen“ gelesen und Sie sagen darin, dass „Klassenbezeichner **mit einer Zahl beginnen dürfen**“ !! obwohl das nicht stimmt .. ich weiß es, weil ich mehrmals versucht habe, Klassennamen mit Zahlen beginnen zu lassen, bevor ich merkte, dass ich es nicht kann. Ist das also ein Fehler oder gibt es eine Möglichkeit, das tatsächlich zum Laufen zu bringen?
Ich kenne mehrere Sprachen, und ich kann mich an keine erinnern, die eine Zahl am Anfang eines Variablen-/ID-Namens erlaubt.
Beachten Sie, dass alles, was Sie auf einer HTML-Seite platzieren, zu etwas im „DOM“ wird … das bedeutet Sprache, Code, IDs, Variablennamen usw.
Es ist am besten, IDs, die mit einer Zahl beginnen, unter allen Umständen zu vermeiden, selbst wenn Sie einen Browser oder eine Situation finden, in der es funktioniert, würden Sie auf dünnem Eis wandeln.
PS: für Leute, die Elemente auf der Seite mit JS durchlaufen – wie z.B. #myRow1, #myRow2… dann 1) platzieren Sie die Zahl einfach am Ende, 2) alternativ verwenden Sie keine IDs und lernen Sie die bessere Methode, diese Elemente mit „Selektoren“ und einer Funktion wie .each() unter Verwendung einer JS-Bibliothek (wie jQuery) durchzulaufen.
IDs und Klassen können leicht mit einer Zahl beginnen (jedes Zeichen außer Leerzeichen, einschließlich aller Unicode-Zeichen). Maskieren Sie einfach das jeweilige Zeichen oder verwenden Sie den Unicode-Codepunkt wie bereits beschrieben: https://css-tricks.de/use-button-element/#comment-1066440
Dies ist *gemäß der HTML-Spezifikation*. Nur HTML <=4 hatte Einschränkungen für diese Attribute.
Was die Angelegenheit betrifft, dass HTML-Quellcode zu DOM wird: Das DOM ist mehr als fähig, Unicode zu verarbeiten. Sonderzeichen sind eine Angelegenheit, mit der ALLE Sprach-Lexer/Parser umgehen. Und sie gehen damit auf dieselbe Weise um: durch Maskierung. Sonderzeichen sind nur dann besonders, wenn sie als Text serialisiert werden. Wenn sie in ihre Speicherstrukturen (als DOM oder ASTs oder andere) eingelesen werden, ist nichts Besonderes an ihnen. Sie sind nur Zeichen (oder Token).
Ich habe vergessen zu sagen, dass ich nur über CSS-Klassennamen gesprochen habe
Ich bin mir nicht sicher, ob ich Ihnen folgen kann. Ich nehme an, Sie meinen das HTML-Klassenattribut (da es keine CSS-Klassen gibt).
Aber die HTML-Spezifikation besagt, dass sowohl das
id- als auch dasclass-Attribut dieselben Zeichenanforderungen haben; mit der Ausnahme, dassidkeine Leerzeichen enthalten darf, währendclasseine Liste von durch Leerzeichen getrennten Token ist. Aber die Token selbst halten sich an dieselben Regeln. Das heißt, jedes Zeichen ist gültig (an jeder Position) außer Leerzeichen.Ein führende Ziffer in einem Klassennamenselektor müsste also auf dieselbe Weise maskiert werden wie ein ID-Selektor: durch Verwendung des Unicode-Codepunkts.
Langer detaillierter Beitrag zu den Spezifikationen für die Maskierung von Token in CSS und JS
Schön! +10 für eine vollständige Erklärung, so viele Artikel, die ich umsonst gelesen habe, dieser hat alles, was ich brauchte.
In meiner Arbeit verwendet jeder „schmutzigen Code“, nur um ein Bild in die Buttons zu bekommen, sogar Tabellen, um es so auszurichten, wie er es wollte, und Links darin zu verwenden, um den Benutzer auf eine andere Seite zu senden.
Ich hatte Probleme, weil der Button immer das Formular „submitet“, wenn er sich in einem Formular befindet, aber wir senden nichts „submit“, jetzt verwalten wir die Werte des Formulars mit JavaScript oder jQuery und senden sie später mit xajax.
Damit ein Button das Formular, in dem er sich befindet, nicht abschickt, muss er das Attribut „type“ auf „button“ haben. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button?redirectlocale=en-US&redirectslug=HTML%2FElement%2Fbutton#attr-type
Ich würde jedoch davon abraten, Ihr gesamtes Formular zu JavaScript zu machen. Vielmehr sollte das Formular normal ohne JS funktionieren. Verwenden Sie JS, um das Formular zu verbessern und per Ajax abzuschicken; aber machen Sie es nicht zur Pflicht.