44

There's a whole bunch of unfixed issues with the way spoilers are implemented in the Stack Exchange CSS:

Perhaps the biggest issue is that the styling is wildly inconsistent between sites, and so are the bugs in it. Some bugs only appear on beta sites, while other bugs appear on SO, but not on beta sites.

Besides, the whole approach currently used for spoiler hiding — that is, styling everything inside spoilers to look like the background, and then restyling it on :hover to look normal again — is fundamentally backwards, and will keep generating bugs as the spoiler styles inevitably fail to keep up with changes to other styles.

It should be possible to fix all these issues at once by scrapping the current spoiler styles and replacing them with something more reliable and maintainable. I have suggested two such options in my own answers below, and I also welcome any alternative suggestions.

Note that this bug report is specifically about the CSS styling of spoiler blocks. It's not meant to cover the various known issues with Markdown parsing inside spoilers, nor issues with spoiler visibility on mobile devices. Those are separate bugs, and need separate fixes.

2

2 Answers 2

25

My suggestion is to scrap the whole set of spoiler styles currently in use, and replace them with the following:

.spoiler > * {
    opacity: 0;
    transition: opacity 0.5s ease-in;
    /* + optional vendor prefix variants for old browsers */
}
.spoiler:hover > * {
    opacity: 1;
}

Note: To make this work 100% reliably, the content of each spoiler <blockquote> should be wrapped in an extra <div> to make sure that all text content inside the spoiler has at least one enclosing element between it and the <blockquote>. (This would also let the > * selector be replaced with > div.) Most of the time, this will not matter, but there are some rare corner cases in current Markdown parsing that apparently can lead to text nodes being placed as direct children of the spoiler <blockquote>.

The styles above will:

  • reliably reproduce the current behavior of spoilers on SE beta sites and other sites using a "modern" variant of the SE CSS, complete with fade-in/out effects, but without the various bugs described above;

  • work reliably on all Stack Exchange sites, regardless of how blockquotes and other elements are styled on each site; and

  • degrade safely and gracefully on old browsers that may not support the CSS opacity or transition attributes.

The one feature of the current spoiler implementation that the method described above doesn't support is the ability to view spoiler text by selecting it. However, since spoiler visibility can now be toggled by clicking, this should no longer be an issue.


Edit: I've included this fix in v1.6 of the Stack Overflow Unofficial Patch, a collection of miscellaneous client-side bugfixes for the Stack Exchange sites packaged as a user script.

For technical reasons, what the user script does is define a new class soup-spoiler, style it as described above, and dynamically replace the class name spoiler with soup-spoiler on any elements that have it. The main reason I'm doing it this way is so that I won't have to try to "reset" all the existing SE spoiler styles before applying my own; given the wide variation in current spoiler styles across the network, this would be very difficult to do reliably.

The main drawback of this method is that, while the page is loading, spoilers may briefly appear styled with the original SE styles before the fix kicks in. To mitigate this issue, I've also included some specific CSS-only fixes for the worst problems in the current spoiler styles, as mentioned in the request above.

3
  • I suggested essentially the same thing in <meta.codegolf.stackexchange.com/questions/1331/…> yesterday, the chief difference being I cargo-culted an extra "transition" from the current CSS.
    – SamB
    Commented Mar 25, 2014 at 16:48
  • Oh, and mine has "visibility", too, in case of older browsers. Except I screwed it up ...
    – SamB
    Commented Mar 25, 2014 at 16:59
  • This has been fixed for a while, pretty much as you suggested.
    – Shog9
    Commented Jan 4, 2019 at 21:02
3

Alternatively, if the ability to view spoiler text by selecting it is considered to be of critical importance, the existing spoiler styles could be replaced with something like the following:

.spoiler, .spoiler * {
    transition: all 0.5s ease-in;
}
.spoiler:not(:hover), .spoiler:not(:hover) * {
    /* change these to match the blockquote background color on each site */
    color: #eee;
    background: #eee;
    border-color: #eee;
}
.spoiler:not(:hover) img {
    visibility: hidden;
    opacity: 0;
}

The main disadvantages of this alternative are that:

  • the color values need to be tailored to each site;

  • it only works on browsers that support the CSS :not selector (but does degrade gracefully on those that don't);

  • either it needs to be included at the very end of the style sheet, or the color / background / border-color / opacity attributes may need to be marked with !important to ensure that they'll override any other matching styles; and

  • it's possible that there may be other attributes that also need to be set in order to properly hide some elements inside spoilers on some sites.

Generally, I feel that this approach is a lot more fiddly and error-prone than the opacity-based one, but it does solve its one major shortcoming compared to the current implementation.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .