0

Try to copy this CSS definition in body on this page:

div{

    cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAEr0lEQVRYR83YXWgcVRQH8P/Zze5km3YbMZ/7Edxq6lcrFPrSaBL6Iiai+BSKgiBCLfjgi4pNsRKrgTbgU0HUor6FKiKixlakuzO7CaVExYogjTVlJps2ia2RhthkZ+6Rmc2GzWZ3Z2a7abyvd+ac35x7z3Bn6OLPc881NAY/BuFzQ/BANFo7gf/RICWhGsFgwNPUFLRYBEwz83ED0kfRKP272VZKJqaGGeJAMBhADrmC0gkkE+NIc8Q3TkTGZmAplUrfL3TjdzN5EWTOdBPASXj874VC9NedhJKZLJnQphncaoO0XAz86mF+oyUifU9E+kZjs0BZfZkZJ3PJylQy37NIwGl4xdutrYErGwW1gPH4ZK2XvOYy1rhEZi9nTBLRwPV53/CuXbRcTawFNIciq2fBeDw/uMNK5t+iM3DGy+hvjvh/IyJxu9hV4Jic3qOz8VNhwAqQuRB/Axhayvjfj8VovlLoKpCZPUlZuw6gvopIawMwcIEhDofDtbLbqq4CrWVWtKMQPFDsaW+jkvnhbgJ0yqdnhhrvqbvqpKprgPH4ZL2XvObSFB1VQmbbCrhEwJstYf+X5V5Xa4DZZtHGwLzvDiBzKZZA+KJG8FuNEekyEZn41bEOmEpMdwroSrnyV7GSBWloBiwGfbXSJ42NZL72zLPB2rHSLDcAbN8cpJWVGRQXrD+/DmjOphTthBD8mt0m3rhK5jLzXFHgeHy6YZH02WIVrvIryKYG9ENRoHlXUtYuMvNuuyqa89WvJM0w8SuhkP+zksBUSusROo84AVYR+aeAOBgO157LdXNJ4EqzLAAIbDiSMA6iQ6GQ/8fCXCWBK8v8ATMfdAp0W0kGnRMsDpX7DioLTKXUkNAx5aRZ8h/CwZ68UZPJPNwU23rN7uHLAq0qKuofLHCvXSDX3c34KhSVnrGLawscVdQDhsCwXaBi83aVZOCbcER6qlxsW2Cx07YbrB2SgK9bI9LTpWLaArPNop5mRp8bmKs9WWa5HQHPy1r7MvOlSoGOursE0hHQTKAkVBVAdEORwEgoIj2Zn8MxMCWnXxRsnLodoKNKEs6EwlJPLo9j4MTEhHQ1LZlnNJ8D5D/ljmt2jQPgu1BE6jXzOAZayyxr34LZurHc8Po8ezjDzwqUPrLZIb3L/pbmHTTjCnhe0R5ZFvxL2fcW0WRnd3SHeU0qoZ2oEHm5NezfaX4BugIyMyVlzTwnNpRC1njwREdX29ncfFLRjrPg10tdv66SjMkl3f9QLEa3XC+xVRVZfVUwhkoknOvsjjYXfvikFPVdIdBviyzAVQSMx2e3eumW2QSewoReD154tKvt02KQpDz1DrM4Uhq55cr2u+5+MFc5112cHzgpawozdxYkW7g2G63v6yv9ozOlqINC4HAhkgBNZ2Pn/v0xa1nzh6s9mLtxdHRqn5ERY/mBPB4cfayr7ZhdhyuKOog8JBPSPh+1d3REi/5urgiYPW2r8wBtWwFlFhaXtvX2ti/ZAc35UXnqmMGiH4T0lrqaB/buDS2Wuq8ioNUseRufiD7s7I6+5ASXu2ZkZELq6blvubChqrLEZpCxMS1gZGD+rvMH6ry7y1XBDbzw2v8AzYPIODUE9pYAAAAASUVORK5CYII="), auto !important;
    height:200px;
    width:200px;
}
<div>hover</div>

