×
Create a new article
Write your page title here:
We currently have 21 articles on Topicalballs Wiki. Type your article name above or click on one of the titles below and start writing!



Topicalballs Wiki

MediaWiki:SpoilerTags.css

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
:root {
    --spoiler-tags-loaded: 1;
	--spoiler-hide-color: rgba(0, 0, 0, 0.75);
	--spoiler-hover-color: rgba(var(--theme-page-text-color--rgb), 0.1);
	--spoiler-show-color: rgba(var(--theme-page-text-color--rgb), 0.1);
    /*
	--spoiler-hide-color: red;
	--spoiler-hover-color: yellow;
	--spoiler-show-color: green;
    */
    --spoiler-tooltip-color: var(--theme-page-background-color--secondary);
    --spoiler-tooltip-text-color: var(--theme-page-text-color);
    --spoiler-tooltip-text: /* Purposefully empty */;
    --spoiler-image-button-color: rgba(0, 0, 0, 0.75);
    --spoiler-image-button-text-color: #ebebeb;
    --spoiler-image-button-text: /* Purposefully empty */;
    --spoiler-image-blur: 20px;
}

/*
    When JS is disabled, we don't want spoiler content to remain inaccessible.
    One option is to conditionally import the CSS, but then it takes longer
    for SpoilerTags to take effect (plus you'll get flicker on the page).

    This is why every rule below is prefixed with .client-js. A bit excessive,
    but it's better than a whole bunch of overrides. In the future this should
    be replaced with nested CSS
*/

.client-js span.spoiler,
.client-js div.spoiler span {
    padding: 2px 0;
    border-radius: 2px;
    transition-property: background-color, color, opacity;
    transition-duration: 0.3s;
    position: relative;
}


/* === Inline spoilers === */


/* Spoiler and direct descendants when unspoiled */
.client-js span.spoiler:not(.spoiled),
.client-js span.spoiler:not(.spoiled) > span {font-style: normal;
    background-color: var(--spoiler-hide-color);
    color: transparent;
    cursor: pointer;
}

/* Spoiler and all descendants on hover */
.client-js body:not(.spoiler-hover-disabled) span.spoiler:not(.spoiled):hover,
.client-js body:not(.spoiler-hover-disabled) span.spoiler:not(.spoiled):hover span,
.client-js body:not(.spoiler-hover-disabled) span.spoiler:not(.spoiled).hovered,
.client-js body:not(.spoiler-hover-disabled) span.spoiler:not(.spoiled).hovered span {
    background-color: var(--spoiler-hover-color);
}

/* Spoiler when spoiled */
.client-js span.spoiler.spoiled {
    background-color: var(--spoiler-show-color);
}

/* Anything within an inline spoiler should not be coloured
or able to be clicked on while their parent is unspoiled */
.client-js span.spoiler > *:not(.spoiler) {
    transition: opacity 0.3s;
}

.client-js span.spoiler:not(.spoiled) > *:not(.spoiler) {
    opacity: 0;
    pointer-events: none;
}

.client-js span.spoiler.spoiled > *:not(.spoiler) {
    opacity: 1;
}


/* === Block spoilers === */

/* The importants are to ensure that more specific styles (set on the
block itself or on the child elements) never override the spoiler.
We can't predict what users are going to place in the spoiler,
we just want it to work in every case regardless and without artificially
increasing the specificity */

.client-js .spoiler-block {
    transition-property: background-color, color, box-shadow;
    transition-duration: 0.3s;
    position: relative;
}

.client-js .spoiler-block:not(.spoiled) {
    background-color: var(--spoiler-hide-color) !important;
    color: transparent !important;
    cursor: pointer;
}

.client-js body:not(.spoiler-hover-disabled) .spoiler-block:not(.spoiled):hover {
    background-color: var(--spoiler-hover-color) !important;
}

.client-js .spoiler-block:not(.spoiled) > * {
    opacity: 0 !important;
    pointer-events: none;
}

.client-js .spoiler-block.spoiled > * {
    opacity: 1 !important;
    transition: opacity 0.3s;
}

/* === Spoiler image === */

.client-js .spoiler-image,
.client-js .spoiler-blur {
    position: relative;
    width: fit-content;
    display: block;
}

.client-js .spoiler-image:before,
.client-js .spoiler-blur:before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(var(--spoiler-image-blur));
}

.client-js .spoiler-image:after,
.client-js .spoiler-blur:after {
    content: var(--spoiler-image-button-text);
    position: absolute;
    top: 50%;
    left: 50%;
    width: max-content;
    max-width: calc(100% - 6px);
    transform: translate(-50%, -50%);
    padding: 0.2em 0.75em;
    border-radius: 1em;
    color: var(--spoiler-image-button-text-color);
    background-color: var(--spoiler-image-button-color);
    text-align: center;
    word-break: break-all;
    font-weight: 500;
}

