Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<ol> style type based on type attribute #7542

Closed
4 tasks done
joapuiib opened this issue Sep 19, 2024 · 19 comments
Closed
4 tasks done

<ol> style type based on type attribute #7542

joapuiib opened this issue Sep 19, 2024 · 19 comments
Labels
change request Issue requests a new feature or improvement resolved Issue is resolved, yet unreleased if open

Comments

@joapuiib
Copy link
Contributor

joapuiib commented Sep 19, 2024

Context

I'm using a Markdown extension that allows writing different types of lists.

  • Lower alphabetic: <ol type="a">
  • Upper alphabetic: <ol type="A">
  • Lower roman: <ol type="i">
  • Upper roman: <ol type="I">

Description

The following CSS overrides the default list styles, so the first nested <ol> will always be rendered as alphabetic regarding the type attribute.

// Nested ordered list
ol {
list-style-type: lower-alpha;
// Triply nested ordered list
ol {
list-style-type: lower-roman;
}
}

Could this be set only if <ol> doesn't have a specific type?

ol, ul {
  // Nested ordered list
  ol:not([type]) { 
     list-style-type: lower-alpha;
  }

  ol, ul {
     // Triply nested ordered list 
    ol:not([type]) { 
       list-style-type: lower-roman; 
    }
  }
}

Related links

Use Cases

For example, writing:

1. List item
2. List item
    1. List item
    2. List item
    3. List item

Will result on:

1. List item
2. List item
    a. List item
    b. List item
    c. List item

Instead of:

1. List item
2. List item
    1. List item
    2. List item
    3. List item

Which might not always be desirable.

Visuals

No response

Before submitting

Repository owner deleted a comment Sep 19, 2024
@alexvoss
Copy link
Collaborator

I have gone and deleted the comment because it seemed to contain a link to a dodgy website hidden behind a blt.ly link. The text around the link does not seem to have anything to do with the question, so, um, a bot? @joapuiib, perhaps also remove the link from our last comment so no one clicks on it?

@joapuiib
Copy link
Contributor Author

I have gone and deleted the comment because it seemed to contain a link to a dodgy website hidden behind a blt.ly link. The text around the link does not seem to have anything to do with the question, so, um, a bot? @joapuiib, perhaps also remove the link from our last comment so no one clicks on it?

I've removed my comment as well. Thanks!

@alexvoss
Copy link
Collaborator

On the substance of your question: I see that this is getting factored into pymdownx, so IMHO it would be appropriate to support this. @squidfunk will need to make the call and has infinitely more experience with this. My view is that this could break something only in unlikely edge cases, so should be ok to change. Someone would need to have a type attribute on their ol elements but expect it to be overridden by the CSS. Hope I am not holding the wrong end of the stick there.

@facelessuser
Copy link
Contributor

It is definitely something I am exploring. A simple override is all that is required to get them working. I don't think lists anywhere are getting type currently unless someone is purposely adding them manually. I'm fairly certain that if I add this extension it won't break anything and people can opt in with some CSS assuming they decide to use this extension. If Material looks for types and avoids the styles automatically, the override will not be needed and I think it will just give people options.

I am still playing around with things, but I imagine if I pull the trigger on this extension some people may disable extra list types or not use the extension. It wouldn't surprise if some people don't opt-in to extra list types because they don't want to add another plugin, they use some other list plugin for some other feature, or simply don't want to use it because their editor won't automatically highlight the new list types in Markdown.

It's an interesting idea for those who want list control, but not everyone has this need. The plan would be to only support the additional list types of both uppercased and lowercased alphatically sorted lists (a-z) and Roman numeral lists.

@facelessuser
Copy link
Contributor

I guess if people want to override it now, all they need is:

.md-typeset {
  /* Override Material's list type preference. */
  ol ol[type]{
    // Nested ordered list
    list-style-type: revert-layer;

    // Triply nested ordered list
    ol[type] {
      list-style-type: revert-layer;
    }
  }
}

@facelessuser
Copy link
Contributor

