Adding classes to images

I am taking the first steps in using Netlify and Netlify CMS and have been looking around for a way to add CSS classes to the images I include in the content.

Is it even possible?

I looked into the documentation and all I could find was the description on how to add a featured image ( Widgets | Netlify CMS | Open-Source Content Management System )

If it helps, I’m using Hugo

1 Like

Hi @brunoamaral I don’t think you can add CSS classes to images from within the Netlify CMS. The CMS edits markdown, and you can’t change CSS classes from Markdown. The only way I can think of to accomplish this would be by creating a custom widget, but I don’t have any details on how you’d accomplish this.

Hello,
I’m also in the situation where I would like to add classes to images in the CMS.
Just the fact that I can add a class = "someclassAddedInCMS" would be fantastic. @futuregerald do you have any example of a custom widget that perform this action? Any updates since Sep 23 where you posted this comment?

@brunoamaral did you arrive to some solution or ideas for this? Appreciate any leads on this.

1 Like

90% sure you can do this with an editor component. You can make a copy of netlify-cms-editor-component-image and make it output whatever markup you want, just make sure the pattern still matches so its still recognized as an editor component on read. Then register it with a unique name and label.

2 Likes

Wow, this is way out of my knowledge, or probably you can show me where in the docs I can find more info about it? Pretty sure I can achieve the results I expect.

Might try asking in the slack where the developers hang out - this is pretty far outside the scope of what anyone else is going to be able to help you with, including our support staff :slight_smile:

You can join by following the slack link from here: Community | Netlify CMS | Open-Source Content Management System

All right thanks, I will ask in slack now.

Did you ever get an answer? I’d love to apply specific styling to images loaded within netlify-cms. Seems like a simple addition of a “class” field in the default image widget could suffice, but adding such functionality is a bit above my skill level.

I hope to see this feature implemented, and I wish I could contribute more!

Hi, nooby here :slight_smile:

Maybe I can help you guys out having the same problem: I’m building a website for a client and she wants to have the ability to change images etc. herself but she doesn’t have any technical knowledge.

I’m taking the approach to add multiple widgets to netlify cms:

  1. install netlify CMS as you would
  2. download this wonderful https://sharadcodes.github.io/hugo-shortcodes-netlify-cms/dist/hugo_shortcodes_netlify_cms.js template, save it in /static/js/ (or where appropriate) and linkt to it in your „/static/admin/index.html“:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Content Manager</title>
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
<!-- Include custom shortcodes in netlify CMS thanks to https://github.com/sharadcodes/hugo-shortcodes-netlify-cms -->
<script src="/js/hugo_shortcodes_netlify_cms.js"></script>
</body>
</html>
  1. now add your new component to “hugo_shortcodes_netlify_cms.js”:
CMS.registerEditorComponent({
    id: "Bild",
    label: "Bild",
    fields: [{
            name: "title",
            label: "Bild Titel",
            widget: "string"
        },
        {
            name: "src",
            label: "Bild Quelle",
            widget: "image"
        },
    ],
    pattern: /{{< img src="([a-zA-Z0-9-_ ]+)" title="([a-zA-Z0-9-_ ]+)" >}}/,
    fromBlock: function(match) {
        return {
            title: match[1],
            src: match[2],
        };
    },
    toBlock: function(obj) {
        return `{{< img src="${obj.src}" title="${obj.title}" class="img-responsive">}}`;
    },
    toPreview: function(obj) {
        return `<img><img src=${obj.src} alt=${obj.title}><figcaption>${obj.title}</figcaption></img>`;
    },
});
  1. as you can see, I’m using the following shortcode (along with fancybox) – substitute for your own shortcode here:
{{ $path := .Get "src" }}
{{ $caption := .Get "title" }}
<div class="fancybox">
    <a data-fancybox="gallery" href="{{ $path | absURL }}" data-caption="{{ $caption }}">
        <img src="{{ $path | absURL }}" class="img-responsive" alt="" loading="lazy" />
    </a>
</div>
  1. now create a new shortcode, I’ve named it img50c.html (centered image 50% width) and inserted a new class “img-50c”:
{{ $path := .Get "src" }}
{{ $caption := .Get "title" }}
<div class="fancybox">
    <a data-fancybox="gallery" href="{{ $path | absURL }}" data-caption="{{ $caption }}">
        <img src="{{ $path | absURL }}" class="img-50c" alt="" loading="lazy" />
    </a>
</div>
  1. add the new shortcode to your “/js/hugo_shortcodes_netlify_cms.js” like so:
CMS.registerEditorComponent({
    id: "bild50c",
    label: "Bild 50% Zentrum",
    fields: [{
            name: "title",
            label: "Bild Titel",
            widget: "string"
        },
        {
            name: "src",
            label: "Bild Quelle",
            widget: "image"
        },
    ],
    pattern: /{{< img50c src="([a-zA-Z0-9-_ ]+)" title="([a-zA-Z0-9-_ ]+)" >}}/,
    fromBlock: function(match) {
        return {
            title: match[1],
            src: match[2],
        };
    },
    toBlock: function(obj) {
        return `{{< img50c src="${obj.src}" title="${obj.title}" >}}`;
    },
    toPreview: function(obj) {
        return `<img><img50c src=${obj.src} alt=${obj.title}><figcaption>${obj.title}</figcaption></img>`;
    },
});
  1. and create the appropriate css class:
.img-50c {
  display: block;
  margin-left: auto;
  margin-right: auto;
  width: 50%;
}
  1. rinse, repeat
  2. profit :slight_smile:

I hope this helps. It’s not optimal but the best I could come up with.

1 Like

Here’s a custom widget that replaces the default image widget with one that supports CSS classes.

CMS.registerEditorComponent({
        label: 'Image',
        id: 'image',
        fromBlock: match =>
          match && {
            image: match[1],
            alt: match[2],
            title: match[3],
            classes: match[4]
          },
        toBlock: function({image, alt, title, classes}, getAsset, fields) {
          return `<img src="${image || ''}" alt="${alt || ''}" title="${title || ''}" class="${classes || ''}"/>`
        },
        toPreview: ({ image, alt, title, classes }, getAsset, fields) => {
          return `<img src="${image}" alt="${alt}" title="${title}" class="${classes}"/>`;
        },
        pattern:  /^<img src="(.*?)" alt="(.*?)" title="(.*?)" class="(.*?)"\/>$/s,
        fields: [
          {
            label: 'Picture',
            name: 'image',
            widget: 'image',
            media_library: {
              allow_multiple: false,
            },
          },
          {
            label: 'Alt Text',
            name: 'alt',
          },
          {
            label: 'CSS Classes',
            name: 'classes'
          },
          {
            label: 'Title',
            name: 'title',
          },
        ]
      })

Add it to your script tag in the index.html and your image widget should look like this:

Ignore the ‘Unique Component’ in my widget picker. It’s another custom widget I had to create. For the CSS classes field, just type them and separate them with a space.

The editor image above renders this single line in markdown:

<img src="/img/building.jpg" alt="Beautiful Skyscraper" title="Skyscrapper in Nigeria" class="img-center"/>

The rendered code is HTML but HTML is valid in markdown and things should work well if you are building for the web.

If you want to preserve the default image widget, change the label and id values at the top of the component registration (1st code snippet above) to something other than 'image'.

Hope it helps🚀.

4 Likes