HTML 元素中固有的语义告诉我们应该如何使用它们。需要标题?您需要一个标题元素。想要一段文字?我们可靠的朋友<p>
就在这里,一如既往地忠诚。想要下载?好吧,您需要…嗯。
什么最能描述下载?它是一个触发的动作,因此应该属于<button>
元素的领域吗?还是它是一个目的地,因此最好使用<a>
元素来描述?
按钮执行操作,链接跳转到位置
关于何时使用按钮以及何时使用链接似乎存在很多混淆。就像制表符与空格或套头衫与拉链衫一样,这场争论可能永无止境。
然而,W3C 为我们提供了一个重要的线索来判断谁是对的:download
属性。
现在怎么办?
我们所知的互联网不可能没有链接。它们构成了语义网,这是一个非常棒、棒极了、令人难以置信的复杂信息网络,使您能够在此刻阅读这篇文章。
与所有其他元素一样,锚链接可以通过HTML 的全局属性进行修改。锚链接元素还具有一些独特的属性,有助于控制它们如何连接到其他文档和文件。
其中一个属性称为download
。它告诉浏览器链接的目标应该保存到您的设备上,而不是访问它。您仍然“导航”到该文件,只是不查看它,而是获取一个副本供自己使用。
任何类型的文件都可以是下载文件!这甚至包括 HTML,浏览器通常会显示 HTML。该属性的存在实际上是一个人为编写的标记,告诉浏览器跳过尝试呈现它检索到的内容,而只是将其存储起来。
<a download href="recipe.html">
Download recipe
</a>
这引出一个非常重要的观点:我们无法了解每个用户访问我们网站的原因,但我们可以使用提供的工具来帮助引导他们前进。如果这意味着存储 HTML 文档以供离线使用,那么我们有能力帮助使体验尽可能简单。
其他证据
仍然不相信?这里有一些更多值得思考的东西
渐进增强
JavaScript 比我们愿意承认的更脆弱。即使 JavaScript 出现故障,<a>
元素也能正常工作。使用锚点进行下载意味着即使在次优情况下,用户也可以访问他们需要的内容。
稳健的解决方案始终是最理想的——在危机时刻,它甚至可以挽救生命。这听起来可能有些夸张,但在需要的时候拥有一份稳定的离线工作副本可能会产生天壤之别。
语义和可访问性
我的朋友Scott,他专门从事这类工作,告诉我们
关于是否应该使用按钮或链接来下载文件的争论有点愚蠢,因为链接的全部目的始终是下载内容。HTML 是一个文件,与所有其他文件一样,它需要从服务器检索并下载,然后才能呈现给用户。
Photoshop 文件、HTML 和其他已理解的媒体文件之间的区别在于,浏览器会自动显示后两者。如果要链接到 Photoshop
.psd
文件,浏览器将启动文档更改以呈现该文件,可能会像“哈哈,什么鬼?”,然后启动操作系统下载提示。混淆似乎来自开发人员对“链接跳转到位置,按钮执行操作”的理解过于字面化。是的,这是真的,**但链接实际上并没有跳转到任何地方**。它们**检索信息并下载它**。按钮执行操作,但它们本身并不“获取”文档。虽然它们可以用于获取数据,但通常是更改当前文档的状态,而不是检索和呈现新文档。它们可以
获取
数据,关于form
的功能,但它仍然是在更新网页文档的上下文中,而不是下载单个文件。长话短说,
download
属性之所以对锚链接唯一,是有原因的。download
增强了链接检索数据的固有功能。它绕过了尝试在浏览器中呈现文件的步骤,而是说:“你知道吗?我只是要保存它以备后用…”
谢谢,Scott!
设计一个好的下载链接
下载文件的默认体验可能会让人感到突兀——它通常不是我们正常浏览行为的一部分。用户必须将他们的思维模型从页面到页面切换和填写表单转变为导航文件系统和提取压缩存档。对于技术水平较低的人来说,这可能是一个令人困惑且令人沮丧的上下文切换。
作为负责任的设计师和开发人员,我们希望使与下载链接交互的体验尽可能好。由于我们无法修改浏览器下载行为本身的操作方式,因此我们应该使周围的用户体验尽可能透明和简化。
告诉我里面有什么
尽可能多地向用户提供信息,以帮助他们了解即将发生的事情。预测并回答以下问题可以提供帮助
什么?
动词加名词是获胜组合。描述链接的作用以及它能带给你什么。
<a download href="downloads/fonts.zip">
Download Fonts
</a>
仅凭动词下载只能表明激活链接时将触发什么行为。包含名词字体对于消除对将要获取内容的歧义非常有用。
在页面上有多个下载链接的情况下,名词的存在将有助于使用屏幕阅读器浏览的用户。如果您正在浏览一个页面,该页面有八个没有名词的下载链接,听起来会是这样的
您知道这八个链接中的哪一个可以获取您想要的内容吗?不知道?这不太好。同样,<a>
元素上的download
属性的存在不会由屏幕阅读器宣布,因此动词也同样重要。提供上下文非常重要!
请记住,显而易见总是胜出。虽然可以通过使用视觉隐藏 CSS 类来隐藏下载的名称部分,从而使您的合规性检查满意,但这会给您的用户带来额外的认知负担。隐藏的名称还会牺牲浏览器页面搜索等功能。
下载时长?
KB、MB、GB、TB。我们这里说的不是神户牛肉、乐高积木、银杏或肺结核。我们说的是下载文件的大小,以及相应地,下载完成需要多长时间。
了解您的受众。大小为 128 KB 的文件比大小为 2 GB 的文件下载速度快得多,但其数字却大得多。除非您的受众熟悉用于描述文件大小的术语,否则如果您只告诉他们有效负载的大小,他们可能无法理解他们将要面临什么。
对于较大的文件,等待时间可能尤其成问题。标准下载是“非此即彼”的——中断可能会损坏它们并使其变得毫无用处。更糟糕的是,它可能会浪费计量数据计划中的宝贵数据,这是一个不幸的非常现实的问题。
准确地确定某人的当前连接速度也极其困难。虽然网络信息 API看起来很有希望,但当前浏览器支持并不理想。
在报告连接和实际连接之间存在隐藏的细微差别。高速5G 连接可能会在某人进入隧道或走到家中覆盖范围不好的地方时断掉。这甚至还没有开始涉及与限流相关的复杂性,这是一个不幸的非常现实的问题。
为了解决这些问题,请应用一些微文案。
查看 Eric Bailey (@ericwbailey) 在 CodePen 上的笔 下载电影。
您的用户比您更了解其连接质量的细节。现在,他们拥有做出明智决策所需的信息,并带有一点有意模糊性来控制期望。
但是进度条呢?
进度条是显示计算任务完成程度的UI 元素。对于UX 设计师来说,它们是必不可少的(也是一个玩弄感知性能的机会)。但是,在下载方面,我对此持谨慎态度。
充其量,它们是多余的。浏览器已经提供了UI 来指示下载的进度。最糟糕的是,它们是一个令人困惑的责任。添加它们会引入不必要的实现和维护复杂性——尤其是在结合前面概述的确定连接速度和质量的问题时。
为什么?
向用户说明他们为什么要关心。它会通过解决现有问题来消除挫败感吗?它会通过添加新功能来增加乐趣吗?它会通过使事物更安全来让用户放心吗?虽然并非每个下载都需要回答“为什么?”这个问题,但对于具有复杂或深奥目的的有效负载来说,这是一个好主意。
如果我正在下载路由器固件,我可能不理解(或不关心)更新在幕后执行的具体细节。但是,关于我为什么需要进行此操作的一些高级通信将大有帮助。
查看 Eric Bailey (@ericwbailey) 在 CodePen 上的笔 描述下载内容。
下一步?
有关下载完成后该做什么的说明可能会有用。再次强调,了解您的受众至关重要。
以我们的路由器示例为例,技术不太娴熟的用户很有可能最终会访问产品支持页面。他们到达时很可能处于情绪困扰状态。在下载启动后,提供有关如何安装新固件的分步信息以及相关支持资源的链接,可以极大地缓解负面情绪。
这是实用的同理心。预料到用户的需求和情绪状态并主动提供解决方案会直接影响到减少昂贵的支持电话等方面。这些节省意味着组织资源可以重新分配到其他重要的事业上。
代码实现
标记差异
从用户体验和可访问性的角度来看,一个好的实践是区分内部和外部链接。这意味着创建一个指示器,表明链接的作用不仅仅是将您带到网站或 Web 应用上的其他位置。对于指向外部站点的链接,常见的做法是使用从框中突出的箭头。对于下载,向下箭头是事实上的标准。