The customized cursor works but it's not rendered as a retina image. It's rendered as a blurry, 100% bigger-sized image.

Is there any way to force it to display as a retina image? (I tried both Chrome and Safari)

ATP
  • 2,939
  • 4
  • 13
  • 34
AGamePlayer
  • 7,404
  • 19
  • 62
  • 119
  • https://stackoverflow.com/questions/13744542/automatic-retina-images-for-web-sites see this question maybe can help you! – MahmouD Skafi May 02 '21 at 12:47
  • @MahmouDSkafi not working for cursor property – AGamePlayer May 02 '21 at 13:03
  • 1
    *"In Gecko (Firefox) the limit of the cursor size is 128×128px. Larger cursor images are ignored. However, you should limit yourself to the size 32×32 for maximum compatibility with operating systems and platforms. (Due to a bug in Gecko 1.9.2-1.9.2.6, Firefox 3.6-3.6.6 on Windows limits to 32×32px. This is fixed in later versions.)*" - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property – T J May 02 '21 at 14:13
  • @AGamePlayer what do you mean by "Force it to display as a retina image"? That it is displayed at 20x20px even if the image dimensions are 40x40 for retina screens? – Hans Spieß May 02 '21 at 14:14
  • It means the image is stretched bigger, which should be rendered in 20x20 but not 40x40 – AGamePlayer May 02 '21 at 23:37
  • @TJ Thanks for the tip. However, even I resized it to 32px, it's still blurry. – AGamePlayer May 02 '21 at 23:39

2 Answers2

0

Here is some CSS. I just converted your PNG to a SVG and resized it. Feel free to decode this and resize the SVG in the XML.

