使用 CSS :target 实现屏幕外设计

Avatar of Matty Collins
Matty Collins 发表于

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

以下是 Matty Collins 的客座文章。Matty 联系我分享了他制作的一个小演示,该演示重现了在 iPhone 上使用信息应用程序的体验。也许比重现该 UI 更有趣的是,该技术非常简单,不需要 JavaScript(“复选框技巧”),并解决了小屏幕上一个经常遇到的难题:如何处理导航?我问 Matty 他是否愿意撰写一篇客座文章,他欣然同意了。

我最近看到了 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,我们不必在设计或交互性方面做出妥协,并且可以回退到简单地将所需元素滚动到视图中。

相关链接