title: Invert text color on mouse hover
body: <p>I'd like to invert a black text while hovering it with a custom -black- cursor.
  This GIF demonstrates the effect:</p>
  
  <p><img src="https://i.stack.imgur.com/kEMjB.gif" alt=""> </p>
  
  <p>Couldn't wrap my head around to make this work with CSS &amp; JS. Some combination with mix-blend-modes, clipping masks, pseudo elements and filters I guess. </p>
  
  <p>The following code makes the cursor white but doesn't alow the black text to be turned white. Sounds abstract? Here's a <a href="https://codepen.io/danoszz/pen/XEQVNB" rel="noreferrer">demo</a>.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>// All creds go to https://murmure.me 
  
  const cursor = $(".cursor"),
        body = $("body"),
        slider = $(".slider"),
        nav = $(".nav"),
        fail = $(".fail"),
        invert = $(".invert"),
        nav_open_menu = $(".navopen"),
        wwidth = $(window).width(),
        wheight = $(window).height(),
               
  cursorMove = function() {
    var e, n;
    return (
      body.addClass("cursor-on"),
      cursor.css({
        transform: "matrix(1, 0, 0, 1, " + wwidth / 2 + ", " + wheight / 2 + ")"
      }),
      (e = wheight / 2),
      (n = 0.65 * wwidth / 2),
      n &gt; e ? e : n,
      $(window).on("mousemove", function(e) {
        var n, t;
        if (
          ((window.x = e.clientX),
          (window.y = e.clientY),
          cursor.css({
            transform: "matrix(1, 0, 0, 1, " + x + ", " + y + ")"
          }),
          !nav.hasClass("overlay-visible"))
        )
          return (
            (n = Math.floor((x - 60) / 5)),
            (t = Math.floor((y - 60) / 5)),
            n &lt; 20 &amp;&amp; t &lt; 20
              ? nav_open_menu.addClass("magnetize").css({
                  transform: "scale(1.3) translate3d(" + n + "px, " + t + "px, 0)"
                })
              : nav_open_menu.removeClass("magnetize").attr("style", "")
          );
      })
    );
  };
  cursorBind = function() {
      var e, n, t;
      if (
        ((n = cursor.find("span")).removeClass("link external new"),
        (e = $(".focus")),
        (t = $(".slack")),
        $(window).on({
          mouseenter: function() {
            return n.removeClass("off");
          },
          mouseleave: function() {
            return n.addClass("off");
          }
        }),
        $("a, button, .cursor-link, .sort-listing th").on({
          mouseenter: function() {
            var e;
            return (
              (e = $(this).hasClass("external") ? "link external" : "link"),
              n.addClass(e)
            );
          },
          mouseleave: function() {
            return n.removeClass("link external");
          }
        }),
        $("h1").on({
          mouseenter: function() {
            var e;
            return (
              (e = $(this).hasClass("external") ? "invert external" : "invert"),
              n.addClass(e)
            );
          },
          mouseleave: function() {
            return n.removeClass("invert external");
          }
        }),
        e.length &amp;&amp;
          e.find("a").on({
            mouseenter: function() {
              return n.addClass("new");
            },
            mouseleave: function() {
              return n.removeClass("new");
            }
          }),
        slider.length &amp;&amp;
          slider.on({
            mouseenter: function() {
              var e;
              return (
                (e = $(this).hasClass("full") ? "click" : "drag"), n.addClass(e)
              );
            },
            mouseleave: function() {
              return n.removeClass("drag click");
            }
          }),
        t.length &amp;&amp;
          t.on({
            mouseenter: function() {
              return n.addClass("light");
            },
            mouseleave: function() {
              return n.removeClass("light");
            }
          }),
        fail.length)
      )
        return fail.on({
          mouseover: function() {
            return n.addClass("relol");
          },
          mouseleave: function() {
            return n.removeClass("relol");
          }
        });
    };
  
  cursorMove();
  cursorBind();</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body {
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  h1 {
    font-weight: 500;
    font-size: 9vw;
  }
   
  
  *, *:before, *:after {
    box-sizing: border-box;
  }
   body {
    min-height: 100vh;
    background-color: #fff;
    color: #000;
    text-rendering: optimizelegibility;
    line-height: 1.5;
   /* System stack font-family mentioned by @wooorm */
    font-family: Roboto, -apple-system, BlinkMacSystemFont, Helvetica Neue, Segoe UI, Oxygen, Ubuntu, Cantarell, Open Sans, sans-serif;
  }
   .cursor-on {
    cursor: none;
  }
   .cursor-on * {
    cursor: none;
  }
   .cursor-on .cursor {
    position: fixed;
    z-index: 10;
    pointer-events: none;
    top: -1rem;
    left: -1rem;
  }
   .cursor-on .cursor &gt; span {
    display: block;
    width: 2rem;
    height: 2rem;
    border-radius: 2rem;
    background: #f8e71c;
    transition: transform 0.2s cubic-bezier(0.165, 0.84, 0.44, 1);
    transform: scale(1);
  }
   .cursor-on .cursor &gt; span.off {
    transform: scale(0);
  }
   .cursor-on .cursor &gt; span.link {
    transform: scale(1.5);
    background-color: #0000ed;
  }
   .cursor-on .cursor &gt; span.link.external:after {
    content: "↗";
    display: block;
    white-space: pre;
    color: #fff;
    font-weight: 100;
    font-size: 1rem;
    text-align: center;
    width: 100%;
    line-height: 1;
    padding-top: 0.6em;
  }
   .cursor-on .cursor &gt; span.light {
    background: #fff;
  }
   .cursor-on .cursor &gt; span.drag, .cursor-on .cursor &gt; span.click, .cursor-on .cursor &gt; span.relol, .cursor-on .cursor &gt; span.new {
    transform: scale(2.5);
  }
   .cursor-on .cursor &gt; span.drag:after, .cursor-on .cursor &gt; span.click:after, .cursor-on .cursor &gt; span.relol:after, .cursor-on .cursor &gt; span.new:after {
    display: block;
    content: "";
    white-space: pre;
    color: #fff;
    font-size: 5px;
    text-align: center;
    width: 100%;
    line-height: 1;
    padding-top: calc((2rem / 2) - 2.5px);
    color: #000;
  }
   .cursor-on .cursor &gt; span.drag:after {
    content: "play";
  }
   .cursor-on .cursor &gt; span.click:after {
    content: "click\A click";
  }
   .cursor-on .cursor &gt; span.relol:after {
    content: "click\A me";
    padding-top: calc((2rem / 2) - 5px);
  }
   .cursor-on .cursor &gt; span.new:after {
    content: "new\A new";
  }
   .cursor-on:active .cursor &gt; span {
    transform: scale(0.75);
  }
   .cursor-on:active .cursor &gt; span.link {
    transform: scale(1);
  }
   .cursor-on:active .cursor &gt; span.drag, .cursor-on:active .cursor &gt; span.click, .cursor-on:active .cursor &gt; span.relol, .cursor-on:active .cursor &gt; span.new {
    transform: scale(2);
  }
   .grid {
    background-color: #fff;
  }
   .grid--column--item {
    background-color: #000;
  }
   .grid--column.sticky .grid--column--item {
    border-color: #000;
  }
  
  
  .cursor-on .cursor &gt; span {
    background: black;
  }
   .cursor-on .cursor &gt; span.invert {
    transform: scale(2.5);
    mix-blend-mode: difference;
    filter: invert(1) grayscale(1) contrast(2);
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;h1 class="invert"&gt;Work&lt;/h1&gt;
  
  
  &lt;div class="cursor" &gt;
    &lt;span class="off"&gt;&lt;/span&gt;
   &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <pre><code>mix-blend-mode: difference;
  filter: invert(1) grayscale(1) contrast(2);
  </code></pre>
  
  <p>I've setup a <a href="https://codepen.io/danoszz/pen/XEQVNB" rel="noreferrer">playground on Codepen</a> to mess around with, but didn't found a solution yet.</p>
  
  <p>How could this hover effect be recreated with CSS and Javascript?</p>