What I would do is use a pseudo-element (e.g. "::before") to duplicate the text and have the different color and background, absolutely position it on top of the other, and then transition the clip-path (with as well clip for IE and Safari support).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.example {
color: #115;
background: #fff;
font-size: 2.5em;
padding: .25em;
position: relative;
}
.example:hover,
.example:focus {
/* this empty rule is a fix for IE10 */
}
.example::before {
content: attr(data-text);
color: #fff;
background: #115;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: .25em;
clip: rect(0,0,2em,0);
clip-path: inset(0 100% 0 0);
-moz-transition: clip .5s;
-webkit-transition: clip .5s;
transition: clip-path .5s, clip .5s;
}
.example:hover::before,
.example:focus::before {
clip: rect(0,1920px,2em,0); /* for old browsers that don't support viewport units */
clip: rect(0,100vw,2em,0); /* can't transition this if 'auto' is specified for any edge */
clip-path: inset(0);
}
</style>
</head>
<body>
<h2 class="example" data-text="Example">Example</h2>
</body>
</html>