Create a Chrome extension to modify a website’s HTML or CSS

A technique we use to visualise how Lateral recommendations would look and work on a website is to create a Chrome extension that inserts the recommendations at load time. This is useful because:

  • No access is required to the websites source files
  • The extension shares assets with the page, so matching styling is easy
  • It allows one to visualise a demo or feature as if it were in production

We often use extensions to insert recommendations into websites that don’t currently benefit from Lateral recommendations. An example is our
Wikipedia similar page Chrome extension. There are, however, many other applications for this type of extension, such as modifying the styling of a website, hiding an annoying element, auto-populating a form, or clicking something on page load.

In this blog post, I will create a Chrome extension that modifies this blog to set a custom background and to modify the HTML.

Side note: You may be thinking “Why not just use Userscripts?” which is a good question. The main reasons for using a Chrome extension are ease of installation and ease of updating. With Userscripts you’d first need to get the user to install a userscript manager. Then you’d need to get them to install the userscript. With Chrome, it’s as simple as clicking a button. Cross-browser compatibility is a valid concern which Userscripts solve (kind of) but so far, as we are primarily creating demos, targeting only Chrome has not been an issue for us.

So, the first thing to do is to create a folder to hold the chrome extension. This folder needs to contain a few files.

The manifest
Chrome extensions require a file called the manifest. It’s a simple JSON file (named manifest.json) and is read by Chrome to understand what permissions the extension requires, which pages it should load on and things like the name and icons. Here’s a simple example for this application:

{
  "manifest_version": 2,

  "name": "Modify CSS and HTML",
  "version": "0.1.0",
  "description": "Lateral blog post demo extension",

  "content_scripts": [{
    "css": ["styles.css"],
    "js": ["content.js"],
    "matches": ["https://blog.lateral.io/*"]
  }]

}

At the top you can see the standard name, version and description fields. The important part is the content_scripts field. This tells Chrome that whenever we are on a page that matches the matches field, load the CSS file(s) in css and the Javascript file(s) in js.

styles.css
This is the stylesheet referenced by the manifest. All I want to do is to change the background of the blog to a simple pattern so my styles.css contains the following:

body {
  background: url('https://media.giphy.com/media/3o7WTDJQVuYwhhuLhC/giphy.gif') !important;
}

#masthead,
#primary {
  -webkit-filter: invert(100%);
  filter: invert(100%);
  background-color: #fff;
  padding: 20px !important;
}
#masthead {
  background: none;
}
#masthead img, #primary img {
  -webkit-filter: invert(100%);
  filter: invert(100%);
}

I changed the background to a GIF of a unicorn floating through space. Since the GIF has a dark background, I set a background colour and inverted the main content areas.

Note: Here I am loading the background image from giphy, but it’s entirely possible to load from the extension itself using the web_accessible_resources field of the manifest and this tip from StackOverflow.

Note #2: I’m using !important here to override the existing pages CSS. You could probably get around this using a more specific selector, but for demonstration purposes I’ll leave it at that.

content.js
Now for the javascript file that gets loaded on the blog. Since this demo extension is already kind of ridiculous, I’m going to replace all the images on the blog with cats.

var images = document.getElementsByTagName('img');
for (var i = 0, l = images.length; i < l; i++) {
  images[i].src = 'http://placekitten.com/' + images[i].width + '/' + images[i].height;
}

Now we have everything in place, the extension folder should look something like this:

I put the code on GitHub at lateral/chrome-extension-blogpost and if you want to download the extension you can get a zip of it here.

To install the extension, visit chrome://extensions in Chrome and drag the folder containing the above files into the window:

And now the Lateral blog looks like this:

Hopefully the extension you make will be a bit more meaningful. ¯\_(ツ)_/¯

The Author
Making stuff with computers at Lateral.
Comments

