使用表单元素和CSS3代替JavaScript

发表评论 阅读评论

前几天加入天地会的译林军,看这篇关于HTML的文章不错就 翻译 过来了。后续我博客主题要修改就像HTML5方向发展了。请在Chrome,Firefox,safari及WebKit核心的浏览器里查看本篇文章里的demo。 自CSS3问世以来,浏览器对新特性的支持正在不断的改善,更多的开发者将使用一种独特的方式(不使用Javascript)将功能添加到网页。 最近两三年,一些开发使用表单元素添加功能,抛弃使用像JQuery类库这样的Javascript传统方式。 这篇文件将讲解其中的一些技术并讨论涉及的概念。这将会使你对于这些技巧的运作方式有个整体的了解,让你深入了解将来的纯CSS的web项目。

为什么要使用这些技术?

一些原因是这些技术将对你的代码有益。首先,任何额外的JavaScript使我们的网站更慢,因为你会添加更多的代码,在某些情况下,可能还需要为该页面加载外部资源(js)。再次,只使用CSS使得代码更干净并且更容易维护。使用好的注释将会非常容易的明白这些功能是如何工作的,以便做出必要的修改或改进。

提醒

事实是,在这篇文章中提到的技术可能不是很好的选择,因为表单元素的方式存在在语义和有效性方面的问题,使得效果不一定是期望的样子。 虽然这篇文章对于学习CSS具有一定的试验性和教育性,但请在这些技术在广泛的应用到任意项目之前考虑这些技术的不足之处。当然,如果你能保证规避这些不确定的问题的同时使用这些技巧,那么就做吧。但还是要事先警告,他们可能会有问题。

用单选按钮实现tab选项卡

许多网站都有选项卡切换的功能。简单的说这是一个独立的单元或小工具,有时会出现的网站的侧边栏,它有两个或更多的内容域供用户选择。在这些内容域中同时只有一个会被显示,并且有对应的tab标签会显示在该组件的顶端。 最老的教程和demo示例使用list,div及JQuery来创建该功能。但是在过去的两三年中,一些脚本和教程已经开始使用单选按钮和一些新的CSS3伪类来帮助实现该组件的tab标签部分。
让我们来看看怎样实现这些。我们的代码会被分成多个section,每一个section看起来可能像下面的这样:

<section class="tab">
    <input type="radio" id="tab-one" name="tab-set" checked>
    <label for="tab-one">Tab #1</label>
    <div class="tab-content">
    <p>First tab content goes here.</p>
    </div><!-- tab-content -->
</section><!-- .tab (1) -->

这可能需要重复三四次。然后我们可以使用一个class为“tab-switcher”的包装器(div)来协调显示所有section。这个片段的关键点是radio类型的input元素和其相关联的label元素。
这里是在JS Bin上的示例。选择CSS查看CSS代码。
JS Bin
在这篇文章中,为简洁起见省略了供应商的CSS3前缀(译者注;该demo包含CSS3前缀)。现在让我们考虑下该tab选项卡所涉及的概念。请注意,该demo没有使用任何Javascript。

隐藏单选按钮

虽然这个示例使用了单选按钮,但实际上我们没有看到任何单选按钮。这是因为在我们的CSS里把单选按钮设置为display:none,但是如果单选按钮在页面上没有显示,它是如何工作的呢?
好吧,请注意该片段包含一个label元素,该label使用for属性来关联到每一个单选按钮的id。虽然该单选按钮不显示也不可点击,但是其关联的label元素却可以。如果你熟悉lable,你就会知道浏览器允许通过点击label来选择其关联的表单元素。
因此,我们需要做一些样式相关的事情,从而让我们的label看起来像tab(我用的圆角和其他一些样式),然后对它们使用了:cheked伪类以及普通相邻选择器(波浪号字符~)。
普通相邻选择器让我们可以像label元素一样匹配到tab选项卡的内容部分。使用:checked配合相邻选择器,可以只匹配tab选项卡当前选中或激活的部分。
使用z轴配合绝对定位可以实现选择部分可见。在这个demo中,我天津了一些CSS3的变换效果,以防止不同tab切换的太快。

概念要点

请记住这些总结的技术要点。

  • 页面上的单选按钮不可见。
  • 任意label元素能被任意的表单元素所关联,并且可以在表单元素不可见的情况下通过该label来选中表单元素。
  • :cheked伪类结合普通相邻选择器可以让我们将选中的表单元素与目标元素相关联。

用多选框实现Accordion组件

再次,我们创建了一个常用的网页小部件,同时避免任何JavaScript 。这一次,我们创建了一个垂直的Accordion组件。 跟tab选项卡类似,我们将accordion的每一项使用HTML5的section元素表示。同样使用一个class为"accordion-wrap"的包装器将所有5项包裹住。每一项看起来像下面的代码片段:

