我最近看到了 Ryan Seddon 关于 复选框可以做的事情 的演示。这让我思考了基于 URL 的类似伪选择器 :target
,以及如何将其用于隐藏和显示元素以节省空间(尤其是在较小的屏幕上)。我给自己设定了任务,利用强大的 CSS3 选择器和过渡效果,在不使用 JavaScript 的情况下重现 iOS 信息应用程序。
简单示例
以下代码示例显示了如何隐藏登录框和导航,并在需要时显示它们。
<header id="hd">
<a href="/" class="logo">Company logo</a>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">News</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<a href="#login">Log in</a>
<div id="login">
<fieldset>
<label for="username">Username:</label>
<input type="textbox" id="username">
<label for="password">Password:</label>
<input type="password" id="password">
<input type="submit" value="login"/>
<a href="/register">Sign up</a>
</fieldset>
</div>
</header>
<div id="bd">
<section>
<p>
... lorem ipsum content ...
</p>
</section>
<a href="#auxNav">Internal navigation</a>
<nav id="auxNav">
<ul>
<li><a href="#">First link</a></li>
<li><a href="#">Second link</a></li>
<li><a href="#">Another link</a></li>
</ul>
</nav>
</div>
body {
position: relative;
max-width: 960px;
margin: 0 auto;
}
#login {
position: absolute;
top: -200px;
right: 0;
-webkit-transition: top 0.3s ease-in-out;
-moz-transition: top 0.3s ease-in-out;
-ms-transition: top 0.3s ease-in-out;
-o-transition: top 0.3s ease-in-out;
transition: top 0.3s ease-in-out;
}
#bd {
position: relative;
overflow: hidden;
}
#auxNav {
position: relative;
overflow: hidden;
height: 60px;
}
#auxNav ul {
position: absolute;
left: -100%;
-webkit-transition: left 0.3s ease-in-out;
-moz-transition: left 0.3s ease-in-out;
-ms-transition: left 0.3s ease-in-out;
-o-transition: left 0.3s ease-in-out;
transition: left 0.3s ease-in-out;
}
/* The Magic Part */
#login:target {
top: 0;
}
#auxNav:target ul {
left: 0;
}
首先将导航和登录放在屏幕外,然后在 :target
上显示它们。请注意,锚链接的 href 属性“#auxNav”与导航的 ID“auxNav”匹配。
auxNav 显示我们不需要隐藏 ID 本身,而是可以隐藏其任何后代。
“应用程序”
每条消息(“屏幕”)都有一个 ID 并位于屏幕外。当单击锚链接时,URL 中的哈希链接会发生变化,:target
选择器会匹配,并显示相应的屏幕。

我使用 :checked
选择器来切换消息的编辑。列表中的每条消息都是其完整详细信息版本的锚点。只需少量代码 :target { left: 0; }
即可将其显示出来。
当选择编辑按钮时,隐藏的“删除”按钮会滑入。按钮文本通过 :before
伪元素中的 content
更改,而不是创建另一个元素来切换状态。“删除”消息按钮在选中时只需隐藏列表中的下一条消息。
然后,每条消息在 :target
选择器匹配时显示,从左侧滑入(从右侧过渡存在困难)。使用更复杂的复选框链来滑动每条线程中的复选框(同时稍微更改其尺寸)并显示底部的另一个复选框以确认删除。使用与之前相同的方法,通过 :checked + div { display: none; }
隐藏消息。
(演示在移动设备上有效,但更像是桌面体验——使其适合移动屏幕非常容易。)
优势
- 无需 JavaScript!
- 只需一个锚链接、ID 和一个简单的伪选择器即可实现此功能
- 不完全依赖于标记顺序。每个对象只需要一个 ID 或选择器中的 ID。例如:#hd:target nav
- 在不支持的情况下回退到锚点
- 自动滚动到元素,因此不需要固定位置
缺点/问题
- 仅在从左侧定位时才能进行进出过渡,其他元素仅在离开
:target
后才会过渡 - 屏幕上只能显示一个元素
- 使用右侧偏移完全使 Chrome 混乱,会错误地显示最后一个 ID 作为目标
结论
我一直对我们仅使用标记和 CSS 就能创建什么感兴趣。虽然这是一种技巧,可能不适合生产环境,但至少它表明,如果设备/用户缺少 JavaScript,我们不必在设计或交互性方面做出妥协,并且可以回退到简单地将所需元素滚动到视图中。
相关链接
- Aaron Gustafson:无需技巧构建智能移动导航
- Luke Wroblewski:多设备布局模式
- Brad Frost:响应式导航模式
不错的演示,但有几点需要注意
– android 2.1 不支持 ~ 选择器(与 :checked 一起使用)(“导航/侧边栏在哪里?”)(+ 受支持)
– 目标和后退按钮(历史记录)可能会对最终用户造成一些“奇怪”的行为(
在演示中,由于固定位置的标题,不会使用后退按钮,但固定和移动…在“真实”网站上,这可能会导致一些麻烦,对于侧边栏而言比导航栏更多)
很棒,尤其是 :checked 的链式操作,让我大开眼界!
非常感谢 Chris 和 Matty 分享如此精彩的演示。 :)
不错的文章,我会仔细研究一下,因为我也喜欢 HTML 与一些不错的 CSS 功能相结合来实现功能的简单性。
由于
:target
的支持似乎有点参差不齐,使用 jQuery scrollTo 或 CSS 动画是否更好?我更倾向于使用 jQuery 为导航分配一个类并使用 CSS 过渡,但它可以用于增强移动非 JS 用户的体验。对于不支持
:target
的情况,理想情况下应该有一个回退方案,但是如何在没有 JavaScript 的情况下找出这一点?……我不确定。不错……我会尝试一下。
这太酷了!
你的另一篇好文章,Chris。我一定会从中获得一些启发。谢谢!
这是一种非常酷的技术,不幸的是,在实践中,我发现许多这样的非常精巧的 CSS 技术都略显不足。例如,在 Android 4.0 上,点击消息原始消息列表通常无法将对话显示出来。
根据我的经验,支持高级选择器和过渡的浏览器也支持 jQuery。虽然 jQuery 会增加页面的一些重量,但我发现它更可靠。
尽管如此,这仍然是一个有趣的回退和练习,对此我表示感谢。
这确实是一种非常有趣的方法,但正如其他人所说,
:target
的可靠性不足以使其变得实用。我怀疑(没有任何证据支持)JavaScript 的可用性更广泛,因此更实用。我更倾向于使用 JavaScript 来添加/移除类,使用原生 CSS 过渡,并在 JavaScript 不可用的情况下提供备用方案。我确信这在某些设备上仍然会失效,但它看起来相当可靠。
话虽如此,我真的很喜欢这种想法和文章。我总是对其他设计师和开发人员的创造力感到非常钦佩。
我喜欢它支持使用 Magic Mouse 滑动在消息和收件箱之间切换。这个支持来自哪里?
谢谢 Chris,不错的演示