marp-team / marpit

The skinny framework for creating slide deck from Markdown
https://marpit.marp.app/
MIT License
964 stars 46 forks source link

Allow setting section id from markdown #385

Open hediet opened 9 months ago

hediet commented 9 months ago

Currently, section ids are numeric (<section id="1">...</section>) It would be nice if the id could be set in markdown, maybe even derived from the first heading in it.

This would make styling certain pages easier and also improve reload stability when slide are added before the currently viewed slide.

Btw. very nice VS Code extension! I love this project!

yhatt commented 9 months ago

Setting a specific id for better styling stability seems like a reasonable proposal. However, due to the risk of negatively impacting web applications that render user-provided Marp(it) Markdown, the id attribute keeps modifiable only by developers through the anchor constructor option.

For example, if an app embeds Marp slides like this:

<div id="app">
  <!-- Marp slides here -->
</div>
<!-- Markup for app-specific features here -->

According to HTML specifications, a document cannot contain same ids. If an id named app is set in the Markdown, it could break the application's functionality.

Style stability already can be achieved with the class directive, and styling based on headings (Marp Core feature) can also be achieved using selectors such as :has().

---
class: |
  section.stable-styling {
    background: #fc6;
  }
---

<!-- _class: stable-styling -->

# Stable styling
---
style: |
  section:has(#stable-styling) {
    background color: #fc4;
  }
---

# Stable styling
hediet commented 9 months ago

The _class directive fixes the stable styling issue!

Being able to set ids would still improve reloading a slide deck, as inserting slides before the current slide wouldn't cause problems.

According to HTML specifications, a document cannot contain same ids. If an id named app is set in the Markdown, it could break the application's functionality.

This could be solved by prefixing the ids. Also, I don't think this is a problem for standalone marp slides, that are not intended to be embedded

yhatt commented 9 months ago

This could be solved by prefixing the ids. Also, I don't think this is a problem for standalone marp slides, that are not intended to be embedded

If the ability to change the id attribute of slides from Markdown were to be considered, it would need to be contemplated as part of the specification for the Marp(it) Markdown format, and all anticipated use cases of Marp ecosystem would need to be considered.

ID prefixing could make confuse the Markdown author, as it might result in IDs that do not match what the author has set. If the prefix was implicitly added to the author-specified ID <!-- _id: foobar -->, it could affect to CSS ID selectors like #foobar { ... } and URL permalinks with the anchor https://example.com/slide#foobar.

Being able to set ids would still improve reloading a slide deck, as inserting slides before the current slide wouldn't cause problems.

That is specific to the incremental update of VS Code Markdown preview, especially to morphdom. Marpit/Marp renderer itself has no involvement in the incremental update of DOM, so I feel it seems not to be appropriate as an issue for the Marpit framework.

If the incremental update algorithm of VS Code had an attribute that served a role similar to React's key attribute, it would be able to explicitly indicate the identity of elements without changing the existing id attribute (in other words, without breaking existing CSS ID selectors).