使用HTML和CSS编写无JavaScript的Todo应用

本文作者:IMWeb zzbozheng 原文出处:IMWeb社区 未经同意,禁止转载

用css实现一个todo应用程序,但不是TodoMVC那样的设计,它不使用JavaScript,而是所有的交互都是由CSS驱动的。

他是怎样实现的?简单来说:它使用预渲染HTML,CSS兄弟组合器(~),CSS计数器和:checked,:target和所需的伪选择器的组合。 这篇文章的其余部分将会更详细的介绍。

具有的功能:

  • 添加todo item(可达50条)
  • 标记已完成的item
  • 删除item
  • 筛选已完成的item和未完成的item
  • 显示未完成的items数量
  • 不允许添加空的item

并不具有的功能:

  • 页面重载后并没有数据持久性
  • 不能一次性标记所有item为已完成
  • 不通通过按Enter键来创建项目

通过:checked的伪类来实现显示和隐藏内容

为了实现应用程序可交互,我们需要一些方法来存储和修改状态,然后在CSS中做出反应。 但通常情况下,该状态将保存在HTML中,但是没有JavaScript,我们无法修改DOM结构。

为了解决这个问题,我们可以使用复选框表单字段来存储状态,然后使用:checked 伪类选择器访问该状态。

Toggle content: <input type="checkbox"></input>
<div id="content">
  Hello world!
</div>

<style>
  #content {
    display: none;
  }
  input:checked ~ #content {
    display: block;
  }
</style>

以上代码也使用了CSS通用兄弟选择器:~。 它匹配我们检查输入的所有以下兄弟姐妹 - 在这种情况下,我们要显示或隐藏的div。这也意味着CSS可以用于控制所有的item显隐状态。

我们知道HTML标签label的属性,允许我们定位和切换与复选框本身无关的按钮。再来看一段代码:

<input type="checkbox" id="toggle-box"></input>
<label for="toggle-box">Toggle!</label>
<div id="content">
  Hello world!
</div>

更大范围地实现显示或隐藏功能

现在我们有办法存储状态了,每个待办事项都有三个复选框来存储状态:

  • 该item是否被创建
  • 该item是否被标记已完成
  • 该item是否被删除

可能会给你一个线索如何应用程序将工作。 没有JavaScript,我们无法修改DOM。 这意味着所有的todo item都必须是初始页HTML的一部分。 如果您查看页面的源码,您会发现它已经包含50个预渲染的待办事项。

.todo#todo-1
    input.created-checkbox
    .todo#todo-2
        input.created-checkbox
        .todo#todo-3
            ...

以下是应用的部分html截图

个人待办事项如下所示:

我们来看看如何实现删除功能。 首先我们有一个复选框来存储删除的状态:

<input type="checkbox" class="deleted-checkbox" id="deleted-checkbox-3">

需要一个删除按钮

<label for="deleted-checkbox-3" class="deleted-checkbox-label">×</label>

If the checkbox is :checked we want to hide all parts of that item. But since each todo item contains all following todo items we have make sure to keep the next .todo visible. 如果该复选框是:checked,我们要隐藏该项目的所有部分。 但是由于每个待办事项包含其他的item,那我们还需要确保保持下一个.todo是可见的。

.deleted-checkbox:checked ~ :not(.todo) {
    display: none !important;
}

为了相对简单一些,复选框首先位于item的DOM中。因此,所有可见的UI可以通过~选择器来匹配。

根据完成状态来过滤item

TodoMVC可以让您选择只查看已完成或未完成的待办事项。我们也可以使用复选框来实现这一点,但是使用URL哈希更简洁些。

<a class="filter-active" href="#/active">Active</a>

When you click on the link the browser will scroll to the element with the id /active 当你点击该链接后,页面会滚动定位到id为/active的元素上。但更重要的是,此时该元素已经匹配了伪类:target

<div id="/completed" class="completed-filter">
    <!-- Todo items -->
</div>

我们可以匹配未完成的子项,并将其隐藏。

.completed-filter:target
    .created-checkbox:checked
    ~ .done-checkbox:not(:checked)
    ~ .todo-input {
    display: none !important;
}

所以,除了复选框,我们还可以在URL中存储和访问状态!

