使用文档片段的锚元素的CSS选择器

时间:2015-04-06 00:39:22

标签: html css html5 css3 css-selectors

考虑以下示例代码

<body>
    <nav>
        <a href="#s1">First Section</a>
        <a href="#s2">Section 2</a>
    </nav>
    <main>
        <section id="s1">
            <p>Example paragraph
            <p>Paragraph 2
        </section>
        <section id="s2">
            <p>Example paragraph
            <p>Paragraph 2
        </section>
    </main>
</body>

我可以选择使用

选择的section
section {
    background: #fff;
}

section:target {
    background: #f00;
}

但我想定位使用 HTML / CSS选择它的a,我可以想象它就像

a[href=:target] {
    font-weight: bold;  
}

a:target(href) {
    font-weight: bold;
}

我能提出的唯一解决方案是

HTML:

<body>
    <div id="s1"><div id="s2">
        <nav>
            <a href="#s1">First Section</a>
            <a href="#s2">Section 2</a>
        </nav>
        <main>
            <section name="s1">
                <p>Example paragraph
                <p>Paragraph 2
            </section>
            <section name="s2">
                <p>Example paragraph
                <p>Paragraph 2
            </section>
        </main>
    </div></div>
</body>

CSS:

#s1:target a[href="#s1"],
#s2:target a[href="#s2"] {
    font-weight: bold;
}

section {
    background: #fff;
}

#s1:target section[name="s1"],
#s2:target section[name="s2"] {
    background: #f00;
}

然而,我不喜欢这样,因为它引入了不必要的元素(div来定位。)

没有JavaScript,有没有一种干净的方法可以做到这一点?

2 个答案:

答案 0 :(得分:3)

虽然存在:target伪类用于匹配命名锚或具有与当前URL片段对应的ID的元素,但CSS不提供用于匹配指向当前URL片段的链接的选择器。 / p>

没有JavaScript,没有干净的方法可以做到这一点。我更倾向于使用JavaScript而不是为了容纳CSS而使用非语义元素和无效属性来污染标记(section元素不能具有name属性。)

hashchange事件是well-supported,所以如果你能负担得起,只需要听一下这个事件并在正确的元素上切换一个类:

var navLinks = document.querySelectorAll('nav > a');

window.onhashchange = function() {
    for (var i = 0; i < navLinks.length; i++) {
        if (navLinks[i].href.match(/(#.*)/)[1] == window.location.hash) {
            navLinks[i].className = 'selected';
        } else {
            navLinks[i].className = '';
        }
    }
};

var navLinks = document.querySelectorAll('nav > a');

window.onhashchange = function() {
    for (var i = 0; i < navLinks.length; i++) {
        if (navLinks[i].href.match(/(#.*)/)[1] == window.location.hash) {
            navLinks[i].className = 'selected';
        } else {
            navLinks[i].className = '';
        }
    }
};
section {
    background: #fff;
}

section:target {
    background: #f00;
}

a.selected {
    font-weight: bold;
}
<nav>
    <a href="#s1">First Section</a>
    <a href="#s2">Section 2</a>
</nav>
<main>
    <section id="s1">
        <p>Example paragraph
        <p>Paragraph 2
    </section>
    <section id="s2">
        <p>Example paragraph
        <p>Paragraph 2
    </section>
</main>

答案 1 :(得分:0)

基于 BoltClock 代码,适用于 2021 年:

window.addEventListener("hashchange", event => {
    document.querySelectorAll("nav > a").forEach(link => {
        if (new URL(link).hash == new URL(event.newURL).hash) {
            link.classList.add("selected");
        } else {
            link.classList.remove("selected");
        }
    });
});

您可能还想在加载时进行设置

for (const link of document.querySelectorAll("nav > a")) {
    if (new URL(link).hash == location.hash) {
        link.classList.add("selected");
        break;
    }
};