{"id":297030,"date":"2020-02-14T08:24:51","date_gmt":"2020-02-14T15:24:51","guid":{"rendered":"https:\/\/css-tricks.com\/?p=297030"},"modified":"2022-02-22T06:54:11","modified_gmt":"2022-02-22T14:54:11","slug":"a-complete-guide-to-links-and-buttons","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/a-complete-guide-to-links-and-buttons\/","title":{"rendered":"A Complete Guide to Links and Buttons"},"content":{"rendered":"\n
There is a lot to know about links and buttons in HTML. There is markup implementation and related attributes, styling best practices, things to avoid, and the even-more-nuanced cousins of the link: buttons and button-like inputs.<\/p>\n\n\n\n
Let’s take a look at the whole world of links and buttons, and all the considerations at the HTML, CSS, JavaScript, design, and accessibility layers that come with them. There are plenty of pitfalls and bad practices to avoid along the way. By covering it, we\u2019ll have a complete good UX implementation of both elements.<\/p>\n<\/div><\/div>\n\n\n\n\n\n\n\n
Quick guidelines<\/strong> on when to use each:<\/p>\n\n\n\n Links are one of the most basic, yet deeply fundamental and foundational building blocks of the web. Click a link, and you move to another page or are moved to another place within the same page.<\/p>\n\n\n\n That’s a link to a “fully qualified” or “absolute” URL.<\/p>\n\n\n You can link “relatively” as well:<\/p>\n\n\n\n That can be useful, for example, in development where the domain name is likely to be different than the production site, but you still want to be able to click links. Relative URLs are most useful for things like navigation, but be careful of using them within content \u2014 like blog posts \u2014 where that content may be read off-site, like in an app or RSS feed.<\/p>\n\n\n Links can also be “hash links” or “jump links” by starting with a Clicking that link will “jump” (scroll) to the first element in the DOM with an ID that matches, like the section element above.<\/p>\n\n\n\n 💥 Little trick:<\/strong> Using a hash link (e.g. 💥 Little trick:<\/strong> Jump-links can sometimes benefit from smooth scrolling<\/a> to help people understand that the page is moving from one place to another.<\/p>\n\n\n\n It’s a fairly common UI\/UX thing to see a “Back to top” link on sites, particularly where important navigational controls are at the top but there is quite a bit of content to scroll (or otherwise navigate) through. To create a jump link, link to the ID of an element that is at the top of the page where it makes sense to send focus back to.<\/p>\n\n\n\n Jump links are sometimes also used to link to other anchor ( There are accessibility considerations<\/a> of these, but overall they are acceptable. <\/p>\n\n\n A link without an When a link has no You can use the The bit that makes it work is Making links open in new tabs is a major UX discussion. We have a whole article about when to use it here<\/a>. Summarized:<\/p>\n\n\n\n Don’t use it:<\/p>\n\n\n\n Do use it:<\/p>\n\n\n\n The This attribute is for the relationship of the link to the target.<\/p>\n\n\n\n The Here are some basic examples:<\/p>\n\n\n\n There are also some And also some You can use multiple space-separated values if you need to (e.g. And finally, some The default role of a link is You’d only need that if you were faking a link, which would be a weird\/rare thing to ever need to do, and you’d have to use some JavaScript in addition to this to make it actually follow the link.<\/p>\n\n\n\n Just looking above you can see how much extra work faking a link is, and that is before you consider that is breaks right-clicking, doesn’t allow opening in a new tab, doesn’t work with Windows High Contrast Mode and other reader modes and assistive technology. Pretty bad!<\/p>\n\n\n\n A useful ARIA role to indicate the current<\/a> page, like:<\/p>\n\n\n\n Probably not<\/a>. Save this for giving an Hover-triggered is the key phrase here. It’s unusable on any touch-only device. If a link needs more contextual information, provide that in actual content around the link, or use descriptive text the link itself (as opposed to something like “Click Here”).<\/p>\n\n\n If a link only has an icon inside it, like:<\/p>\n\n\n\n That isn’t enough contextual information about the link, particularly for accessibility reasons, but potentially for anybody<\/a>. Links with text are almost always more clear. If you absolutely can’t use text, you can use a pattern like:<\/p>\n\n\n\n Unlike Images can be links if you wrap them in a link. There is no need to use the alt text to say the image is a link, as assistive technology will do that already.<\/p>\n\n\n\n You can link a whole area of content, like:<\/p>\n\n\n\n But of course, there are UX implications. For example, it can be harder to select the text, and the entire element needs fairly complex styling to create clear focus and hover states. There are also accessibility implications<\/a>, like the fact that the content of the entire card is read before it is announced as a link.<\/p>\n\n\n\n Here’s an example with two approaches. The first wraps the entire card in a link. This is valid, but remember the implications. The second has a link inside the title, and the link has a pseudo-element on it that covers the entire card. This also has implications (a bit awkward to select text, for example), but is perhaps more expected for assistive technology. <\/p>\n\n\n\n<a href=\"\/somewhere\">link<\/a><\/code>)<\/li>
<button type=\"button\">button<\/button><\/code>)<\/li>
<input type=\"submit\" value=\"Submit\"><\/code>)<\/li><\/ul>\n<\/div><\/div>\n\n\n\n
Links<\/h2>\n\n\n
Table of Contents<\/strong><\/summary>\n\n\n\n
HTML implementation<\/h3>\n\n
A basic link<\/h4>\n\n\n
<a href=\"https:\/\/css-tricks.com\">CSS-Tricks<\/a><\/code><\/pre>\n\n\n\n
A relative link<\/h4>\n\n\n
<!-- Useful in navigation, but be careful in content that may travel elsewhere (e.g. RSS) -->\n<a href=\"\/pages\/about.html\">About<\/a><\/code><\/pre>\n\n\n\n
A jump link<\/h4>\n\n\n
#<\/code>:<\/p>\n\n\n\n
<a href=\"#section-2\">Section Two<\/a>\n<!-- will jump to... -->\n<section id=\"section-2\"><\/section><\/code><\/pre>\n\n\n\n
#0<\/code>) in development can be useful so you can click the link without being sent back to the top of the page like a click on a
#<\/code> link does. But careful, links that don’t link anywhere should never make it to production.<\/p>\n\n\n\n
<a href=\"#top-of-page\">Back to Top<\/a><\/code><\/pre>\n\n\n\n
<a><\/code>) elements that have no
href<\/code> attribute. Those are called “placeholder” links:<\/p>\n\n\n\n
<a id=\"section-2\"><\/a>\n<h3>Section 2<\/h3><\/code><\/pre>\n\n\n\n
Disabled links<\/h4>\n\n\n
href<\/code> attribute is the only practical way<\/a> to disable a link. Why disable a link? Perhaps it’s a link that only becomes active after logging in or signing up.<\/p>\n\n\n\n
a:not([href]) {\n \/* style a \"disabled\" link *\/\n}<\/code><\/pre>\n\n\n\n
href<\/code>, it has no role, no focusability, and no keyboard events. This is intentional<\/a>. You could think of it like a
<span><\/code>.<\/p>\n\n\n
Do you need the link to open in a new window or tab?<\/h4>\n\n\n
target<\/code> attribute for that, but it is strongly discouraged<\/a>. <\/p>\n\n\n\n
<a href=\"https:\/\/css-tricks.com\" target=\"_blank\" rel=\"noopener noreferrer\">\n CSS-Tricks\n<\/a><\/code><\/pre>\n\n\n\n
target=\"_blank\"<\/code>, but note the extra
rel<\/code> attribute and values there which make it safer<\/a> and faster<\/a>.<\/p>\n\n\n\n
Need the link to trigger a download?<\/h4>\n\n\n
download<\/code> attribute<\/a> on a link will instruct the browser to download the linked file rather than opening it within the current page\/tab. It’s a nice UX touch.<\/p>\n\n\n\n
<a href=\"\/files\/file.pdf\" download>Download PDF<\/a><\/code><\/pre>\n\n\n
The
rel<\/code> attribute<\/h4>\n\n\n
rel<\/code> attribute is also commonly used on the
<link><\/code> element (which is not used for creating hyperlinks, but for things like including CSS and preloading). We’re not including
rel<\/code> values for the
<link><\/code> element here, just anchor links.<\/p>\n\n\n\n
<a href=\"\/page\/3\" rel=\"next\">Next<\/a>\n<a href=\"\/page\/1\" rel=\"prev\">Previous<\/a>\n\n<a href=\"http:\/\/creativecommons.org\/licenses\/by\/2.0\/\" rel=\"license\">cc by 2.0<\/a>\n\n<a href=\"\/topics\/\" rel=\"directory\">All Topics<\/a><\/code><\/pre>\n\n\n\n
rel=\"alternate\"<\/code>: Alternate version of the document.<\/li>
rel=\"author\"<\/code>: Author of the document.<\/li>
rel=\"help\"<\/code>: A resource for help with the document.<\/li>
rel=\"license\"<\/code>: License and legal information.<\/li>
rel=\"manifest\"<\/code>: Web App Manifest document.<\/li>
rel=\"next\"<\/code>: Next document in the series.<\/li>
rel=\"prev\"<\/code>: Previous document in the series.<\/li>
rel=\"search\"<\/code>: A document meant to perform a search in the current document.<\/li><\/ul>\n\n\n\n
rel<\/code> attributes specifically to inform search engines<\/a>:<\/p>\n\n\n\n
rel=\"sponsored\"<\/code>: Mark links that are advertisements or paid placements (commonly called paid links) as sponsored.<\/li>
rel=\"ugc\"<\/code>: For not-particularly-trusted user-generated content, like comments and forum posts.<\/li>
rel=\"nofollow\"<\/code>: Tell the search engine to ignore this and not associate this site with where this links to.<\/li><\/ul>\n\n\n\n
rel<\/code> attributes that are most security-focused:<\/p>\n\n\n\n
rel=\"noopener\"<\/code>: Prevent a new tab from using the JavaScript
window.opener<\/code> feature, which could potentially access the page containing the link (your site) to perform malicious things, like stealing information or sharing infected code. Using this with
target=\"_blank\"<\/code> is often a good idea<\/a>.<\/li>
rel=\"noreferrer\"<\/code>: Prevent other sites or tracking services (e.g. Google Analytics) from identifying your page as the source of clicked link.<\/li><\/ul>\n\n\n\n
rel=\"noopener noreferrer\"<\/code>)<\/p>\n\n\n\n
rel<\/code> attributes come from the microformats standard<\/a> or the indieweb<\/a> like:<\/p>\n\n\n\n
rel=\"directory\"<\/code>: Indicates that the destination of the hyperlink is a directory listing containing an entry for the current page.<\/li>
rel=\"tag\"<\/code>: Indicates that the destination of that hyperlink is an author-designated “tag” (or keyword\/subject) for the current page.<\/li>
rel=\"payment\"<\/code>: Indicates that the destination of that hyperlink provides a way to show or give support for the current page.<\/li>
rel=\"help\"<\/code>: States that the resource linked to is a help file or FAQ for the current document.<\/li>
rel=\"me\"<\/code>: Indicates that its destination represents the same person or entity as the current page.<\/li><\/ul>\n\n\n
ARIA roles<\/h4>\n\n\n
link<\/code>, so you do not<\/em> need to do:<\/p>\n\n\n\n
<a role=\"link\" href=\"\/\">Link<\/a><\/code><\/pre>\n\n\n\n
<span class=\"link\" tabindex=\"0\" role=\"link\" data-href=\"\/\">\n Fake accessible link created using a span\n<\/span><\/code><\/pre>\n\n\n\n
<a href=\"\/\" aria-current=\"page\">Home<\/a>\n<a href=\"\/contact\">Contact<\/a>\n<a href=\"\/about\">About\/a><\/a><\/code><\/pre>\n\n\n
Should you use the
title<\/code> attribute?<\/h4>\n\n\n
iframe<\/code> a short, descriptive title.<\/p>\n\n\n\n
<a title=\"I don't need to be here\" href=\"\/\">\n List of Concerts\n<\/a><\/code><\/pre>\n\n\n\n
title<\/code> provides a hover-triggered UI popup showing the text you wrote. You can’t style it, and it’s not really that accessible<\/a>. <\/p>\n\n\n\n
Icon-only links<\/h4>\n\n\n
<a href=\"\/\">😃<\/a>\n\n<a href=\"\/\">\n <svg> ... <\/svg>\n<\/a><\/code><\/pre>\n\n\n\n
<a href=\"\/\">\n <!-- Hide the icon from assistive technology -->\n <svg aria-hidden=\"true\" focusable=\"false\"> ... <\/svg>\n <!-- Acts as a label that is hidden from view -->\n <span class=\"visually-hidden\">Useful link text<\/span>\n<\/a><\/code><\/pre>\n\n\n\n
visually-hidden<\/code> is a class used to visually hide the label text with CSS:<\/p>\n\n\n\n
.visually-hidden {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}<\/code><\/pre>\n\n\n\n
aria-label<\/code>, visually hidden text can be translated and will hold up better in specialized browsing modes<\/a>.<\/p>\n\n\n
Links around images<\/h4>\n\n\n
<a href=\"\/buy\/puppies\/now\">\n <img src=\"puppy.jpg\" alt=\"A happy puppy.\">\n<\/a><\/code><\/pre>\n\n\n
Links around bigger chunks of content<\/h4>\n\n\n
<a href=\"\/article\/\">\n <div class=\"card\">\n <h2>Card<\/h2>\n <img src=\"...\" alt=\"...\">\n <p>Content<\/p>\n <\/div>\n<\/a><\/code><\/pre>\n\n\n\n