有些人可能认为,当应用于浏览器已知要存储的链接时,download
属性的存在是多余的。我不同意。
除了在 HTML 中成为一个明确的语义标记之外,download
属性还可以用作一个简单而优雅的样式挂钩。CSS 属性选择器——允许我们根据有助于描述 HTML 元素的特性创建样式的代码——允许我们定位任何是下载的链接并对其进行样式设置,而无需附加特殊的类。
a[download] {
color: hsla(216, 70%, 53%, 1);
text-decoration: underline;
}
a[download]::before {
content: url('../icons/icon-download.svg');
height: 1em;
position: relative;
top: 0.75em;
right: 0.5em;
width: 1em;
}
a[download]:hover,
a[download]:focus {
text-decoration: none;
}
结合描述下载的文本,图标的存在清楚地传达了激活此链接时将遵循下载行为。它还提供了额外的目标区域,非常适合触屏设备。
同时定位download
属性的存在以及href
属性末尾字符串中的文件扩展名,可以让我们变得更加花哨。我们可以利用层叠样式表为所有图标设置一致的处理方式,但根据文件类型更改图标本身。这对于在一个页面上可以下载多种类型内容的情况非常有用。
查看 Eric Bailey (@ericwbailey) 在 CodePen 上的笔 下载图标。
如果您正在寻找起点,我可以维护一个常见文件类型的列表。请记住,只包含您需要的选择器,以免在生产 CSS 中创建不必要的膨胀。如果您的网站或 Web 应用包含许多图标和/或大量花哨的状态管理,请考虑使用SVG 图标系统。它将提高性能——只需记住使其可访问!
命名有效负载
download
属性可以接受一个可选值,允许作者为下载的文件创建自定义的、用户友好的名称。在此示例中,我们将播客剧集的名称更改为在下载到用户设备时有意义的内容,同时保留对播客制作人有意义的内容。
<a
download="Pod-People-Podcast-Episode-12-Feed-Me-Seymour.mp3"
href="https://www.dropbox.com/s/txf5933cwxhv1so6/12-final-v5-RADIO-EDIT.m4a?dl=0">
Download Episode 12
</a>
对于复杂的站点,此属性允许我们创建对请求者有意义的下载,同时还可以利用CDN 和动态生成的文件等功能。这里没有太多复杂的后台魔法,只是一些简单的模板逻辑。
<a
href="https://s3-us-west-2.amazonaws.com/ky22o6s6g8be80bak577b17e34bb93cex3.pdf"
download="{{ user.name | slugify }}-{{ 'now' | date: "%Y" }}-tax-return.pdf">
Download your {{ 'now' | date: "%Y" }} Tax Return
</a>
材料诚实性
保持内容的外观和行为与用于描述它的 HTML 元素一致,对于加强外部一致性非常有用。外部一致的内容对于确保人们能够并且愿意使用您的网站或 Web 应用程序至关重要。使用对于参与度非常重要,这是一个让商业人士感到高兴的指标。
我们可以将这种语义漂移的责任完全归咎于趋势。渴望尝试最新技术的设计师和开发人员张开双臂迎接模糊性。领导层追逐感知到的价值以保持相关性。
不必如此。网站可以既美观又易访问。语义和当前的框架/美学并不相互排斥。花点时间回顾一下基础知识——您可能会发现一些简单的东西,只需稍作努力就能帮助每个人获得他们需要的东西。
不幸的是,download 属性有时会被忽略。
我遇到过一个情况,我想从网页下载几张图片。我创建了一个用户脚本以实现此目的。我使用
document.querySelectorAll
收集了这些图片,然后创建了一个像<a download href="imgsrc">
这样的不可见的 a 标签,然后以编程方式点击了每个链接。该脚本在 Chrome 中完美运行(询问我是否真的想允许多次下载),但是当我在 Firefox 中尝试相同的脚本时,它只在浏览器中打开了最后一张图片。Firefox 认为既然它可以渲染图像,它就会显示它而不是下载它。
但是,我编写的一个类似的用户脚本用于下载一些 json 数据,该脚本生成了一个类似
<a download="data.json" href="data:application/json,{}">
的标签并点击了该标签,在两个浏览器中都能完美运行。基本上,如果文档类型是浏览器可以原生渲染的类型,则某些浏览器会忽略 download 属性。
我认为问题不在于内容类型,而在于来源:因为一些“偏执”的人在目标位于其他来源时会忽略
a[download]
。例如:在 Firefox 中打开我的这个旧项目 并点击下载链接(“可以下载”)。即使下载的文件是 HTML 文件(Firefox 可以原生渲染),它也会触发下载。请注意,Chrome 将遵循与 Firefox 相同的行为。不错的文章!
我发现这篇文章的启发性超越了按钮。只是好的用户体验。
按钮执行操作,链接跳转到位置
把它印在海报上。
如果您的下载 UI 元素不仅仅用于单个静态资源,而是在您按下它时实际上生成一个自定义文件呢?
例如,如果您有一个文件列表,您可以选中任意多个文件,然后按下下载 UI 元素将这些文件压缩在一起,然后下载该文件。在这种情况下,无论如何我们都会使用 JS,并且 UI 元素触发的不仅仅是链接,它还在“执行操作”,因此按钮是有意义的,对吧?
但是,如果您还有常规的静态下载,可以通过带“download”元素的链接轻松完成。您是否仍然将它们作为链接,而将更复杂的操作作为按钮,或者这种不一致会导致问题?特别是如果您想以类似的方式对其进行样式设置(因为为什么不呢?对于用户来说,他们在这两种情况下都只是在下载,他们不需要理解静态文件和动态生成文件之间的区别)。
我认为“按钮执行操作(配置下载),链接跳转到位置(请求下载)”仍然适用。
您最终仍然会在调整自定义下载后请求它,因为您无法动态更改下载的内容(除非像 torrenting 这样的事情)。也可以根据按钮事件轻松更改 download 属性的字符串。
我认为您在最终用户无需担心动态下载或静态下载之间的区别这一点上抓住了重点。实际上,链接的美学可能取决于现有的设计工作。但这篇文章在一定程度上是在恳求您考虑您在视觉上调用的内容以及围绕它的期望。
用户的一个不太为人所知的行为是,当用户想要选择一个备用下载位置时。
在下载链接上,用户可以右键点击 ->“另存为...”并将下载直接放置到他们选择的文件夹中。例如,如果您希望某些内容直接进入可移动介质,这将非常方便。
在下载按钮上,没有这样的选项。
值得注意的是:Chrome 65 将阻止应用了 download 属性的链接的有效负载,如果有效负载是跨源资源。我相信该属性仍然可以作为选择器,但是。
在我的最新项目中,我没有为一些下载链接的文本同时编写动词和名词,而是将动词“下载:”作为静态文本,然后将每个名词(小册子、封面、视频等)作为垂直堆叠的类似按钮的链接(旧的透明框中的幽灵链接,带有一个与链接颜色匹配的完整框形边框)。我认为即使是最不熟悉互联网的人也会明白每个框都用于下载列出的项目,并且他们会更好地了解每种类型的文件在他们的设备上通常需要多长时间才能下载。
其余的下载“链接”实际上是原生音频元素附带的下载图标,还包括每首曲目以分钟和秒为单位的时长,我认为这是另一个关于每个下载需要多长时间的良好非特定指标。
此外,在帮助页面中,我将解释如何在他们自己的设备上找到文件,如果他们足够精通,可以按照一些基本说明操作。毕竟,如果他们正在使用我正在构建的扩展程序,他们必须已经下载了它,包括 MP3、SVG、MP4、PDF 等。
我不在每个链接中包含“下载”一词、将链接样式设置为类似按钮的幽灵链接、对音乐使用原生下载方法以及不为每个下载提供完整的说明,这样做错了吗?我一直在努力保持 UI 和可见内容的简洁,以避免遮盖动画 SVG 背景,但是如果为了添加完整的说明以帮助用户理解下载内容而必须放弃音乐视频般的动画,那么我将放弃它们并将其设置为看起来像一个长列表文章并放弃帮助页面。
省略动词的问题在于,如果视力低下或没有视力的用户借助屏幕阅读器浏览,他们可能无法确定名词是什么。
屏幕阅读器可以抓取当前页面并按内容类型(标题、链接、按钮等)创建列表,以便于导航。如果通过这种方法访问,则放置在下载链接视觉邻近处的静态文本将不会一同出现。虽然一遍又一遍地显示“下载”一词似乎是多余的,但包含它可以在很大程度上为没有视觉辅助或将页面内容缩放到布局可能无法传达视觉关系的程度的用户提供上下文。
如果页面的主要目的是访问下载,并且其标题和一级标题传达了这一点,我可能会看到一个省略动词的案例。但是,这会增加页面上其余非下载链接的目的的模糊性。屏幕阅读器将浏览器扩展程序视为小型网页,因此我认为建议仍然适用。
我不确定您指的是哪个扩展程序,但听起来曲目长度是一个很好的细节!我还建议研究“减少运动”媒体查询以获得动画背景,以便适应前庭障碍、偏头痛触发因素等。
这些都是很好的观点,尽管我想知道替代文本是否可以更好地解决屏幕阅读器的问题,而无需重复动词的冗余视觉效果。我不知道这是否可行,因为它是一个扩展程序而不是网站——扩展程序不需要互联网访问,除了最初的下载。
为了进一步解释我正在构建的内容,动画背景是旧音乐视频的纯代码等效项,但运行时间与专辑的完整长度一样长,尽管没有任何事件触发器将其与音乐绑定(动画持续运行专辑的不间断持续时间,但不会暂停或跳转到动画中的其他位置)。它也是极其缓慢的动画,因此动画在前几分钟内不太可能被注意到,而不是会导致偏头痛或其他与运动相关的触发因素。
此外,每个页面上的大多数链接都是下载链接;其余链接用于更改当前播放的曲目(用方括号标记)、音量和播放/暂停(音频元素的原生功能)。没有标题,因为点击浏览器中的扩展程序图标会打开一个菜单(唯一一个链接在新页面中打开的地方),菜单中唯一的选项是特定专辑、合辑中的曲目、单曲、一些供其他音乐艺术家使用的样本、关于页面和简短的帮助页面。
由于扩展程序在浏览器中的打开方式,缩放是不可能的,因为所有内容都以弹出窗口的形式显示,而不是全页面显示。虽然我希望扩展程序尽可能多地为人们所用,但我也不希望破坏所有视觉导航用户的视觉效果。鉴于扩展程序的主要目的是提供音乐,我已经排除了任何失聪或听力障碍的用户。