<section class="accordion-item">
    <input type="checkbox" id="accordion-one" name="accordion-group" checked>
    <label for="accordion-one">Accordion Section #1</label>
    <div class="accordion-content">
        <p>content here... </p>
    </div><!-- .accordion-content -->
</section><!-- .accordion-item -->

实际上有5项,为简洁起见,这里只写一项。同样,关键点为复选框和相关的label元素。 我们的CSS是与前面的例子类似,我们再一次使用:checked伪类和普通相邻选择器。这里是 JS Bin 上的示例。选择CSS查看代码。
JS Bin

使用 max-height

本示例使用复选框,与单选按钮不同的是,复选框允许多个项被选定。这意味着accordion的不同项都可以同时展开。
tab选项卡的例子中使用透明和z轴相结合的方式实现选中项的显示。但是这次,我们使用max-height属性。任何未被选中的项被设置max-height为0,配合overflo:hidden,这样它们就不能被看见了。当一个项被选中时,我们为它设置一个比所有项的最大高度还要大的max-height值。
我们使用max-height属性而非height属性,因为虽然height可以通过CSS3做动画,但是动画不会从0到auto。因此我们不得不选择一个随意的max-height值,并确保该值比每一项展开来的实际高度还要大。(感谢Lea Verou的技术支持)(译者注:如果不需要动画,可以用height属性设置0和auto,而非max-height

概念要点

这是这这个例子中的关键点:

  • 多选框允许多个项被选中,通常模拟这个我们可能会使用Javascript。
  • 再次,我们使用label来触发选中,但是让多选框不可见。
  • 我们显示每一项的内容的动画是从max-height的0到一个足以包括最高项展开的高度。
  • 我们为选中状态到未选中状态使用不同的变换持续时间,就像 flexibilities 上的CSS3变换效果一样。

展示一个带焦点的文本框

最后一种技术是一个简单的表单按钮,当点击时,用动画显示一个输入文本。让我们先看看这个代码片段,这是一个很简单的例子。 <input

type="text" class="txt" id="textfield">
<label for="textfield">Click to Type</label>

这这个例子中,我们只用一个关联到label元素的文本框。请看下面的 JS Bin 上的例子。选择CSS查看相关代码。
JS Bin

使用:focus

在这个例子中,我们使用:focus伪类让文本表单可见。label元素的风格看上去像个按钮。它出现在文本框上面,所以文本框不能立刻可见。 然后我们使用超级方便的相邻选择器将动画添加到label元素的left属性。这样,移动label元素后就能看到文本框了。
请查看在 JS Bin 上的代码。

概念要点 总结下最后一个例子:

  • :focus伪类用来检测label的点击,这样就将焦点添加到了文本框。
  • label和决对定位的表单元素使用z轴来排列顺序。
  • 当用户输入时,CSS的变换动画根据left属性移动label。
  • 普通相邻选择器再次被用来匹配表单域相邻的元素。

Bugs,问题和提醒

如前所述,请认真思考这些技术后再使用。首先,老版本的WebKet有一个bug,不允许:checked结合相邻选择器一起工作。幸运的是,现在已经没有多少人在用旧版本的WebKit,因此这在现在不算问题了。
另一问题出现在ios5及更低版本的WebKit中,不逊于通过触摸一个label元素改变复选框的状态。解决办法是为所有的label元素添加一个空的内置onclick句柄。正如这篇文章里的demo一样。另外,iOS上对于通过点击label来触发输入框的状态改变的反应很慢。
然而,还有一个更重要的问题。事实上,这些标记在像屏幕阅读器这样的辅助技术设备上会有问题。请在引入像这里的方法前考虑这些易用性的问题。 这里已经在讨论使用纯CSS添加这类行为到原生元素的可能性,以防止这些bug和易用性的问题,但是这将有更远的路,并且很长一段时间这些将不能在所有浏览器中实现。

接下来干吗

要处理一些跨浏览器的问题,你可以尝试使用选择polyfill的间隙中填充像Selectivizr的,但你可能最终与车或不可预知的结果,和,除非你提供的动画polyfill ,否则转换失踪。
处理跨浏览器的问题,你可以尝试使用Selectivizr或ppolyfill选择器插件,但是可能有bug或者效果与预期不一致。当然可以用polyfill提供动画,否则转换失败。
正如引言中所提到的那样,如果你注意避免易用性问题,那么这些技术会是有用的。避免使用Javascript,网页会加载的更快,功能将不太可能滞后。简单的说,Html和CSS将更容易维护。
这篇文章中大部分的技术和灵感来源于一些开发者在工作中的积累。如果你要深入的研究这个主题,一定要查看下面的文章和demo。

标签: , , ,

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
回到顶部