Adding caption to images

It seems that both the image and caption are left-aligned by default. We can use the CSS like this to center the image.

  /*center image*/
  img { 
    display: block !important; 
    margin-left: auto !important; 
    margin-right: auto !important; 
    } 
    

But I don’t know how to center the caption. I tried this, but it doesn’t work.

  .image-captions-caption {
    text-align: center;
  }

You’ll want to use this to center the image:’

.image-captions-figure { 
  margin-left: auto; 
  margin-right: auto; 
} 

It sounds like you have some other CSS affecting this. You can test this in the Sandbox vault and see that the captions are centered:

You just need to do some investigation to find out what other CSS is preventing the text from being centreed.

1 Like

Sorry for the confusion. I have two obsidian caption plugins. I turned down another one. It works fine now.

Possible solution, editor mode + preview mode

Version: 1.2.8 (Installer 1.1.16)
Build with :

  • Create a .css file with the following code (I use Textedit for mac, don’t leave the .txt extension)
  • Put it in the snippet folder : your vault/.vault/snippet
  • Open the .vault folder using CMD OPT . command.
  • Notice that I added text-align: center; to center the caption because I use another snippet to center my image. If you don’t want to center your image, juste erase this part of the code (for reading mode and source view).
  • Don’t forget to activate this new snippet in the obsidian setting
  • Don’t hesitate to try different settings !
/* reading mode */
.image-embed[alt]:after {
    content: attr(alt);
    display: block;
    margin: 0.2rem 1rem 1rem 1rem;
    font-size: 90%;
    line-height: 1.4;
    color: var(--text-faint);
    text-align: center;

}
/* source view and live preview */
.image-embed[alt]:after {
    content: attr(alt);
    display: block;
    margin: 0.2rem 1rem 1rem 1rem;
    font-size: 90%;
    line-height: 1.4;
    color: var(--text-faint);
    text-align: center;
}

The other snippet to center all my image if this interests you :

/* reading mode */
img {
        display: block !important;
        margin-left: auto !important;
        margin-right: auto !important;
}
    
 .markdown-source-view.mod-cm6 .cm-content > * {
        margin: auto auto !important;
}
/* source view and live preview */
img {
        display: block !important;
        margin-left: auto !important;
        margin-right: auto !important;
}
    
 .markdown-source-view.mod-cm6 .cm-content > * {
        margin: auto auto !important;
}
6 Likes

That’s very cool and could negate the need for a plugin.

Did you have any luck getting external images to work?

This style:

