您的位置:

如何优化表格的可访问性和用户体验

表格是网站中不可或缺的一部分,可以用来展示大量的数据和信息,但如果未正确使用和设计,会对可访问性和用户体验造成负面影响。本文将介绍如何优化表格的可访问性和用户体验,涵盖正确的 HTML 结构、表头和标题的使用、样式和布局、无障碍访问和移动优化。

一、正确的 HTML 结构

正确的 HTML 结构对于表格的可访问性至关重要。每个单元格都应该在一个<td>标签内,每行都应该在一个<tr>标签内,表头应该在一个<thead>标签内。此外,要确保每个单元格的<th>标签都在表头中使用,以便屏幕阅读器识别为表头。

<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Data 1</td>
      <td>Data 2</td>
    </tr>
    <tr>
      <td>Data 3</td>
      <td>Data 4</td>
    </tr>
  </tbody>
</table>

上面的示例展示了一个基本的 HTML 表格结构。表头在<thead>标签中,表格主体在<tbody>标签中,每个单元格都在<td>标签内,前两个单元格被标记为表头,使用了<th>标签。

二、使用表头和标题

使用正确的表头和标题可以让表格更容易理解和使用。<caption>标签可以用来为表格添加标题,而<th>标签可以用来指定每列的标题。这些技巧对于屏幕阅读器用户来说尤其有用。

<table>
  <caption>Sales figures for 2019</caption>
  <thead>
    <tr>
      <th>Product</th>
      <th>Sales</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Product A</td>
      <td>1000</td>
    </tr>
    <tr>
      <td>Product B</td>
      <td>500</td>
    </tr>
  </tbody>
</table>

上面的示例展示了一个带有标题和列标题的表格。<caption>标签指定了表格的标题,而每列的标题使用了<th>标签。

三、样式和布局

通过使用 CSS 样式和布局,可以使表格更具可读性和易用性。例如,可以使用斑马线条纹和悬停效果来突出每行和单元格,使表格更易于阅读。此外,可以使用媒体查询和响应式设计来优化表格在移动设备上的显示效果。

table {
  width: 100%;
  border-collapse: collapse;
}

th, td {
  padding: 8px;
  text-align: left;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

tr:hover {
  background-color: #ddd;
}

@media (max-width: 768px) {
  th, td {
    padding: 4px;
  }
}

上面的示例展示了一个简单的 CSS 样式和布局。表格被设置为 100% 的宽度,边框被合并,每个单元格都有 8 像素的内边距和左对齐对齐方式。奇数行具有淡灰色的背景色,当用户将鼠标悬停在表格上方时,会显示淡灰色。在移动设备上,单元格内边距被减少为 4 像素。

四、无障碍访问

为了使表格对于使用屏幕阅读器的读者更具可访问性,可以通过添加额外的 ARIA 属性来标记表格的状态和结构。例如,使用<th>元素的 scope 属性指定列标题和行标题的范围。使用aria-label来为表格添加额外的标签来描述表格内容。

<table aria-label="Sales figures for 2019">
  <thead>
    <tr>
      <th scope="col">Product</th>
      <th scope="col">Sales</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Product A</th>
      <td>1000</td>
    </tr>
    <tr>
      <th scope="row">Product B</th>
      <td>500</td>
    </tr>
  </tbody>
</table>

上面的示例展示了如何使用 aria-label 和 scope 属性。aria-label 属性为表格添加了描述性标签,scope 属性指定了列标题和行标题的范围。

五、移动优化

移动设备上的视图通常比传统桌面浏览器窄,因此,为了确保表格在移动设备上能够正常显示,应该使用响应式设计和移动优化技巧。其中一种方法是使用响应式表格插件,如 DataTables 或 Responsive Tables。

<table class="responsive">
  <thead>
    <tr>
      <th>Product</th>
      <th>Sales</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Product A</td>
      <td>1000</td>
    </tr>
    <tr>
      <td>Product B</td>
      <td>500</td>
    </tr>
  </tbody>
</table>

上面的示例展示了如何使用响应式表格插件。添加 class="responsive" 属性以启用响应式设计。通过这种方法,表格将自动调整大小以适应不同的屏幕大小和方向。

结论

通过正确的 HTML 结构、表头和标题的使用、样式和布局、无障碍访问和移动优化,可以优化表格的可访问性和用户体验。如果您正在构建一个拥有大量数据和信息的网站,那么正确的表格设计可以使信息更加清晰易懂,提高用户的满意度和可访问性。

如何优化表格的可访问性和用户体验

2023-05-12
如何优化网页的可访问性和用户体验

2023-05-12
when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: ${item.id} [in template "article/detail/index.ftl" at line 48, column 106] ---- Java stack trace (for programmers): ---- freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...] at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134) at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:481) at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:401) at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:370) at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:104) at freemarker.core.DollarVariable.accept(DollarVariable.java:63) at freemarker.core.Environment.visit(Environment.java:371) at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321) at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271) at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244) at freemarker.core.Environment.visitIteratorBlock(Environment.java:645) at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108) at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94) at freemarker.core.Environment.visit(Environment.java:335) at freemarker.core.Environment.visit(Environment.java:341) at freemarker.core.Environment.visit(Environment.java:341) at freemarker.core.Environment.process(Environment.java:314) at freemarker.template.Template.process(Template.java:383) at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:332) at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:266) at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:220) at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:181) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1431) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1167) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at com.software.filter.HttpSpiderIdentifyFilter.doFilter(HttpSpiderIdentifyFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at java.base/java.lang.VirtualThread.run(VirtualThread.java:309)