Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS selector for anchor element using document fragment

Consider the following sample code

<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>

I can select the section that is selected with

section {
    background: #fff;
}

section:target {
    background: #f00;
}

But I want to target the a that selected it using only HTML/CSS, which I could imagine being like

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

or

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

The only solution I could come up with is

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;
}

I don't like this, however, because it introduces needless elements (the divs to target).

Is there a clean way to do this without JavaScript?

like image 896
quittle Avatar asked Apr 06 '15 00:04

quittle


People also ask

How to append a document fragment to an array in HTML?

How it works: 1 First, select the <ul> element by its id using the querySelector () method. 2 Second, create a new document fragment. 3 Third, for each element in the languages array, create a list item element, assign the list item’s innerHTML to the... 4 Finally, append the document fragment to the <ul> element. More ...

What are the basic CSS selectors?

This page will explain the most basic CSS selectors. The element selector selects HTML elements based on the element name. The id selector uses the id attribute of an HTML element to select a specific element.

What happens when selectors are incorrectly used in HTML?

If the selector matches an ID and this ID is erroneously used several times in the document, it returns the first matching element. If the selectors specified in parameter are invalid a DOMException with a SYNTAX_ERR value is raised.

How do I get the first element in a documentfragment?

The DocumentFragment.querySelector () method returns the first element, or null if no matches are found, within the DocumentFragment (using depth-first pre-order traversal of the document's nodes) that matches the specified group of selectors.


1 Answers

While the :target pseudo-class exists for matching a named anchor or an element with an ID corresponding to the current URL fragment, CSS does not provide a selector for matching links that point to the current URL fragment.

There is no clean way to do this without JavaScript. I would heavily prefer using JavaScript over polluting the markup with unsemantic elements and invalid attributes for the sake of accommodating CSS (section elements cannot have name attributes).

The hashchange event is well-supported, so if you can afford it it's simply a matter of listening for that event and toggling a class on the right element:

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>
like image 190
BoltClock Avatar answered Sep 30 '22 13:09

BoltClock