Overlaying an image with a transparent one

Previously on the CogitActive Saga:
Copyright infringement is a commonplace in the realms of internet. Be it criminal or accidental, misuse of creative content – images in particular – without proper permission from their respective owners is flourishing.

Despite the threat of prosecution and payment of damages, image theft is rampant. In fact, malicious intent is not the only culprit; ignorance is also to blame. People are often unaware of copyright law, assuming that they can use anything published on the Internet without permission. Granted, it is so easy to copy or download images nowadays that would-be-thieves are a right-click away from copyright infringement.

Images are a particularly vulnerable part of your site. They’re easy to copy and, consequently, steal through right-clicking, screenshotting, Google searching, and site scraping.Brenda Barron

There are many strategies to make it much harder harder for infringers – especially non-tech-savvy ones – to download and misuse your images (see How to protect my graphics?). However, the upsetting truth is that nothing can stop the determined crooks from stealing your content1. Now, one trick (among the many solutions listed in the aforementioned post) excited my curiosity: the HTML table solution.

The HTML table solution (from Computer Hope)

The idea behind this method is to overlay your to-be-protected image with a transparent one. To accomplish this, you can use a one-row, one-column HTML table, in which the protected image is set to be the table’s background image. A transparent image is then stretched and overlaid in front of the image [you] want to protect. A disappointing surprise will be in store for whoever tries to get the image via a right-click.

Given the availability of some code in the Computer Hope article (see below), I thought it would be straightforward to implement this technique. However, my first attempt was not successful. For a reason I didn’t comprehend (back then2), WordPress was removing the background image (as confirmed by inspecting the source code). I first thought that something was wrong with my URL, but after double-checking it, I discarded this possibility. Someone in WordPress Development Stack Exchange claimed – in response to someone else similar concern – that the background-image property was the culprit, but replacing the latter with background, as suggested, was not helping.

<table style="margin-left:auto;margin-right:auto">
    <td style="background-image:url(URL OF THE TO-BE-PROTECTED IMAGE HERE);background-repeat:no-repeat;background-size:231px 58px;">
      <img height="58" src="URL OF THE TRANSPARENT IMAGE HERE" width="231" alt="Copyright image">

Code from the Computer Hope article, slightly modified (TEXT IN UPPER CASE). Note that the height and width of the transparent image should match those of the to-be-protected image as specified with the background-size property.

I really struggled with this puzzle; not knowing much about HTML nor CSS for that matter. Going through the W3Schools tutorials helped me to understand the code, but not why it wasn’t working as expected. Briefly, the background-image property places a background-image at the top-left corner of an HTML element (e.g. a <table>), and repeats it both vertically and horizontally (to cover the entire element); hence, the background-repeat property being set to “no-repeat” in the above code. The style attribute is added to the <td> opening tag (“td” standing for table data) of a one row table (<tr>; table row). Last, the table data is filled with the transparent image thanks to the <img> element.

So why did WordPress strip the background image?

For a while, I thought wrongly that the code was not working because of the missing <tbody> tag. By serendipity, when shifting from the Text editor to the Visual editor – a thing better avoided3 – I noticed that WordPress was adding this tag to the code. Indeed, the latter, which groups the body content in an HTML table, must be used as a child of a table element. Anyway, to make a long story short, I (or WordPress) ended up with a code that was working as expected. Erroneously, I thought this was due to the addition of this <tbody> tag. Of course, I omitted another detail…

In the meanwhile, I learned about a serious limitation with this table background approach, though. A background image cannot have an alt attribute. So what, you may wonder? This attribute provides an alternative text for an image. It is actually required when using the <img> tag. Not only is this textual description necessary when the image cannot be rendered normally (i.e. a fallback), but more importantly it is essential for visually impaired people who depend on screen readers or the like. Moreover, the alt attribute is a prime component of any SEO strategy.

In the process of writing this post, and being now more knowledgeable in both HTML and CSS, I noticed something else than the presence of the <tbody> tag in the now functioning code. Earlier, I explained that, after double-checking the URL, I discarded the possibility of an invalid URL. In fact, while the URL was indeed correct, something was wrong with the syntax of the url() CSS function. Specifically, the URL should be provided without quote (as shown in the original Computer Hope code), or optionally in single or double quotes4. Out of habit, I used the double quotes (for the to-be-protected image URL) without even paying attention to it. But here’s the thing:

Double quotes cannot occur inside double quotes and single quotes cannot occur inside single quotes unless escaped.Moz://a

That simple! By removing the double quotes, I fixed my mistake. Alternatively, I could have replaced them with single quotes. The point is that such an apparent insignificant – for beginners like me at least – detail can mess up your code big time!

A better approach

As I said, since the time I first tried the above technique, I learned more about HTML and CSS. In particular, I discovered another way (than the background approach) to place one image on top of another (while keeping the <alt> element, of course). In fact, this technique – generally used for overlay effects – allows adding any HTML element on top of an image, so why not a <img> tag with a transparent image.

