这篇文章发布于 2016年11月12日,星期六,00:01,归类于 HTML相关。 阅读 41856 次, 今日 7 次 8 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=5730
本文可全文转载,个人网站无需授权,只要保留原作者、出处以及文中链接即可,任何网站均可摘要聚合,商用请联系授权。
一、双十一了
现在是2016年11月11日0点11分,大家都在忙着shopping,而对于我而言,正是工作效率最高的时间段,文章写起来~
二、HTML fieldset,legend元素与可访问性
注:本文可访问性部分的部分内容参考自这篇外文。
我们无论做什么产品,都不能只关注眼前那点东西,或者说肉眼所见的表层那点东西。尤其对于有相当用户基数的产品,无障碍访问和无障碍阅读一定要引起重视,否则,对产品的口碑会有严重的影响。
下面这张图是我之前在刷微博的时候看到的,是批评跟滴滴合并之后的uber中国在在无障碍访问这一块做得很糟糕:
看来评价者是相当的生气,好奇的我又去看了下滴滴出行APP的反馈,结果不看不知道一看吓一跳,对无障碍访问这一块的差评出乎意料的多,几乎全部都是1星,这口碑和评分妥妥地下去了,看来无障碍访问这一块做的确实很糟糕啊!
其实,如果你只要有一些基本的常识,按照文档规范本身语义去实现,并不要求你有多精通,基本的无障碍使用绝对是没有问题的。但是,像上面这样,被批得一无是处的,可见真的是一无是处。
我们做web开发的,也同样需要对无障碍阅读,可访问性等引起重视。
我们平常可能都听过“语义化”这个词,为什么HTML代码要语义化,除了代码可读性好以外,SEO有帮助外,最主要的还是对一些屏幕阅读设备或者其他辅助阅读设备友好,可以让用户在条件受限的条件下依然可以正常使用我们的产品,比方说鼠标坏了,又或者说视力有障碍的用户等等。
我们这里介绍两个HTML元素,fieldset
和legend
,可能有部分小伙伴没见过,说不定会认为是哪个新出的HTML标签,不是的哈,这两个标签在我在津津乐道看《樱桃小丸子》的时候就有了,主要用来form
表单中,给表单控件们分组用的。
我们先看一个例子,一个带有多个选择项的问题:
如果让小伙伴们来实现,基本上HTML都是下面这种套路:
<form> <p>你有港澳通行证吗?</p> <input type="radio" id="yes"> <label for="yes">有</label> <input type="radio" id="no"> <label for="no">没有</label> ... </form>
对于我们以视觉为主要感官的人来讲,上面的最终的视觉呈现是没有问题的,有问题,有单选。但是,由于我们的问题和下面的2个单选他们是有关联的,或者说带有“组”的关系。如果我们使用上述的HTML代码,就会带来一个什么问题呢?屏幕阅读设备就无法知道他们之间的关系,我们听到的仅仅是单选控件的label
元素中的“有”和“没有”这两个词,然后问题是什么可能永远都听不到。
对于普通元素,我们如果想让其有特定的可访问特性,可以使用WAI-ARIA中的API,关于ARIA我多年前话很多精力整理过,可参见“WAI-ARIA无障碍网页应用属性完全展示”,例如,你想使用div
标签模拟按钮,可能需要加个role="button"
。
虽然说ARIA是一种解决方法,但是,对于开发人员而言,学习成本啊什么的还是很麻烦的,对于盲人用户而言,要根据ARIA关键属性的引导来引导去,其实效率不太高,于是,还是喜欢使用tab键快速索引,这就导致上面的“你有港澳通行证吗?”被忽视掉,也无法和下面的“有”和“没有”联系上。
我自己使用VoiceOver测试了下,确实,标题内容是很难读取的,也可能是我用得不熟的原因,我发现要框选这段标题文字才会读音,但是,如果用户知道哪里可以框选,怕是也就不需要阅读设备了。
实际上,要修复上面的可访问性问题很简单,我们使用form表单中具有语义的fieldset
和legend
元素就可以了,如下:
<form> <fieldset> <legend>你有港澳通行证吗?</legend> <input type="radio" id="yes"> <label for="yes">有</label> <input type="radio" id="no"> <label for="no">没有</label> </fieldset> ... </form>
其中,fieldset
表示组的意思,专门用在form
表单元素中,表示一组内容,例如,我们填写收货地址的时候,省市区会有多个输入框后者下拉框,就可以使用fieldset
归为一组,legend
表示这个组的标题,在我们这里例子中,正好就是问题内容。
此时,你再使用tab键导航form
表单的时候,就会清晰读出问题“你有港澳通行证吗?”了,这样,用户就能清楚知道,下面的“有”和“没有”到底说的是什么鬼,就不会有困扰了。
注意:IE浏览器中,Jaws屏幕阅读器会读fieldset中每一个操作框的legend(而不是仅第一个),这其实是有问题的。(原文内容,未测试)
我使用VoiceOver测试了下使用fieldset
和legend
元素的表单,确实,读的内容是“组 你有港澳通行证吗? 2个选项”,这样显然更好理解。
当然,并不是说只要有表单就一定要使用fieldset
和legend
,那什么时候该使用,什么时候不该使用呢?
什么时候该使用fieldset
和legend
?
- 使用单选框或多选框的提问内容;
- 几个输入框使用的是同一个主题,例如,省市区3个下拉和最后详细地址输入框都是“地址”这个主题,此时,
legend
元素里面就可以是“收获地址”这样的文字,整个所有表单都套上fieldset
,例如:<form> <fieldset> <legend>双十一收货地址</legend> <label for="province">省:</label><select id="province"><option>上海市</option></select> <label for="city">省:</label><select id="city"><option>上海市</option></select> <label for="district">区:</label><select id="district"><option>浦东新区</option></select> <label for="address">详细地址</label> <input type="text" id="address"> </fieldset> ... </form>
什么时候不建议使用fieldset
和legend
?
- 单打独斗的表单控件元素们。
三、fieldset,legend元素在CSS布局中的应用
很多HTML标签抛开语义,就本身就一无是处了,比方说<p>
标签,本身没有任何特异性,也没有私藏的绝活。但是,<legend>
却不一样,其天生带有一种特殊的布局,在某些场合可以轻松实现一些效果。
我们先看下这种HTML原生的样式是怎样的:
如下HTML:
<fieldset> <legend>标题</legend> </fieldset>
效果如下(实时):
会看到,有一个方框框,但是这个框不是完全闭合的,有个开口,这个开口上面的就是<legend>
里面的文字。注意,这里有2个非常重要的点,第1个就是开口,也就是线并没有从文字下面穿过去,这个文字的背景看上去是白色的,实际上,咳咳,是透明的,再说一遍是透明的。类似这种效果,如果你想使用其他标签和CSS模拟,一般想到的就是用个背景色覆盖,使用背景色的问题在于,如果换了个背景,这个覆盖就穿帮了。而透明没有这种担忧,各种背景各个模块都可以自如地飞起来;第2个就是文字是压在线上的,传统的标签我们写个border
属性,里面的文字肯定是在border
里面的,但是,<legend>
偏不,直接压在线上,天然的,你还别说,如果用CSS来模拟这种效果,还真要下点成本的。
基本上,各个浏览器下都是这种框框开口标题文字的效果,我大致看了下,Firefox浏览器的最有质感(设一个深色背景,如下截图),IE就是个浅边框,在白色背景下效果不错,而Chrome浏览器的边框类型是groove
(沟槽)。
总而言之,各个浏览器各个系统下差异都不同,但是,注意但是,好在,我们通过特定的CSS代码设置,我们可以让表现保持一致。由于边框是<fieldset>
元素产生的,所以,我们可以设置:
fieldset { border: 1px solid #ddd; }
所有浏览器下,基本上效果就大统一了。
如果我们仅仅希望就上面有一条线,我们可以:
fieldset { border: 0 none; border-top: 1px solid #ddd; }
如果,我们希望<legend>
里面的文字居中对齐,而不是飘在左上角,则……说来话长。
首先,Chrome浏览器下,我们使用text-align:center
即可~
legend { text-align: center; }
IE浏览器,IE8+浏览器下可以使用margin:auto
:
legend { text-align: center; margin: auto; }
但是IE7和Firefox浏览器怎么办呢?告诉大家,经过我的反复尝试,几乎无解。有一种方法可以实现居中,那就是:
legend { width: 100%; }
但是,由于<legend>
元素的原始位置天然镂空下面的边框,因此,这种设置,会让<fieldset>
元素的上边框无法显示,我们使用这两个元素就是看上了上边框的覆盖和开口特性,如果被覆盖了那还使用个毛线啊。
兼容问题在眼前,难道就这么结束了?其实不是的,虽然CSS有些强弩之末的感觉,但是,毕竟这是上世纪就出现的HTML元素,因此,要想居中对齐,还要看HTML属性,如下设置:
<fieldset>
<legend align="center">标题</legend>
</fieldset>
效果如下(实时):
结果所有浏览器下一马平川,一路居中。
这跟type="file"
的<input>
需要size
控制宽度的尿性有些类似。
我们还可以设置线框的类型为虚线,例如:
fieldset {
border: 0 none;
border-top: 1px dashed #ddd;
}
但是,有个不幸的消息,在IE浏览器下,如果border-style
类型如果不是实线solid
,则边框线就会从标题内容下面穿过去,而不是镂空,如下截图:
我瞬间无言以对,而且所有IE浏览器都是这样,我内心呵呵一下。不过IE浏览器很淡定,因为黑色上面再抹点黑色是没有区别的。并且几乎无解。并且IE浏览器还不支持border-radius
圆角,需要<legend>
浮动后绝对定位或变成其他display
类型。
如果非对虚线或者点线念念不忘,我能想到的挫方法就是弄个背景色覆盖覆盖了。
然后,<fieldset>
和<legend>
元素组合使用的时候,<legend>
一定要是第一个子元素,并且是正常块状流。如果我们在<legend>
前面插入其他元素,则在Chrome和Firefox浏览器下,会忽略,视觉表现上会呈现在<legend>
的下面。
基本上总结下,如果你有文字压线的效果,使用<fieldset>
和<legend>
布局是成本最低的,标题想居中,使用align="center"
这个HTML属性,如果是实色边框,无论是solid
或者double
都可以自如使用,没有兼容性问题,但如果是虚线边框,则要考虑IE浏览器穿透的问题。
好了,说了那么多,我们当场演示一个妙用<fieldset>
和<legend>
元素低成本实现特殊布局的效果。什么效果呢?我写文章的时候,有时候会打上分隔线,写上文字示意这里有一段风格。我之前是使用字符实现的,类似“——————低调的分隔线———————-”,使用字符的问题在于,如果在手机上看,很可能字符换行了,就显得有点傻了。
有了<fieldset>
和<legend>
事情就简单多了,如下CSS和HTML:
fieldset {
border:0;
border-top:1px dashed #ccc;
}
legend {
color: #999;
/* for IE */
background-color: #fff;
}
<fieldset> <legend align="center">低调的分隔线</legend> </fieldset>
效果如下,是不是比之前实现要巧妙和清爽的多。
实际上,对于本例子,最好的实现是使用伪元素生成“低调的分隔线”这几个字,因为,这几个字实际上不属于文章内容的一部分。
四、结束语
本文时间跨度正好一整日,从开头看我的心情还不错,但是,写结束语的时候,心情哪,五味杂陈。
今天小马哥给腾讯的每个员工送了300股腾讯股票,算算6万多港币,想想自己,也就早走半年而已,再想想腾讯股票我160就卖掉了,而现在200多,更是哭晕在厕所。
不过现在好多了,因为老婆安慰我说:“没事,我们还有土可以吃!”想想也是,剁手节一过,很多人土都吃不起,顿时平衡了很多。
你还别说,土的味道还不错,要不,也给你来两份?
本文为原创文章,包含脚本行为,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=5730
(本篇完)
- 如何disabled禁用所有表单input输入框元素 (0.367)
- 拾人牙慧:不同浏览器如何渲染不同border-style值 (0.353)
- WAI-ARIA无障碍网页应用属性完全展示 (0.215)
- 基于VoiceOver的移动web站无障碍访问实战 (0.215)
- HTML5语音合成Speech Synthesis API简介 (0.164)
- span与a元素的键盘聚焦性以及键盘点击性研究 (0.160)
- 翻译-盲人如何使用互联网的8个误区 (0.160)
- 找到适合自己的前端发展方向 (0.105)
- 实力科普:为什么浮层或弹框一定要有叉叉关闭按钮? (0.105)
- HTML5按钮元素新属性formaction,formenctype等简介 (0.104)
- 妙法攻略:渐变虚框及边框滚动动画的纯CSS实现 (RANDOM - 0.024)
为什么 IETester上的 IE8测试有问题啊。。。不居中
>>我瞬间无言以对,而且所有IE浏览器都是这样,我内心呵呵一下。不过IE浏览器很淡定,因为黑色上面再抹点黑色是没有区别的。并且几乎无解。并且IE浏览器还不支持border-radius圆角,需要浮动后绝对定位或变成其他display类型。
—-现在遇到IE的这个问题,圆角设置后,加入legend就无法呈现,在firefox和chrome中没这个问题,怎么解?
legend的位置不是第一个子元素的时候,在ie浏览器下,legend之前的标签在视觉上没有被框住,而在其他浏览器(经测试火狐、谷歌)下,与legend是第一个子元素的情况无异,这个能否解决
一下更新三篇,好多。
作为一个新手,感觉本文最重要的就是提醒我们要注意语义化标签,有时候能用a标签,但是页面完成后,后台的要让我改成input标签;用背景图做完了,又要改成img标签。类似的情况还有一些,这里我不是很懂什么时候该用什么标签?
张老师,CSS代码里legend误写成了lengend
好的,感谢反馈。
老师你太棒啦
土已经吃不起了,张老师