![Alt text](https://forum.obsidian.md/uploads/default/original/1X/39438916879fc6e20fca16cbc962a44f272e102f.png)

Old Topics. But my personal solution is to use a callout for figure. One has to scarify a standard callout or custom one. Here after I use tip:

> [!tip] ![[my_figure.png]]
> *This is the caption* 

With some css leverage you can customise Icon and Title specific for tip (in this example) callout.

I wish Obsidian can support some [!figure] [!table] [!math] callout natively.

With this trick you can also make a collapsible bigger figure with caption :

> [!tip]- ![[my_figure.png|100]]
> ![[my_figure.png]]
> *This is the caption* 
3 Likes

Now you only need to share the css :smile:

This would be a snippet like this one :

.callout[data-callout="figure"] {
  --callout-color: 100, 100, 100;
  --callout-icon: none;
  .callout-content {
      font-size: 0.5em; 
      text-align: center;
   }
 }

The markdown :

Normal text 

> [!figure] ![[two_noises.png]]
> Two signal measurement one has a SNR of 10 the other of 100. The signal average is however the same. 

Some normal text continue here 

How it looks like :

I like the solution because it stays human readable, it does not need special plugin, and I can make it work on my markdown publisher (quartz) easily.

9 Likes

@slyg I would offer a counterpoint to this.

Markdown already has a place for the image description (spec here):

![Image description](path/to/image.jpg)

or

![[path/to/image.jpg|Image description]]

This is where the text is taken from in the captions plugin(s) above.

Relying on Obsidian-style callouts is quite far from any sort of standard Markdown. It might be supported on another Markdown renderer, but it probably won’t be.

Using the in-spec Image Description has a higher likelihood of being supported on another platform into the future, and even without that, it is easier for other software to parse and renders perfectly into HTML.

edit: I’ll add that there’s nothing wrong with doing it the callout way - it’s just food for thought as you consider the longevity of your vault, and the cross-compatibility of it on other platforms if Obsidian is no longer around.

Of course . This was just an additional solution on the topics.

This solution is pretty suitable for long descriptions which can include bold text LaTeX , cross references etc …

Works well within Obsidian and any Markdown render with Obsidian callout flavour .

In fact the information is still there for Markdown render that does not handle callouts (like pandoc) . Only a weird [!figure] is added somewhere, but figure and caption are there.

2 Likes

Good points - I quite like that approach, especially being able to add other markdown in the description.

I just realised an other use case for this method. Is the possibility to add One caption for two images.

> [!figure] ![[fig1.png|300]] ![[fig2.png|300]] 
> The two figures shows .... **when**  $\alpha  = \int_0^\infty f(t) dt$ 
3 Likes

Using @slyg’s Callout option, another way to center the caption without CSS is to use html tags.

> [!tip] ![[Black-Eyed Susans.png|256]]
> <center>Black-eyed Susans</center>

Is it so that still after 3 years, there is no good and easy way to render my alt text image captions on Oblidian Publish?

Seems such an obvious feature for any type of “serious writing tool”

2 Likes

I was able to achieve this by using a simple markdown table.

| ![](/path/to/image.ext)  |
| ------------------------ |
| <center>Caption</center> |
6 Likes

I use the following code in publish.css to apply an image caption in Publish:

img[alt] {
  margin : 0 auto;
  display: block;
}

span[alt]::after {
  content: attr(alt);
  display: block;
  text-align: center;
  margin-top: 8px;
  font-size: inherit;
  color: inherit;
}
1 Like

Is there a way to add LaTeX to alt text and have them rendered correctly locally and hopefully also when Published?

See an example in which everything before the last LaTeX gets cut off from the rendered caption:

1 Like

I have another example use-case to add. I’m trying to make a local vault in the src directory of GitHub - cp-algorithms/cp-algorithms: Algorithm and data structure articles for https://cp-algorithms.com (based on http://e-maxx.ru) so that I can use Smart Connections for studying. Some of the articles are written with a ton of admonitions, and I’d really like to have a robust captioning feature so that admonitions are also manageable. I’m already cleaning up the files to replace the indented admonition syntax (!!! example "Example") with Obsidian’s amazing admonition syntax; it would be helpful if I had less Obsidian Markdown converting to do.

Screenshot (I tried inside the figure caption and the next line down, but I don’t like how either look):

Raw Text:

> [!example] Nose stretching algorithm
>
> Each time you add $\vec r_{k-1}$ to the vector $\vec p$, the value of $\vec p \times \vec r$ is increased by $\vec r_{k-1} \times \vec r$.
>
> Thus, $a_k=\lfloor s_k \rfloor$ is the maximum integer number of $\vec r_{k-1}$ vectors that can be added to $\vec r_{k-2}$ without changing the sign of the cross product with $\vec r$.
>
> In other words, $a_k$ is the maximum integer number of times you can add $\vec r_{k-1}$ to $\vec r_{k-2}$ without crossing the line defined by $\vec r$:
>
> <figure><img src="https://upload.wikimedia.org/wikipedia/commons/9/92/Continued_convergents_geometry.svg" width="600px"/><figcaption>_Convergents of $r=\frac{7}{9}=[0;1,3,2]$. Semiconvergents correspond to intermediate points between gray arrows._</figcaption></figure>
> 
> _Convergents of $r=\frac{7}{9}=[0;1,3,2]$. Semiconvergents correspond to intermediate points between gray arrows._
>
> On the picture above, $\vec r_2 = (4;3)$ is obtained by repeatedly adding $\vec r_1 = (1;1)$ to $\vec r_0 = (1;0)$.
>
> When it is not possible to further add $\vec r_1$ to $\vec r_0$ without crossing the $y=rx$ line, we go to the other side and repeatedly add $\vec r_2$ to $\vec r_1$ to obtain $\vec r_3 = (9;7)$.

This is my favorite solution so far because I’m trying to use Obsidian to view someone else’s Markdown. The table format is the most reliable way for me to use a script to clean-up process.

Screenshot:

Raw Text:

> | ![_Convergents of $r=\frac{7}{9}=[0;1,3,2]$. Semiconvergents correspond to intermediate points between gray arrows._](https://upload.wikimedia.org/wikipedia/commons/9/92/Continued_convergents_geometry.svg)  |
> | ------------------------ |
> | <center>_Convergents of $r=\frac{7}{9}=[0;1,3,2]$. Semiconvergents correspond to intermediate points between gray arrows._</center> |
> 
> <figure><img src="https://upload.wikimedia.org/wikipedia/commons/9/92/Continued_convergents_geometry.svg" width="600px"/><figcaption>_Convergents of $r=\frac{7}{9}=[0;1,3,2]$. Semiconvergents correspond to intermediate points between gray arrows._</figcaption></figure>

Using callouts for captions works well for me. Thanks for your excellent idea!

Here’s my current CSS snippet for figure callouts. It has three variants: [!figure] is the default for figures that span the whole column width. [!figure-left] and [!figure-right] are floating images.

.callout[data-callout^="figure"] {
	padding: .5em;
	margin: .5em;

	& .callout-icon {
		display: none;
	}

	& .callout-title {
		padding: 0;
		margin: 0;
	}

	& .callout-content {
		--callout-content-background: rgba(0, 0, 0, 0);
		padding: 0;
		margin: 0;
		border: none;
		box-shadow: none;
	}
}

.callout[data-callout^="figure-right"] {
	float: right;
	width: 50%;
}

.callout[data-callout^="figure-left"] {
	float: left;
	width: 50%;
}

I have tested the CSS successfully with various themes. For example Primary theme in dark mode and Default theme in light mode:

5 Likes