在顶部输入完毕时,在底部添加todos

将最后一个未完成的item目移动到列表的顶部,其位置为:absolute,并显示“添加”按钮。

计算未完成item条数

CSS有一个可爱的功能,称为计数器。我们可以通过他来计算出与CSS选择器匹配的item数量。我们可以用它来显示剩下几个todos。

body {
    counter-reset: items-left;
}
.created-checkbox:checked
    ~ .deleted-checkbox:not(:checked)
    ~ .done-checkbox:not(:checked)
    ~ .items-left-counter-helper {
    counter-increment: items-left;
}
#items-left:before {
    content: counter(items-left);
}

我们可以统计:

  • 被创建的item数量
  • 未被删除的item数量
  • 未完成的item数量

为什么我们是统计.items-left-counter-helper的数量,而不是计算.mark-undone-checkbox-label? 之前有尝试过,但是CSS计数器不计算被隐藏的元素,所以当筛选出已完成的item时(因为所有未完成的项目都不可见),会看到未完成的item总数量值为0。

防止用户创建空item

这里我们用到一个伪类选择器:required! HTML具有基本的表单验证功能。 例如,我们可以给一个文本输入框标记为必填:

<input required type="text" value="" class="todo-input">`

然后,我们可以使用CSS来检查该字段是否已被填写,是否是有效值:

input:not(:valid) ~ .created-checkbox-label {
    pointer-events: none;
}

使用pointer-events,我们可以禁用鼠标交互,例如单击或悬停。

最后

尽管这个应用远达到不完美,但对于CSS的伪类的灵活运用值得我们学习。

参考资料: http://www.mattzeunert.com/2017/10/30/javascript-free-todo-app.html#showing-and-hiding-content-with-the-checked-pseudo-selector 应用: http://www.mattzeunert.com/TodoCSS/#/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯社交用户体验设计

高清ICON SVG解决方案(下) - 腾讯ISUX

1551
来自专栏谦谦君子修罗刀

React Native备课笔记Day01一、React Native介绍二、特点分析三、推荐网站以及运行第一个react native项目四、环境搭建五、React Native文件结构六、View

(本节包括React Native介绍、特点分析、环境搭建、RN文件结构、View组件讲解、FlexBox布局及props与state) 一、React Nat...

33311
来自专栏数据小魔方

动态图表9|组合框(名称管理器)

今天要跟大家分享的是动态图表9——组合框(名称管理器)! 其实看过最近8篇推送的小伙伴儿大概都能看出来了,我所讲的动态图表制作技巧是沿着这样的思路来的: 数据有...

3828
来自专栏更流畅、简洁的软件开发方式

能自己“跑”的表单控件,思路,雏形,源码。vs2005版本

下载地址:  http://www.cnblogs.com/jyk/archive/2008/07/29/1255891.html 大家是怎么处理CRUD的呢?...

1929
来自专栏用户2442861的专栏

Chrome开发者工具不完全指南:(三、性能篇)

 卤煮在前面已经向大家介绍了Chrome开发者工具的一些功能面板,其中包括Elements、Network、Resources基础功能部分和Sources进阶功...

1082
来自专栏Danny的专栏

&nbsp在IE和FireFox中显示不一致

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

913
来自专栏知无涯

前端必看!各大浏览器 CSS Hack 收集

36413
来自专栏小程序之家

如何使用小程序表单组件

上一篇文章中,我们给大家介绍了小程序的视图容器及基础内容组件,该组件主要应用是输出内容。接下来这篇文章中,我们将继续介绍小程序最常用的表单组件,该组件主要应用是...

1973
来自专栏搞前端的李蚊子

基于Vue.js的大型报告页项目实现过程及问题总结(二)

距离上一篇文章过去了二十多天了,期间一直想把第二部分写完,结果在测试过程中遇到了各种坑爹的问题,到今天才算基本完成,也许还有后续,但趁着今天有时间就写出来吧,也...

42710
来自专栏iOSDevLog

scetch入门 第3部分:符号和导出谢谢阅读!

符号非常适合组织您经常重复使用的设计元素。在这个例子中,让我们将袜子猴子图标变成符号。选择图标后,查看顶部菜单栏并选择“创建符号”

690

扫码关注云+社区