Actions

Work Header

Rating:
Archive Warning:
Fandom:
Additional Tags:
Language:
English
Series:
Part 1 of Site Skins and CSS Quackery
Collections:
References for writing, HTML & CSS stuffs
Stats:
Published:
2022-09-09
Completed:
2025-06-25
Words:
16,702
Chapters:
25/25
Comments:
527
Kudos:
557
Bookmarks:
630
Hits:
27,151

How to Block Tags With Site Skins (And Get Real Specific About It)

Summary:

Just some info I've gathered over the past couple of weeks, about how to:
1. Block tags using Site Skins, block only fics that contain both tag A and tag B, and block fics with a tag that contains a certain phrase, unless they are a specific whitelisted tag
2. Highlight the tags in pretty colors! Or bold, or hide them!
3. Block mega-crossovers with a million different fandoms
4. Select for/block fics that are completed/rated something/have a certain category/don't have summaries
5. Block everything that doesn't have a certain tag, or one of a list of tags
6. Block orphan_account and tag block by author
7. Block only tags of specific types (fandoms, relationships, freeforms, etc.)
8. Block fics focused on original characters, and/or fics without any tags of a specific type
9. Block every pairing with two characters in it—case insensitive, any order, no matter how many other people are also in the tag
10. Block by number of tags

Notes:

If any of this doesn't work correctly, or doesn't cover a specific situation that you'd like it to, please don't hesitate to ask. No guarantees I'll be able to figure it out, but I am rapidly developing an obsession with creating hyper-specific site skin filters, so I'm happy to chew on a problem for a while!

(See the end of the work for other works inspired by this one.)

Chapter 1: has(), not(), and how to chain them together

Chapter Text

Overview

So for a while there actually wasn't a way to filter out tags using site skins. That changed with the rollout of something called the has() selector. It's not available in all browsers, unfortunately, and in some you may have to manually enable it. Permablocking Specific Tags by Eli0t is a great resource for learning how to do that, it's what led me down this rabbithole in the first place. I did my best to explain how the has() selector works before I get into how to chain them together and stuff, but that link will probably do a better job.