div{

    cursor: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDMyIDMyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAzMiAzMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+ICA8aW1hZ2UgaWQ9ImltYWdlMCIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiB4PSIwIiB5PSIwIg0KICAgIGhyZWY9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQ0FBQUFBZ0NBTUFBQUJFcElyR0FBQUFCR2RCVFVFQUFMR1BDL3hoQlFBQUFDQmpTRkpODQpBQUI2SmdBQWdJUUFBUG9BQUFDQTZBQUFkVEFBQU9wZ0FBQTZtQUFBRjNDY3VsRThBQUFDaTFCTVZFVkhjRXpTeit6bDVQam01UG5tDQo0dmpqM2ZibTQvbkJ2dUhsNC9qbTVQbm80L3JtNC9uQ3dPTFF6K3ZtNVBubTVQbm01UG5tNVBuazVQcm01UG5uNVBuRHdPUEF2dUhSDQp6K3ZtNVBubTQvam00L2puNVBubjVQamw0L3JGeE9IQ3dPTEF2dUhtNVBubDQvam01UGpsNC9qbTR2ckN3T0xDd09MQXZ1SG00L2psDQo1UGptNC9ubDQvbmw0L2pGd3VUQ3YrTEN3T0xsNC9ubTVQamw0L25sNVByazQvakR3ZUhEd09MbTQvam00L25tNC9ubTVQakJ3ZUxCDQp2K0xsNVBubTQvbm00L2ptNC9uQnYrSEJ3T0xCditIbDQvbmw0L2ptNVBqbTVQbm01UGp3NHZiQ3dPUEN3T0xtNC9qbTVQbmw0L25tDQo1Zm5rNWYzQ3dPTER3ZVBCditIbTQvbm00L2ptNVBubDQvYmwwdkxDd09MbDVQam01UGptNVBqQ3dlTER3T0xCditMbDQvbmw1UG5tDQo1UHZFdytQQ3dlTEN3T0xtNVBubDQvaS92dUxDd09MbDQvbmw0L25sNVBqbTUvckR3ZVBDditMQ3YrTG00L2psNC9uaDQvcm00L2puDQo0UGZEd2VIbDQvbkN3T0hDd09IbTQvbm00dmpDd09MbDQvbm00dm5DditMbDQvbm01UG5KdytmQ3dPTEN3T0xCd09MQnYrTEN3T0xDDQp3T0xtNHZyRHdlTEV3dVBDd09MQnYrSEN3ZUxDditMQndPTEN3T0xDd09MRnd1UEN3T0xsNC9uRHdPTEN3T0hDditMRncrTEN3T0xtDQo0L25Ed2ViUHpldlN6K3pEd2VQQ3dPTEZ4T0xDd2VMQ3dPSER3ZUhEdnVQQndPSEV3dVBZMXZUNitQL3E2UDdRenZQeThQL3Q2Ly9GDQp3K2JwNS8zcjZmL3U3UC9NeWUzUnordm01UG4xOC8vSXh1bmw0L2p6OGYvQXZ1SEd4T2ZvNXZ2czZ2L281L3pKeCt2Q3dPTHY3Zi80DQo5Zi9Ed2VQUXp2TEV3dVhzNmYvdzdmL096UEQwOGYvTXl1N0J2K0hMeWUzdjdQL3I2ZjdOeSsvSHhlalQwZmJMeWV6THlPekt5T3ZLDQp5T3pGdytYTHl1Ny8vLytxN0R0eUFBQUFxWFJTVGxNQTIrYVRYd1lCNk11VUpRT1U5UDN4eWxFU0JRSmYvZjc4OG9JOUNRSUV5L3YrDQovclYwSXBMOS92cjczS3hLSWZEKytPQjdIQVFCeHY3OCsweE0vZjdTaFVNUTYvNysvUG04Y1FoNSt2bnJwekVMQXpuOC92MzdVUUtyDQovdjMxQlczNy9JZ25GdFg4N1k0Rm8vM1dpUkEzOVA3VWFSamRHMlBvK3Y3a0wvdmlMa0xqTUE2N2QvNysydGNYQWluaCtuM1IvTEhqDQpMTXh2VVBrSkhzcHhISEVEZmJNZGN6R21EQjg4WVZIVVRBQUFBQUZpUzBkRTJBQU5SNjRBQUFBSmNFaFpjd0FBQ3hJQUFBc1NBZExkDQpmdndBQUFBSGRFbE5SUWZsQlFZT0NqbklvcjIxQUFBQ2hVbEVRVlE0eTNXVGlWdE1VUmpHUDltTGthMlphSEV1bWluSlFVMkZ4amIyDQprR21VWFZGRDJjcWVKSVRRUW5heWxiMnBHWk5PaTJsMDJpeUpyaEwvam5ObnVYTmJuUHM4OXpuM2VYL1ArZDczKzg2RklSNURodzBIDQpHQUgvV3lQZlZSaEhqZllVdGw2RFVtTXF4OHFxVE9POHgwOWdIeE1uRFFRbW0zM2tDdGw3UzdYdmxLbCtEUEh2RHdRRWZwaFdneEFuDQpJN1hWMDJmTUhLUkdVSjFTVlVOUVBRb09hYWlkRlRyYjdrWjZUdGdjTS83SUNJNXd3U0dtaHJuejVvZEhzRkplTGwwTmtWWXNFS1FlDQprYWpvQlkwVzI2ZlFoZUVBRVNLeXFDbUdPZ21PYURpa2lXcHVXYnhrS1lqTldiYThWWXVwbldEUENnYXRYR1dyOEYyOVppMFQ3Ym5YDQp0Y1ZTTjBFSUlwcm85WTBOWk1QR3VFMU0xa0Y4dXg1cnFaUkFtelVKaWNUeStZdjNGdUdFcmR1K3h0SStCQ0hiRVVFN0ZOeTNuVXpmDQpCYnM3a2pEK0xpVTBSSk9jWURTUlBYdnRRVk5TbXd5VXVna3VpaVFITjF2MjdROTN4RWlEOUU0OWxoQ0VIUGpSY3ZEUVlhYjVPM3AxDQpKS01kWjdvSmxQRHo2TEhqa2t1aWhsUXJhNFZJY0RMamlaUGdKNTNZcVRvbHBXNmlYbUU2SFFjUkVpQWxpNTdCSW9FRUl2dHNIeUtvDQpLNGQxazJaU1ZrcmxJTTdsdWdrZG5PK0lGVnhncXRRTEJMc2ZDdHVGaStBbHVzeTcxSmxqMTgyODNqbVhSSnRIbkJna0RTNVhabDNKDQoxeXI1cTlmcTlNTDBoU3EyN091dUdnVlFXTVFiS0M3K2RTUHZabmNKcFNvNVltbXJQRVdUYVhDckswZHI0Ry9mZ2JDN1BVbUNENW1zDQorWjQ3UlFIY2Y5Q0tTMzZudzBONFZOcGJqS21QM1BSWTJpbzFGUEhLUHhtRm9OYkJrOUxlSkJ6VDh4U2U5Ym4vejNrRFg4WkFGcm84DQpzTnZ3OTBVL0hjcXQrVTB2blcwcGoyd2JvRVBBcTY2eUFKZWoxMjhHL0dFRkVOLzZscjJkamx6ckgxUzROZ1VZUHRrSkFBQUFKWFJGDQpXSFJrWVhSbE9tTnlaV0YwWlFBeU1ESXhMVEExTFRBMlZERTBPakV3T2pVM0t6QXdPakF3WjlDQ3BnQUFBQ1YwUlZoMFpHRjBaVHB0DQpiMlJwWm5rQU1qQXlNUzB3TlMwd05sUXhORG94TURvMU55c3dNRG93TUJhTk9ob0FBQUFBU1VWT1JLNUNZSUk9IiAvPg0KPC9zdmc+DQo="), auto;
    height:200px;
    width:200px;
}
awholegnuworld
  • 381
  • 1
  • 12