Actually, it is even easier (I didn't account for ul nesting).

  /* Override Material's list type preference. */
.md-typeset {
  ol[type]{
    // Nested ordered list
    list-style-type: revert-layer;
  }
}

@squidfunk
Copy link
Owner

squidfunk commented Sep 19, 2024

Thanks for reporting. As mentioned, we could probably defensively scope our styles to ol:not([type]), or more specifically the list-style-type property without breaking anything. This would be the mirror of the workaround posted in #7542 (comment), that would then become obsolete. Thanks for investigating to all of you, btw!

Would somebody like to propose a PR?

@squidfunk squidfunk added the change request Issue requests a new feature or improvement label Sep 19, 2024
@joapuiib
Copy link
Contributor Author

Would somebody like to propose a PR?

I'll try in the next few days! Thanks you all for your feedback!

@squidfunk
Copy link
Owner

I was working on other issues and also fixed this in 68b6758. In this commit, I've also added the same fix to the list style type of ul, which can now also be explicitly set. Before, I thought I was clever and added the changes in 85d6091, but that would be a breaking change for when users have deliberately overridden list-style-type on ul or ol. The only downside is that when you use type, the defaults are not applied anymore on any layer, so all ol inside an ol with type will be numbered with 1., 2., ... I think this is fine, or could be even desired, as you're making things explicit.

@squidfunk
Copy link
Owner

Note that I used revert and not revert-layer, as we're currently not using Cascade Layers.

@squidfunk squidfunk added the resolved Issue is resolved, yet unreleased if open label Sep 20, 2024
@facelessuser
Copy link
Contributor

Note that I used revert and not revert-layer, as we're currently not using Cascade Layers.

I didn't even notice that was what I used...either way, looks great!

@squidfunk
Copy link
Owner

Released as part of 9.5.36.

@facelessuser
Copy link
Contributor

@squidfunk this doesn't actually end up working so great. What this fix does is reverts all list items to numerical, but it does so in a way where browsers do not register that an <ol> has a type set to it.

While it may have been an accident on my part, revert-layer is the only thing that works the way I would expect it to (revert it to its initial state where it still cares about the type) if done in the way you are doing it. While it seems revert-layer is supported in many browsers, it is fairly new. I can understand that this approach may not be the solution right now. The real solution seems to be to never set the list style if it has a type. Or at least one solution.

Anyway, I'm not sure how Material wants to handle this, but I'll at least let you know my direction as I need to have this feature just work for people, and luckily there are things I can do to make this happen.

Browsers have a problem that for some reason they are dragging their feet on fixing. Only Firefox seems to support the case-senstive s flag in attribute selectors: [type="a" s] even though it has been sitting in the spec for years and has real, valuable use cases. While browsers recognize the case-senstive property of ol[type=a] vs ol[type=A], CSS selectors do not and will treat both the same. This makes it nearly impossible to differentiate between uppercase and lowercase lists with CSS unless there is a class that selectors can key off of.

Because of the poor browser support, though it looks like revert-layer will eventually be a good approach to this, I will have a couple of options to help in the area of styling.

  1. I am adding an option in these "fancy lists" to allow the user to have the style list-style-type: <style> injected into each <ol>. The idea is to make this just work for those who don't want to fiddle with CSS.
  2. I am also adding an option to inject classes on the element as CSS selector support simply sucks for targeting type. This way, those who want to style the specific list types further can actually target a lowercase alphabetic or Roman numeral list vs an uppercase one.

@squidfunk
Copy link
Owner

squidfunk commented Sep 21, 2024

Maybe a misunderstanding then? It worked when I've tested it and resets to numerical formatting because of the caveats mentioned in #7542 (comment). Could you please provide examples that showcase how it does not work?

The real solution seems to be to never set the list style if it has a type. Or at least one solution.

I tried to make it as backward compatible as possible, and if we'd scope to :not([type]), it would mean we would break existing adaptations because of higher specificity. Users that overrode list-style-type would need to increase specificity on their selectors. However, if you're sure that revert-layer works better, we can use that for sure. I'm currently fighting other battles, so I'm happy for any input or help here. Happy to merge and issue a bugfix release.

@facelessuser
Copy link
Contributor

Here is an example that illustrates what I'm talking about.

https://codepen.io/facelessuser/pen/rNbZGQZ

It's possible it works as you intend, it doesn't work at least how I thought it would or I needed. Either way, I'll have a workaround.

I guess with your approach, revert reverts to numerals, but then type doesn't work, so that makes using type pointless.

That's okay, maybe the intention is the user can just add the CSS they want, but if you use CSS to target the lists, you are limited as you can target type=a case insensitive, but not both type=a and type=A. This limits you to either lowercase list types or uppercase list types, but not both. If all you want is one or the other, that is fine.

revert-layer (which arguably may not be available on all systems) works more like I would hope, but may not be a good fix i the short time because it is so new. But this helps the items act like they do in their original state where type is recognized.

That leaves me with either forcing the style and/or generating classes so users can target the elements with CSS. Either of these are okay.

In short, the recent fix does not give the full flexibility that I would want or expect, but that may be a limitation that we are stuck with in Material until browsers can finish doing things like give us the s case sensitive flag in attribute selectors. I can workaround this issue though with my mentioned workaround of injecting styles and/or CSS classes.

@squidfunk
Copy link
Owner

You know, you are absolutely right. I'm not sure why I didn't catch this, but yes, we need revert-layer. Should be fixed with 43a22b6, where I also added styles for the 4th and 5th layers ☺️

@squidfunk
Copy link
Owner

Reopening until released.

@squidfunk squidfunk reopened this Sep 21, 2024
@facelessuser
Copy link
Contributor

Excellent! That will give a better experience. If there are some browsers that don't support revert-layer, I'll allow people t inject styles or inject classes if they want more control over styling.

@squidfunk
Copy link
Owner

Released as part of 9.5.37.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
change request Issue requests a new feature or improvement resolved Issue is resolved, yet unreleased if open
Projects
None yet
Development

No branches or pull requests

4 participants