11

I have an HTML file that will be portable to distribute to clients. It has an index of documents. I want a PDF or Word icon for each document but I don't want to repeat the base64 string 30 times if I can avoid it. How should I do this? Javascript is okay, but my goals are simplicity and portability.

4 Answers4

15

Try using CSS class

img.word-icon {
  content: url(data:image/gif;base64,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);
  width: 32px;  
  height: 32px;
}
<html>
  <body>  
    <img class="word-icon">foo
    <img class="word-icon">bar
    <img class="word-icon">
  </body>
</html>
ryanafrish7
  • 3,222
  • 5
  • 20
  • 35
7

The other answer using CSS gives the right idea, but it is not compatible with all browsers. The content property of the CSS is only allowed in the pseudo-elements ::before and ::after. The img tag with a class with a content property is empty. The browsers have no obligation to display it. Chrome displays it nevertheless (incorrectly).

To make this work for all browsers, use for example the ::before on an empty span:

span.word-icon::before {
  content: url(data:image/gif;base64,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);
}
<html>
  <body>  
    <p><span class="word-icon"></span>Paragraph with icon.</p>
  </body>
</html>

You can also attach it directly to p::before.

MartinTeeVarga
  • 10,478
  • 12
  • 61
  • 98
5

You can use a CSS variable.

In the <head> section of the page, name and define the variable and a class to use it:

:root {
    --img-123: url(data:null;base64,iVBORw………); /* your image data here */
}

.img-123 {
    background-blend-mode: normal;
    background-clip: content-box;
    background-position: 50% 50%;
    background-color: rgba(0,0,0,0);
    background-image:var(--img-123);
    background-size: 100% 100%;
    background-origin: content-box;
    background-repeat: no-repeat;
}

In the <body> section of the page, use the image repeatedly via element style section or CSS classes. The SVG data creates a transparent image through which to see the content.

<img 
  class="img-123" 
  src="data:image/svg+xml,&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot;&gt;&lt;rect fill-opacity=&quot;0&quot;/&gt;&lt;/svg&gt;"
>

I observed this technique in the output of the open source Firefox / Chrome extension SingleFile. There might be ways to simplify the CSS and to avoid using SVG.

tanius
  • 14,003
  • 3
  • 51
  • 63
  • 3
    I'm the author of SingleFile. The purpose of the SVG in SingleFile is to give a size to the image without altering the CSS. So, I confirm you can avoid SVG if setting the width and the height of the image with CSS is not an issue for you. – check_ca May 16 '19 at 17:26
1

create a script to insert it into the images. I purposely put the script code inline since you're sending a single HTML file:

<img alt="pdf"/>
<img alt="pdf"/>
<img alt="pdf"/>
<img alt="pdf"/>
<img alt="pdf"/>
<img alt="pdf"/>
<script>
  var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++){
  images[i].src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADmklEQVRYhc2VSWgTURjHgycFPVsEtQdRXE96UFDxZHtRXFDRClrxICoIIl7EhWo9eFDEi+jFBRFxqRUFccEusY11abSKjSa2WZqmbZaZzGRt+/d9r5nxzSSpk9iCD34Mb/Le/P7vmy+Jzfafj6l+vx+Ez+fT0e4FAgH09fUhGAyiv7+fEwqFMDAwgMHBQY7T6VzPnjOl3AAVotzr9eoBSG4OQHIxwNDQELq7u4lzRQ3RShsmAwpEAXp6enhQj8dzpmCAMFssr5g5odAzqVIUgK7xeJxXjVXwdF6A0FwbzGRZWZOtLYgcOzI2D/Yh9dmJcG0Nnw+zMqe+OKE8fpS3V4NOHg6HeYBUKgVJkngl2H1jJYJssZm0x43Q5mok3znG5r88CK5cAvX1yz/zAvtEtABut1vvIbrncrnoeldvTP8cG8xkWRMpTW8QOrCfz0lI19TPH2Ofs9ImqSKXL+bt1SBZJBJBNBpFLBbjUBVkWeYw9XQeoJctNpNiFTDMWQDfupVQP37Q54X2GejtLSqnnmDqWTyAe7YNZhLfvhrmadYDSucneGu28Xmy+3veHjP0lS0mVxSFAlTyAC62eDKgd15MbgjwnS2eDOhrV0iuqipHD8DGbMb8Iqxrbm5GU1OTTktLC6e1tRV2ux1tbW1ob2/nOBwOdHR0oKuri/8iamKzPJFIGAJMY8wowmJqJjP0fjUK/UeQnBpQLLkoTyaThgDjjUp6kBmtuQj51VPED22HfP2SodyFTq3JSwogysSu1ohfqYfs+gZ5d7VBXExOv4qE5QCiTGwq/bQNdxB/cBvyvi3jijV5Op3mWA6QJ8ydUj9tMABp7ULEr14cVyzKM5mM9QAGWe6EIiSU1iyC2vnBkpjIZrPWA5hlIiRTO99D2rAa8uljlsTE8PCw9QBmoQjJ5JNHody8BrXxPpR7t/8qJkZGRqwHMJfVQMCHyPJ5SLx3QLlxDbH9NYju2Aj5Qj2ks6cgn6/LExOjo6PWA5jLqqG+eIZo9WrE9m6D+vwpMqrCT6s2PoR04jiUO7cwsHSBQU5igoblAGJJiZTfC+lgLeIX6hBetQxpWTKUmZ+YQr+1I+PtNYg1eUkBtPeoEavdyUNENlUhaW/Oe7/mUotScVgOIJ6MiB09jOiurUg8aRhXWkxccgBRUkhYirSsAKKokLAUaVkBzLJyhWUHmBDbPwSoYFQx9kwwVbln/3VMzS2snGAqcs+2/QZXZB6MU7ZPlQAAAABJRU5ErkJggg==";
}
</script>
HaulinOats
  • 3,628
  • 4
  • 21
  • 24
  • 1
    The application is the difficulty. I could do it in JQuery but I don't want any libraries or separate files. –  Jun 24 '16 at 13:47
  • 1
    Updated my answer @Devil'sAdvocate. Just another approach. – HaulinOats Jun 24 '16 at 13:55
  • 2
    This is what I was expecting, thanks for the update. But I prefer the CSS solution. –  Jun 24 '16 at 13:56
  • I've heard from different sources that using 'content' in CSS is bad since it separates the purposes of CSS, HTML and Javascript. CSS is supposed to be for presentation only, HTML for content, and Javascript for interactivity or DOM manipulation. Honestly, I don't think it really matters in your specific case, and i'm not an expert, just what the general consensus in the programming community is from what I've read: http://www.karlgroves.com/2013/08/26/css-generated-content-is-not-content/ – HaulinOats Jun 24 '16 at 14:04
  • I respect that argument but I was never a fan. Of course I also mix my food on my plate. –  Jun 24 '16 at 14:05