-2

Yes, this is fully possible using SVG, which displays in crisp definition on screens of any pixel density, standard (@1x), retina (@2x), and even 4k and 8k displays (@3x, @4x+).

You also don't have to use Base64, and it may be easier without relying on Base64. Here is an example without Base^4, where I simply pull the cursor SVG image in via URL. I also have a dynamic Base64 example below this first example, so scroll down for that.

div {
  cursor: url('https://assets.codepen.io/1580009/stackoverflow-67356313-cursor.svg'), auto;
  height: 200px;
  width: 200px;
}
<div>hover</div>

If you would prefer to Base64 encode your SVG, that will work too, though it's not always performant (Probably Don't Base64 SVG). Below is an example which uses Base64 dynamically. For the sake of this example, I've added the SVG itself into the body of the HTML, along with a field that you can use to control the size of the cursor. As you adjust the input field's cursor size, the Base64 string will automatically recompute the new Base64 string for the updated cusror size and rewrite that style on the hover-div.

const input = document.querySelector('input'),
      svgCursor = document.querySelector('svg#cursor'),
      hoverDiv = document.querySelector('div');

const setCursor = (size = 16) => {
  svgCursor.setAttribute('width', size);
  svgCursor.setAttribute('height', size);
  const base64cursor = window.btoa(new XMLSerializer().serializeToString(svgCursor));
  hoverDiv.style.setProperty('cursor', `url('data:image/svg+xml;base64,${base64cursor}'), auto`);
};
setCursor();

input.addEventListener('change', () => setCursor(input.value));
div {
  margin-top: 20px;
  height: 200px;
  width: 200px;
  border: 2px dashed #f00;
}
svg#cursor {
  display: none;
}
<label>Cursor size: <input value="16" type="number"></label>

<div>hover</div>

<svg version="1.1" id="cursor" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve" width="16" height="16"><polygon fill="#D0CBE7" points="0,0 13,32 17,23 25,32 32,25 23.7,17.1 32,13 "/><g><polygon fill="#EDE9FA" points="24,17 32,13 0,0 29,28 32,25"/></g></svg>
Brandon McConnell
  • 5,776
  • 1
  • 20
  • 36