ZhuTango

使用伪类 :target 小技巧

原文链接: bitsofco.de

伪类:target是指用来匹配文档(页面)的URI中某个标志符的目标元素。举个例子,这段文档被包在一个有ID为#target-test的元素下。如果你跳转到该url[https://bitsofco.de/the-target-trick#target-test] (https://bitsofco.de/the-target-trick#target-test),这时这个元素将会是目标并且该元素的伪类:target 的样式会生效。

去年,我写了一个关于伪类:target的文章:5 Lesser Used CSS Selectors(有些相关的用例)。我提到的有个关于伪类:target的例子是去高亮显示被引用到的页面的一部分。例如在例子中添加背景颜色或者边框来高亮显示。

但是最近我想到我们可以把伪类 :target放到更有用的地方,即在不用javascript的情况下在页面中实现交互。

Example 1 - 隐藏或者显示内容

一个简单的应用是用伪类:target 去显示和隐藏目标内容。举个例子,在博客中我们可能不想在我们点击前显示评论内容。要达成这个目的我们可以用:target

<a href="#comments">Show Comments</a>

<section id="comments">  
    <h3>Comments</h3>
    <!-- Comments here... -->
    <a href="#">Hide Comments</a>
</section> 

#comments:not(:target) {
    display: none;
}
#comments:target {
    display: block;
} 

Demo of Hiding & Showing Content using :target

演示例子

Example 2 - 一个滑动抽屉导航

另一个用例是创建一个滑动抽屉导航。我们可以固定窗口的导航栏来保证我们在点击打开时不会跳来跳去。

#nav {
    position: fixed;
    top: 0;
    height: 100%;
    width: 80%;
    max-width: 400px;
}

#nav:not(:target) {
    right: -100%;
    transition: right 1.5s;
}

#nav:target {
    right: 0;
    transition: right 1s;
} 

Demo of A Slide-Out Navigation Drawer using :target

演示例子

Example 3 - 一个弹出的Modal窗口

更进一步,我们可以创建一个modal窗口来铺满整个页面。

#modal-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0,0,0,0.8);
    display: flex;
    justify-content: center;
    align-items: center;
}

.modal {
    width: 70%;
    background: #fff;
    padding: 20px;
    text-align: center;
}

#modal-container:not(:target) {
    opacity: 0;
    visibility: hidden;
    transition: opacity 1s, visibility 1s;
}

#modal-container:target {
    opacity: 1;
    visibility: visible;
    transition: opacity 1s, visibility 1s;
} 

Demo of A Pop-Up Modal using :target

演示例子

Example 4 - 更改全局样式

最后的例子,可能语意不太准确,可以用来用到:target元素本身,来重新定义其样式或者改变其布局。

#body:not(:target) {
    main { width: 60%; }
    aside { width: 30%; }
    .show-sidebar-link { display: none; }
}

#body:target {
    main { width: 100%; }
    aside { display: none; }
    .hide-sidebar-link { display: none; }
} 

Demo of Changing Global Styles using :target

演示例子

这个是否语义化并可理解的?

我提及的 Anchors vs Buttons,当一个元素被用到,浏览器希望使用者被用到不同的页面或者页面总不同的部分。在这些例子中(不包括最后一个),这个是自然发生的。唯一的技巧是要被改变样式的目标元素可以动态的显示或者隐藏。

据我所知,这个方法有两个潜在的问题。

  1. 这种改变URL会影响到用户浏览器的浏览历史。这以为这如果用户用“返回”功能,可能会无意的导航到目标元素上。

  2. 要“关闭”目标元素,使用者需要被导航到另一个元素或者只用“#”。我用到了自己的例子中的后边的一种,不是十分的语义化并且会导致使用者跳转到页面的最顶端,而目标元素并不在那里。

尽管如此,如果正确的使用,我相信这个方法会是在不用javascript的情况下的一个备用的交互方法。在一些例子中,就像我的第一个例子,这个会比用javascript更合适更简单。当然,这个要基于具体情况而定。