YouTube No Saturated Hover

Removes YT's saturated hover effects.

2025/10/29のページです。最新版はこちら

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         YouTube No Saturated Hover
// @namespace    https://greasyfork.org/users/1476331-jon78
// @match        *://*.youtube.com/*
// @run-at       document-start
// @grant        none
// @version      1.0
// @description  Removes YT's saturated hover effects.
// @license      CC0
// ==/UserScript==

(() => {
  "use strict";

  const ID = "no-saturated-hover";
  let styleEl, dark, fixTimer, rafPending, obs;

  const detectDark = () => {
    const html = document.documentElement;
    if (html.hasAttribute("dark") || html.classList.contains("dark-theme")) return true;
    if (html.hasAttribute("light") || html.classList.contains("light-theme")) return false;
    const bg = getComputedStyle(html).getPropertyValue("--yt-spec-base-background").trim();
    if (bg.startsWith("rgb(")) {
      const [r, g, b] = bg.match(/\d+/g).map(Number);
      return (r + g + b) / 3 < 60;
    }
    return false;
  };

  const css = d => `
/* Use YT vars first, custom values only as fallback */
html {
  --yt-spec-base-background: var(--yt-spec-base-background, ${d ? "#0f0f0f" : "#fff"});
  --yt-spec-additive-background: var(--yt-spec-additive-background, ${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"});
  --yt-spec-text-primary: var(--yt-spec-text-primary, ${d ? "#f1f1f1" : "#0f0f0f"});
  --yt-spec-text-secondary: var(--yt-spec-text-secondary, ${d ? "#aaa" : "#606060"});
}

/* Disable hover effect */
.yt-spec-touch-feedback-shape__hover-effect,
.yt-spec-touch-feedback-shape__stroke,
.yt-spec-touch-feedback-shape__fill {
  display:none!important;opacity:0!important;pointer-events:none!important;
}

/* Titles & descriptions */
.yt-lockup-metadata-view-model__title,
.yt-lockup-metadata-view-model__title a,
ytd-watch-metadata #description,
ytd-video-secondary-info-renderer #description {
  color:var(--yt-spec-text-primary, ${d ? "#f1f1f1" : "#0f0f0f"})!important;
}

/* Video titles on hover */
#video-title:hover,
.yt-lockup-metadata-view-model__title a:hover {
  color:var(--yt-spec-text-primary, ${d ? "#f1f1f1" : "#0f0f0f"})!important;
}

/* Homepage metadata stays secondary color */
#metadata-line span,
ytd-rich-item-renderer #metadata-line span,
.yt-core-attributed-string--link-inherit-color {
  color:var(--yt-spec-text-secondary, ${d ? "#aaa" : "#606060"})!important;
}

/* Watch page description and snippet text stays primary, except call-to-action links */
ytd-watch-metadata #description,
ytd-watch-metadata #description .yt-core-attributed-string--link-inherit-color,
#snippet-text,
#snippet-text .yt-core-attributed-string--link-inherit-color,
#attributed-snippet-text,
#attributed-snippet-text .yt-core-attributed-string--link-inherit-color {
  color:var(--yt-spec-text-primary, ${d ? "#f1f1f1" : "#0f0f0f"})!important;
}

/* Preserve call-to-action links color inside watch metadata */
ytd-watch-metadata .yt-core-attributed-string__link--call-to-action-color,
#snippet-text .yt-core-attributed-string__link--call-to-action-color,
#attributed-snippet-text .yt-core-attributed-string__link--call-to-action-color {
  color: var(--yt-spec-call-to-action, #3ea6ff)!important;
}

/* Reset saturation variables to base YT vars */
ytd-watch-metadata,.ytd-watch-metadata {
  --yt-saturated-base-background: var(--yt-spec-base-background, ${d ? "#0f0f0f" : "#fff"});
  --yt-saturated-raised-background: var(--yt-spec-additive-background, ${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"});
  --yt-saturated-additive-background: var(--yt-spec-additive-background, ${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"});
  --yt-saturated-text-primary: var(--yt-spec-text-primary, ${d ? "#f1f1f1" : "#0f0f0f"});
  --yt-saturated-text-secondary: var(--yt-spec-text-secondary, ${d ? "#aaa" : "#606060"});
  --yt-saturated-inverted-background: var(--yt-spec-additive-background, ${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"});
  --yt-saturated-overlay-background: var(--yt-spec-additive-background, ${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"});
}

/* Remove video highlighted backgrounds */
ytd-rich-item-renderer.ytd-rich-item-renderer-highlight {
  background:transparent!important;box-shadow:none!important;--yt-spec-outline:transparent!important;
}

/* Hover cleanup */
a:hover,.yt-simple-endpoint:hover {filter:none!important;opacity:1!important;}

/* Description link */
.yt-core-attributed-string--highlight-text-decorator {
  background-color:var(--yt-spec-static-overlay-background-light, ${d ? "rgba(255,255,255,0.102)" : "rgba(0,0,0,0.051)"})!important;
  border-radius:8px!important;padding-bottom:1px!important;
}`.trim();

  const applyStyle = d => {
    if (!(styleEl = document.getElementById(ID))) {
      styleEl = document.createElement("style");
      styleEl.id = ID;
      document.head.append(styleEl);
    }
    styleEl.textContent = css(d);
  };

  const fixHighlights = () => {
    const expected = dark ? "rgba(255, 255, 255, 0.102)" : "rgba(0, 0, 0, 0.051)";
    document.querySelectorAll(".yt-core-attributed-string--highlight-text-decorator").forEach(el => {
      if (el.style.backgroundColor !== expected) el.style.backgroundColor = expected;
    });
  };

  const scheduleFix = () => {
    if (rafPending) return;
    rafPending = true;
    requestAnimationFrame(() => {
      rafPending = false;
      clearTimeout(fixTimer);
      fixTimer = setTimeout(fixHighlights, 60);
    });
  };

  const refresh = () => {
    const d = detectDark();
    if (d !== dark) { dark = d; applyStyle(d); }
    scheduleFix();
  };

  const init = () => {
    dark = detectDark();
    applyStyle(dark);
    scheduleFix();
    addEventListener("yt-navigate-start", refresh, { passive: true });
    addEventListener("yt-navigate-finish", refresh, { passive: true });
    addEventListener("yt-dark-mode-toggled", refresh, { passive: true });
    obs = new MutationObserver(scheduleFix);
    obs.observe(document.documentElement, { attributes: true, attributeFilter: ["dark", "light", "class"] });
    addEventListener("pagehide", () => obs.disconnect(), { once: true });
  };

  document.head ? init() : addEventListener("DOMContentLoaded", init, { once: true });
})();