视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
纯CSS的导航栏Tab切换方案
2020-11-27 18:54:04 责编:小采
文档


不用 Javascript,使用纯 CSS 方案,实现类似下图的导航栏切换:

CSS 的强大之处有的时候超乎我们的想象,Tab 切换,常规而言确实需要用到一定的脚本才能实现。下面看看如何使用 CSS 完成同样的事情。

实现 Tab 切换的难点在于如何使用 CSS 接收到用户的点击事情并对相关的节点进行操作。即是:

如何接收点击事件

如何操作相关DOM

下面看看如何使用两种不同的方法实现需求:

法一::target 伪类选择器

首先,我们要解决的问题是如何接收点击事件,这里第一种方法我们采用 :target 伪类接收。

:target 是 CSS3 新增的一个伪类,可用于选取当前活动的目标元素。当然 URL 末尾带有锚名称 #,就可以指向文档内某个具体的元素。这个被链接的元素就是目标元素(target element)。它需要一个 id 去匹配文档中的 target 。

解释很难理解,看看实际的使用情况,假设我们的 HTML 代码如下:

 
  • 列表1
  • 列表2
  • 列表1内容:123456 列表2内容:abcdefgkijkl

    由于要使用 :target,需要 HTML 锚点,以及锚点对应的 HTML 片段。所以上面的结构要变成:

     
  • 列表1
  • 列表2
  • 列表1内容:123456 列表2内容:abcdefgkijkl

    这样,上面 中的锚点 #content1 就对应了列表1 。锚点2与之相同对应列表2。

    接下来,我们就可以使用 :target 接受到点击事件,并操作对应的 DOM 了:

    #content1,
    #content2{
     display:none;
    }
     
    #content1:target,
    #content2:target{
     display:block;
    }

    上面的 CSS 代码,一开始页面中的 #content1 与 #content2 都是隐藏的,当点击列表1触发href="#content1" 时,页面的 URL 会发生变化:

    1.由 www.example.com 变成 www.example.com#content1

    2.接下来会触发 #content1:target{ } 这条 CSS 规则,#content1 元素由 display:none 变成display:block ,点击列表2亦是如此。

    如此即达到了 Tab 切换。当然除了 content1 content2 的切换,我们的 li 元素样式也要不断变化,这个时候,就需要我们在 DOM 结构布局的时候多留心,在 #content1:target 触发的时候可以同时去修改 li 的样式。

    在上面 HTML 的基础上,再修改一下,变成如下结构:

    列表1内容:123456
    列表2内容:abcdefgkijkl
    
     
  • 列表1
  • 列表2
  • 仔细对比一下与上面结构的异同,这里我只是将 ul 从两个 content 上面挪到了下面,为什么要这样做呢?

    因为这里需要使用兄弟选择符 ~ 。

    E~F{ cssRules } ,CSS3 兄弟选择符(E~F) ,选择 E 元素后面的所有兄弟元素 F。

    注意这里,最重要的一句话是 E~F 只能选择 E 元素 之后 的 F 元素,所以顺序就显得很重要了。

    在这样调换位置之后,通过兄弟选择符 ~ 可以操作整个 .nav 的样式。

    #content1:target ~ .nav li{
     // 改变li元素的背景色和字体颜色
     &:first-child{
     background:#ff7300;
     color:#fff;
     }
    }
    #content2:target ~ .nav li{
     // 改变li元素的背景色和字体颜色
     &:last-child{
     background:#ff7300;
     color:#fff;
     }
    }

    上面的 CSS 规则中,我们使用 ~ 选择符,在 #content1:target 和 #content2:target 触发的时候分别去控制两个导航 li 元素的样式。

    至此两个问题,1. 如何接收点击事件 与 2. 如何操作相关DOM 都已经解决,剩下的是一些小样式的修补工作。

    法二: &&

    上面的方法通过添加 标签添加页面锚点的方式接收点击事件。

    这里还有一种方式能够接收到点击事件,就是拥有 checked 属性的表单元素, 或者

    假设有这样的结构:

    
     
    
     
  • 列表1
  • 对于上面的结构,当我们点击 单选框表单元素的时候,使用 :checked是可以捕获到点击事件的。

    .nav1:checked ~ .nav li {
     // 进行样式操作
    }

    同样用到了兄弟选择符 ~

    这样,当接收到表单元素的点击事件时,可以通过兄弟选择符 ~ 操作它的兄弟元素的样式。

    但是,这里有个问题 我们的 Tab 切换,要点击的是

  • 元素,而不是表单元素,所以这里很重要的一点是,使用
  • 元素,而
  • 中,有一层
  • 元素的时候,相当于点击了 这个单选框表单元素,而这个表单元素被点击选中的时候,又可以被 :checked 伪类捕获到。

    这个时候,我们就可以将页面上的表单元素隐藏,做到点击

  • 相当于点击表单:

    input{
     display:none;
    }

    这样,应用到本题目,我们应该建立如下 DOM 结构:

     
     
     
     
  • 列表1内容:123456 列表2内容:abcdefgkijkl

    使用两个单选框,分别对应两个导航选项,运用上面介绍的 label 绑定表单,:checked 接收点击事件,可以得到第二解法。

    下载本文
  • 显示全文
    专题