In CSS, the position property sets how an element is positioned in a document; the available methods being “static”, “relative”, “fixed”, “absolute” and “sticky”. The absolute method is of particular interest (for the task at hand) because it will position an element relatively to the nearest positioned ancestor. For instance, you can define explicitly (i.e. other than the default “static”) the position of the to-be-protected image and then used an “absolute” positioned element for the transparent image. Icing on the cake, an element with “absolute” position is taken out of the flow of the web page; other elements are positioned as if it did not exist.

As for the to-be-protected image, the relative method sounds like a good fit. It will place the image (i.e. <img> element) relative to its normal position. Typically, elements are further positioned using the top, bottom, left, or right properties. However, there is no need to do so here (i.e. for the to-be-protected image to stay at its normal position). On the other hand, it is important to set the top and left properties of the second element (i.e. the transparent image set with the “absolute” position) to zero pixel each, in order to make sure its upper left corner is positioned exactly as the one of the nearest ancestor (i.e. the to-be-protected image set with the “relative” position). Savvy?

To organize things neatly, we can group our two images (or <img> elements) together. While the HTML <div> element is normally used to make divisions of content in a web page, it can also be used as a container for other HTML elements that need to be styled with CSS. Sounds appropriate, right? The element positioned last will be shown on top (by default); therefore, there is nothing else (e.g. z-index) to worry about. With the code below, the transparent image is positioned on top of the nearest positioned ancestor, namely the <div> container; hence, over the to-be-protected image as well.

<div style="position:relative;">
  <img src="URL OF THE TO-BE-PROTECTED IMAGE HERE" alt="ALTERNATIVE TEXT HERE" style="width:500px;height:500px;">
  <img style="position:absolute;top:0;left:0;width:500px;height:500px;" src="URL OF THE TRANSPARENT IMAGE HERE" alt="ALTERNATIVE TEXT HERE">

Notice the use of the style attribute for sizing the images, as suggested by the W3Schools, rather than the width and height (as in the code from Computer Hope). Both methods are valid; still, the former prevents styles sheets from changing the size of images.

In keeping with size, you don’t have to worry about the size of the container; it will size automatically. On the other hand, it’s a good idea to set the size of the transparent image to the same size as the to-be-protected image. Setting it to 100% (as opposed to a size in pixels) makes it needless to adjust it manually each time. Last, but not least, like this, you can use a transparent image as small as 1 x 1 pixel!

“Great! But when I have tried your code in WordPress, it didn’t work.”
“Yep, I had the same problem. For some reasons, WordPress strips the position, top and left properties from the style attribute.”

The fix is simple: use a class selector to define those properties instead as doing so inline. Besides, inline style should be used sparingly anyway. You can add the new rules to the Additional CSS panel of the Customizer, or even better, add them to the style.css of your child theme. In doing so, you can also include the sizing of the transparent image.

.first {
	position: relative;
.second {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;

The code is now:

<div class="first">
  <img src="URL OF THE TO-BE-PROTECTED IMAGE HERE" alt="ALTERNATIVE TEXT HERE" style="width:500px;height:500px;">

Check out the outcome below:

CogitActive Logo


CogitActive Logo
All right reserved


If, like me, you think that this is too much HTML to write (each time), here is a tip that will make your life easier. Do you remember my post on Gutenberg? No! Not even the game-changing block that I described at the end? The Reusable block! If you create one with the above HTML code, you will just have to replace the first <img> element with the correct information (you can simply copy and paste the HTML from the Image block). Don’t forget to convert it to regular block before, though.

Keep in mind that this image protection technique will not stop image theft via screenshot, making it easy to circumvent even by average computer users. Similarly, tech-savvy thieves can get around by checking the source code of the web page. Actually, whatever protection you put in place in your website, it will not be effective anymore if people access your graphics via Image Search. As I said earlier, no method is 100% foolproof.

Coming next: A copyright notice

1 See 10 Ways to Protect Images From Being Copied. ^
2 This story is quite old – way before I published my first post, actually; hence, its insertion at this point in the CogitActive Saga. ^
3 During this exploration, I also realized that switching between both editors was causing some dramatic changes – even lost – in the HTML. At first, I thought of fixing this issue and searched for options to do so (including plugins). However, the Visual editor being far from satisfactory, I decided instead to compose my posts directly in HTML (i.e. in the Text editor) – despite my limited coding knowledge at the time – and never to use the Visual editor again. I didn’t bother to check the “Disable the visual editor when writing” in my Profile; still I didn’t use the Visual editor anymore until the advent of Gutenberg. ^
4 Of note, quotes are required if the URL includes parentheses, whitespace, or quotes, unless these characters are escaped, or if the address includes control characters above 0x7e. Ignore the gibberish part at the end; still, you might be glad to know that the last hieroglyph is the ASCII graphic character for “~”. ^

What do you think?
  • Like 
  • Agree 
  • Disagree 
  • Thank you