.client-js .spoiler-image[data-image-button-text],
.client-js .spoiler-blur[data-image-button-text]
.client-js .spoiler-gallery[data-image-button-text] {
    --spoiler-image-button-text: attr(data-image-button-text);
}

.client-js .spoiler-image:before,
.client-js .spoiler-image:after,
.client-js .spoiler-blur:before,
.client-js .spoiler-blur:after {
    transition-property: opacity;
    transition-duration: 0.3s;
    z-index: 1;
}

.client-js body:not(.spoiler-hover-disabled) .spoiler-image:not(.spoiled):hover:before,
.client-js body:not(.spoiler-hover-disabled) .spoiler-image:not(.spoiled):hover:after,
.client-js body:not(.spoiler-hover-disabled) .spoiler-blur:not(.spoiled):hover:before,
.client-js body:not(.spoiler-hover-disabled) .spoiler-blur:not(.spoiled):hover:after {
    filter: brightness(1.05);
}

.client-js .spoiler-image:not(.spoiled):before,
.client-js .spoiler-image:not(.spoiled):after,
.client-js .spoiler-blur:not(.spoiled):before,
.client-js .spoiler-blur:not(.spoiled):after {
    cursor: pointer;
    opacity: 1.0;
}

.client-js .spoiler-image.spoiled:before,
.client-js .spoiler-image.spoiled:after,
.client-js .spoiler-blur.spoiled:before,
.client-js .spoiler-blur.spoiled:after {
    opacity: 0.0;
    pointer-events: none;
}

/* === Text selection === */


/* Use globally-set variable by default */
.client-js body.spoiler-selection-disabled span.spoiler:not(.spoiled),
.client-js body.spoiler-selection-disabled span.spoiler:not(.spoiled) > span,
.client-js body.spoiler-selection-disabled div.spoiler:not(.spoiled) span,
.client-js body.spoiler-selection-disabled .spoiler-block:not(.spoiled),
.client-js body.spoiler-selection-disabled .spoiler-blur:not(.spoiled) {
    user-select: none;
}


/* === Selection highlights === */

.client-js span.spoiler:not(.spoiled)::selection,
.client-js span.spoiler:not(.spoiled) *::selection,
.client-js div.spoiler:not(.spoiled) *::selection,
.client-js .spoiler-block:not(.spoiled)::selection,
.client-js .spoiler-block:not(.spoiled) *::selection {
    
    /* Ensure that text-selecting the spoiler doesn't reveal it */
    color: transparent;
    
    /* But still allow the user to see the selection */
    /* (If a background-color is not set, it will be transparent) */
    background-color: Highlight;
}


/* === Tooltips === */

/* Disable tooltips when:
- Globally disabled
- The data-tooltip attribute is "" or "" */

.client-js .spoiler-tooltips-disabled :is(.spoiler, .spoiler-block):after,
.client-js .spoiler-tooltips-disabled :is(.spoiler, .spoiler-block):before,
.client-js :is(.spoiler, .spoiler-block):is([data-tooltip="false"], [data-tooltip=""]):after,
.client-js :is(.spoiler, .spoiler-block):is([data-tooltip="false"], [data-tooltip=""]):before {
    display: none;
}

.client-js .spoiler:after,
.client-js .spoiler:before,
.client-js .spoiler-block:after,
.client-js .spoiler-block:before {
    position: absolute;
    z-index: 100;
    opacity: 0;
    transition: margin-bottom 0.15s ease, opacity 0.15s ease;
    pointer-events: none;
}

.client-js .spoiler:after,
.client-js .spoiler-block:after {
    content: var(--spoiler-tooltip-text);
    height: 25px;
    line-height: 25px;
    padding: 0 5px;
    font-family: inherit;
    font-weight: normal;
    font-style: normal;
    font-size: 12px;
    text-align: center;
    color: var(--spoiler-tooltip-text-color);
    background-color: var(--spoiler-tooltip-color);
    border-radius: 2px;
    box-shadow: 0 0 5px rgba(0,0,0,0.3);
    white-space: nowrap;
    box-sizing: border-box;
    left: 0;
    bottom: 100%;
}

.client-js .spoiler:before,
.client-js .spoiler-block:before {
    content: "";
    width: 0;
    height: 0;
    left: 10px;
    bottom: calc(100% - 6px);
    border-width: 6px;
    border-style: solid;
    border-color: var(--spoiler-tooltip-color) transparent transparent transparent;
    margin-bottom: -5.5px;
    transition-duration: 0.1s;
}

/* Show tooltip and use text from style when using "true" */
.client-js .spoiler:is([data-tooltip="true"], [data-tooltip=""]):after,
.client-js .spoiler-block:is([data-tooltip="true"], [data-tooltip=""]):after {
    content: var(--spoiler-tooltip-text);
}