30 thoughts on “Create a Chrome extension to modify a website’s HTML or CSS

  1. I’m looking for an extension that can edit javascript source on the fly from html pages– could this sort of thing be used to do that? A simple string substitution is what I need, but over the

  2. Hi! First of all what you are doing is simply amazing! But I was just wondering is there a way to inject the css and html to all the other websites instead of just a specific website?

    1. Sure, just change the “content_scripts” part of the manifest JSON file to look like this:


      "content_scripts": [{
      "css": ["styles.css"],
      "js": ["content.js"],
      "matches": ["*"]
      }]

      You can read more about “content_scripts” here.

      1. Hi Max! Thank you for the prompt reply. But if you don’t mind I still have 1 more question.

        I am try to inject an overlay into every webpage upon the user clicking on my chrome extension.

        As for the code you wrote, it does it really nicely on blog.lateral.io, however if I were to apply it on some other webpage, it breaks the styles the code is trying inject because of the difference in the DOM structure i suppose.

        Is there a way where I can do an overlay across the whole webpage without breaking my code styles. You do not have to give me a direct answer, but I hope you could guide me to some relevant reading materials which maybe helpful since your materials are the ones I found to be the most relevant to the current project I am working on.

  3. Hi, is there a way I can change a balance on a website so whenever the page is reloaded it changes to the desired balance but the balance not actually be there?

  4. Is there any way to create this app but for changes on the site to be on the owners side to push out for everyone to see? So they could make non permanent changes to thier site?

    1. You could use the content.js file to load an external JS file on to the page. Something like:


      var script = document.createElement('script');
      script.src = 'https://path-to.my/script.js?v=' + Date.now();
      document.head.appendChild(script);

      Then you can update the content of your script.js on your server to change what happens. You could do the same by loading an external CSS file from the content.js too.

  5. Do you know of anyway to do this for browsing on an adroid phone?

    I am have to use a rather annoying site and just want to change the font and resize some divs. So it at least fits on my screen.

    1. Hi Nicholas, unfortunately it doesn’t look like support for extensions is planned for Chrome on Android. I know that add-ons are supported on Firefox for Android so maybe you could look into using Firefox and creating an add-on there.

  6. Max, how would you insert a div video element that overlays the entire page, but that you can click through? I would like to access computer’s the webcam for this.

  7. Hey max, i’m looking to simply change my logo within my 5 website pages. Which php file should i most likely find the script that i need to edit, please?

  8. Hi,
    This is great thanks, but I wondered if you could provide me with an example of how to change this so that I can replace ads with my own image/text? I use adblock plus for the most part but there seem to be more and more ads allowed through these days and thought I’d like to replace them with something else.

    Thanks

    1. ABP allows advertisers to buy their way through the filtering. uBlock Origin is a much better ad-blocker

  9. I did a chrome extension. In this extension I want set data input box in external website page. Example: search field in google

  10. Is there a way to make an extension which can modify several websites different?

  11. What’s the difference between putting the background file as a content script versus putting it as a script for background in the manifest.json?

  12. Chrome DevTools technical writer and developer advocate here. Thanks for the great article.

    One issue with this approach is that you can’t view the source code of the injected styles in DevTools. You can see the injected styles in the Styles pane, but the link on the right merely says “injected stylesheet” whereas usually it gives you a link back to the source code of the CSS. Ideally DevTools just fixes this, but honestly I don’t know when the team will get around to it, so I’m noting that Paul Irish suggested this alternative code pattern: https://bitbucket.org/pauli

  13. Is there a way to search the HTML/CSS for references to external domains (other than what domain you’re on) and replace them?

  14. Hi Max, great explanation!
    I write to ask a simple but not founded solution, I need on a specific page to change a table height every time it loads. I tried lots of extensions, plugins, and the only way I could do it is changing manually with the internal code editor the height size, but I enter many times by day and it gets annoying haha. I think this article is the most accurate solution for my problem, but my poor html knowledge makes me impossible to find a way to change a single html sentence with code.
    It is as simple to make a
    “” if sentence contains ‘ height: 640 px ‘ then change to ‘ height: 800 px ‘ “”
    , but I tried base on your code and nothing yet..
    Thanks for the blog by the way, it’s very useful!

  15. hey thnks for this great job
    i want a javascript do this work
    if ( some classname ) exist go to this ( url )
    i mean redirect page when class is disponible
    i want extension alert when (html class) is available
    and thank you

Comments are closed.