(Also, quick disclaimer that while I am studying Computer Science, I have never learned any CSS in a formal way and 100% of what I'm about to write is from some combination of repeating what other people taught me over Ao3, Googling around, and literally just trying stuff to see what happened. So I may horribly butcher terminology and/or do terrible things that make web developers who actually know CSS violently angry at me.)


First and foremost: what is the has() selector and what does it do?

From what I understand, the has() selector is a way of telling your site skin to do something to every element (in this case, fic) that "has" whatever is in the parentheses. In the case of tag blocking, that's a link to that tag's page on Ao3.

*Important note for Firefox users: a lot of these filters rely on the :has() selector, which isn't enabled on Firefox by default. To turn it on, you can go to "about:config" and search for the setting "layout.css.has-selector.enabled". Setting that to true should enable the :has() selector!

First thing's first: if you haven't messed around in the CSS part of the site skins before, you can navigate to it by hitting the "Write Custom CSS" button in the editor, like so:

"Write Custom CSS button"

Now, say you want to select the tag Blorbo Baggins/Steve. First thing you'll want to do is right click on that tag, click "copy URL", and paste it into the CSS part of your site skin.

You should get something like this:

https://archiveofourown.org/tags/Blorbo%20Baggins*s*Steve/works

(Something you'll want to keep in mind is that *s* is used in place of slashes, *a* in place of the & that marks platonic relationships, and %20 in place of spaces in these links.)

Then you're going to want to cut off the "https://archiveofourown.org" part, to get:

/tags/Blorbo%20Baggins*s*Steve/works

Now, you pop it into the has selector, like so:

.blurb:has(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"])

Once you've got a tag selected, you can do a few things.

This chunk of code will turn the text on all Blorbo/Steve fics blue, which can be super helpful if you want a quick way to make sure your selection is working correctly.

.blurb:has(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"]) {

  color: blue;

}

While this chunk of code will hide any fic tagged with Blorbo Baggins/Steve:

.blurb:has(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"]) {

  display: none !important;

}

Or if you really like the ship, you can highlight it with pretty colors in the background like so:

.blurb:has(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"]) {

  background: linear-gradient(135deg, rgb(199, 199, 255), rgb(240, 160, 210));

}

This highlighting feature is super neat, and I learned about it from Highlight comments of your favourite readers! by ElectricAlice, which also explains how to highlight things with solid colors and even images! I've been using it to highlight authors that I've already bookmarked a bunch of times, so I notice when I run across something new from them in my searches.


More General Filters

Okay. So you can filter out specific tags! But what if, as an example, you don't like any romantic pairings with Blorbo Baggins in them? What do?

See the dollar sign?

.blurb:has(a[href$=""])

If you swap it out with a star, like so:

.blurb:has(a[href*=""])

Then it will filter out any tag that contains whatever you stick in the quotation marks. For instance, if you want to select every single tag (including both the character tag "Blorbo Baggins" and the freeform tag "BAMF Blorbo Baggins") that has Blorbo in it at all, you might do something like this:

.blurb:has(a[href*="Blorbo%20Baggins"])

Or this:

.blurb:has(a[href*="Blorbo"])

(The second one will catch fics whose authors didn't add his last name to their character tag, but you may run the risk of accidentally grabbing fics about his similarly named archnemesis Blorbo Blobbington as well.)

Also, with the way Ao3 ship tags are (usually) formatted, you can get rid of every (correctly tagged) romantic pairing with just two lines:

.blurb:has(a[href*="*s*Blorbo%20Baggins"]),

.blurb:has(a[href*="Blorbo%20Baggins*s*"]) {

  display: none !important;

}

Since we've disallowed tags that contain "/Blorbo Baggins" or "Blorbo Baggins/", it should catch any romantic pairing with him in it.

(It won't, because unfortunately with the way these selectors work, if somebody tagged something "Blorbo Baggins / Steve" you're out of luck unless you also block that tag. But that's pretty rare at least!)


Chained has() Selectors

So this is the part where I went rogue and started messing around. And as it turns out: you can chain the has selectors together!

For example: say you're looking for a romance fic featuring Blorbo Baggins/Steve, but you have very strong opinions about ship dynamics and don't ever want to read anything in that ship with the tag Top Blorbo Baggins. You could filter out "Top Blorbo", but then you would suffer the tragic loss of your second favorite ship dynamic, which is the combination of Blorbo Baggins/Brad and Top Blorbo Baggins.

Fortunately, you don't have to choose! You just have to glue two has() selectors together with a colon like so:

.blurb:has(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"]):has(a[href*="Top%20Blorbo"]) {

  display: none !important;

}

This will get rid of any of those pesky Top Blorbo/Steve fics, while leaving all the rest for you to read.

As far as I can tell, you can just keep chaining these together. So if you've been incredibly irked by an unbelievably specific combination of 10 or so tags, you can now get rid of it!

This is especially nice because as far as I know there isn't a way to do this using Ao3's search function—you can filter out tags, or include them, but I don't think you can filter out works that have two tags without also blocking works that have only one of them.


The not() Selector

Okay, cool. But suppose you're a Blorbo Baggins/Steve purist. You absolutely do not want to see Blorbo with anyone else, but you can't block all of his relationship tags because then you wouldn't get the pairing you actually want! Is the only option to go through and block every single other ship?

No! There's also another selector called not(), which after some trial and error does actually let you be extremely specific about what you're blocking.

So we start with what we had before, when we wanted to block every ship with Blorbo in it:

.blurb:has(a[href*="*s*Blorbo%20Baggins"]),

.blurb:has(a[href*="Blorbo%20Baggins*s*"]) {

  display: none !important;

}

And the tag we want to allow, Blorbo Baggins/Steve, will go into a not() selector like so:

not(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"])

Now it's just a matter of chaining them together like this:

.blurb:has(a[href*="*s*Blorbo%20Baggins"]),

.blurb:has(a[href*="Blorbo%20Baggins*s*"]:not(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"])) {

  display: none !important;

}

Note that the first half of the rule can be left alone—Blorbo Baggins comes before Steve alphabetically, so he should be first in the ship tag. But if you want to specifically allow the Steve/Blorbo Baggins tag as well, you can do that the same way, just like this:

.blurb:has(a[href*="*s*Blorbo%20Baggins"]:not(a[href$="/tags/Steve*s*Blorbo%20Baggins/works"])),

.blurb:has(a[href*="Blorbo%20Baggins*s*"]:not(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"])) {

  display: none !important;

}

You will unfortunately probably block some fics that are tagged with Blorbo/Steve and similar, but that should hopefully only make you miss out on a handful of fics.

Note: Be careful to put the not() selector inside the parentheses for the has() selector. I tried it the other way around first and it didn't work.

Also: as I understand it, the site skin will check each tag, and will select the fic if any of them satisfy one of your selectors. This means that if a fic is tagged both Blorbo Baggins/Steve and Blorbo Baggins/Brad, it will be filtered—not because of the first tag, but because of the second. So you aren't whitelisting all fics tagged Blorbo Baggins/Steve, but just the tag Blorbo Baggins/Steve. I say this because I've gotten confused about it myself and wound up with weird behavior from my filters. It also foiled my initial attempts to make a whitelisting system that blocks everything that isn't tagged with Blorbo Baggins/Steve, but I might mess around more later to see if I can figure that out.

Edit: After some recent experimenting, the not selectors can also chain together. If you like Blorbo/Steve and Blorbo/Brad but want to filter out all other Blorbo ships, you can double up the whitelisted Blorbo/ tags like so:

.blurb:has(a[href*="Blorbo%20Baggins*s*"]:not(a[href$="/tags/Blorbo%20Baggins*s*Steve/works"]):not(a[href$="/tags/Blorbo%20Baggins*s*Brad/works"])) {

  display: none !important;

}

And I need to do a little more testing on this but I'm fairly sure you could exempt, say, poly pairings including both Blorbo and Steve from a filter like so:

.blurb:has(a[href*="Blorbo%20Baggins*s*"]:not(a[href*="Steve"])) {

  display: none !important;

}


The Sad Part (And How To Fix It)

Good news and bad news. The bad news? In my experience (with my specific browser, which is firefox), these tag blockers stop working if you try to put too many of them in your site skin at once. Mine seem to break down after roughly 10-20ish.

The good news? You can get around that (in my specific browser, mileage may vary on this one)! It just involves making a whole lot of small site skins and then adding them as parents of your main one, which is slightly annoying but can lend itself to some nice organization if you're so inclined.

First thing you'll want to do is to create a "face" (at least that's what I've been calling it) that will be your main site skin that you use. Let's say you're me, and you're naming it after the color you made the heading: Indigo. My "Indigo (Face)" site skin doesn't have anything in the CSS window at all, just some colors I put into the wizard to make things look pretty.

Now, I can create a new site skin called Indigo (Blocked Tags). (You could call it "Potato Party" if you want, I'm just using this system because it's a little easier to explain what's going on. Though I did run into problems when I tried to use a parent skin with the & symbol in its name, so you may want to avoid those.)

In the CSS window of my Blocked Tags skin, I can put 10 or so blocked tags and save it. Then I can open up the editor of my Face skin. First, I need to make sure I'm in the CSS view. Then I can scroll down to the very bottom of the CSS window. There should be something called "Advanced" with a "Show" button. (Forgive my janky MS Paint diagrams)

Show Advanced Button

I can click that, and scroll down some more until I get to the tab called "Parent Skins", and click "Add Parent Skin".

Add Parent Skin button

From there I search for my Blocked Tags skin, and add it as a parent. Now, when I'm using my Face skin, it will block all the tags that my Blocked Tags skin does.

These can keep stacking indefinitely, as far as I can tell. So if you're as rabid as I am and you find yourself wanting to block all 50 some-odd synonyms to a tag you hate, let's say "Blorbo Baggins Bashing," you could make a skin called "Blorbo Bashing Filter" and give it 5 parent skins, each blocking 10 of those tag synonyms, and then make that a parent of your Face skin.

This is also useful if you have some tags that you might want to block sometimes, but that you won't necessarily always want to filter out. They can live in their own little site skin, which can be popped on and off of your Face skin at will, depending on how picky you're feeling!