/* Use attribute when neither of the above */
.client-js .spoiler[data-tooltip]:not([data-tooltip=""], [data-tooltip="false"], [data-tooltip="true"]):after,
.client-js .spoiler-block[data-tooltip]:not([data-tooltip=""], [data-tooltip="false"], [data-tooltip="true"]):after {
    content: attr(data-tooltip);
}

/* Show tooltip on hover when not spoiled */
.client-js body:not(.spoiler-hover-disabled) .spoiler:not(.spoiled):hover:after,
.client-js body:not(.spoiler-hover-disabled) .spoiler:not(.spoiled):hover:before,
.client-js body:not(.spoiler-hover-disabled) .spoiler-block:not(.spoiled):hover:after,
.client-js body:not(.spoiler-hover-disabled) .spoiler-block:not(.spoiled):hover:before {
    opacity: 1;
}

.client-js .spoiler:not(.spoiled):hover:after,
.client-js .spoiler-block:not(.spoiled):hover:after {
    margin-bottom: 5.5px;
}

.client-js .spoiler:not(.spoiled):hover:before,
.client-js .spoiler-block:not(.spoiled):hover:before {
    margin-bottom: 0.5px;
}

/* Hide the tooltips of spoilers that are nested within other spoilers */
.client-js .spoiler:not(.spoiled) .spoiler:after,
.client-js .spoiler:not(.spoiled) .spoiler:before {
    opacity: 0 !important;
}


/* === Spoil all button === */


.spoil-all-button {
    position: relative;
}

.spoil-cross-icon {
    position: absolute;
    background-color: currentColor;
    border-radius: 2.5px;
    width: 2.5px;
    height: 18px;
    transform: rotate(-45deg);
    opacity: 0;
    transition: opacity 0.2s;
}

/*
The spoil icon does double duty as showing the current state, and the target
state when hovering. So:
- If spoilers are hidden a crossed eye is shown. If we hover over the button, it
shows an eye, indicating that clicking the button will make the spoilers visible.
- If spoilers are shown, an eye is shown. If we hover over the button, it shows a
crossed eye, indicating that clicking the button will hide the spoilers.

/* Show the crossed eye only when all spoilers are spoiled and we hover over the icon
or if any spoilers are unspoiled and we're not hovering over the icon */
.spoil-all-button.spoiled:not(.disabled):is(:hover, :focus, :focus-within) > .spoil-cross-icon,
.spoil-all-button:not(.spoiled, :hover, .disabled) > .spoil-cross-icon,
.spoil-all-button:not(.spoiled).disabled > .spoil-cross-icon {
    opacity: 1;
}

.spoil-all-button.spoiled > .spoil-settings-button:hover + .spoil-cross-icon,
.spoil-all-button:not(.spoiled, .disabled):is(:focus, :focus-within) > .spoil-cross-icon {
    opacity: 0;
}

.spoil-all-button:not(.spoiled, .disabled) > .spoil-settings-button:hover + .spoil-cross-icon {
    opacity: 1;
}

.spoil-all-button.disabled {
    pointer-events: none;
}

.spoil-all-button.disabled > .spoil-eye-icon,
.spoil-all-button.disabled > .spoil-cross-icon {
    color: var(--theme-accent-color--hover);
}

.spoil-settings-button {
	/* Reset default <button> styles. */
	appearance: none;
	background: none;
	border: none;
	color: inherit;
    cursor: pointer;
	padding: 0;
    /* We make the outline transparent and not hidden so it still
	** displays itself in high-contrast mode. */
	outline: 2px solid transparent; 

    position: absolute;
    top: -2px;
    right: 0;
    transition: transform 0.1s cubic-bezier(0.22, 0.61, 0.36, 1);
    transition-delay: 0s;
    transform: scale(0);
    pointer-events: all;
}

.spoil-all-button:is(:hover, :focus) > .spoil-settings-button,
.spoil-all-button > .spoil-settings-button:focus {
    transition-delay: 0.35s;
    transform: scale(1);
}


/* === Spoiler settings === */


.spoilerOptionsDialog .oo-ui-window-body {
    font-size: 15px;
}

.spoilerOptionsDialog .oo-ui-window-content.oo-ui-processDialog-content .oo-ui-window-body {
    padding: 0;
}

.spoilerOptionsDialog .oo-ui-popupWidget-popup {
    font-size: 13px;
    padding: 14px;
}

.spoiler-fieldLayout.oo-ui-layout.oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
    width: 90%;
    width: fit-content;
    flex-grow: 0;
}

.spoiler-fieldLayout.oo-ui-layout.oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-inline-help {
    font-size: 11px;
    padding-left: 1em;
}

.spoiler-fieldLayout.oo-ui-layout.oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help {
    align-self: center;
}

.spoiler-fieldLayout.oo-ui-layout.oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
    width: 10%;
    margin-left: auto;
}

.spoiler-fieldLayout .oo-ui-inline-help {
    color: var(--theme-page-text-color--hover);
}