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

Indicator Display Style Variations #3142

Open
lesichkovm opened this issue Jan 24, 2025 · 12 comments
Open

Indicator Display Style Variations #3142

lesichkovm opened this issue Jan 24, 2025 · 12 comments

Comments

@lesichkovm
Copy link

At the moment, the hx-indicator uses the visibility: hidden style. Unlike display: none, the visibility style maintains the element's width, which can be undesirable in certain scenarios. For instance, when used within buttons, the hidden indicator can still occupy space, affecting the button's appearance.

To address this, many developers resort to additional styling like this:

.htmx-indicator {
    display: none;
}

.htmx-request .htmx-indicator {
    display: inline-block;
}

.htmx-request.htmx-indicator {
    display: inline-block;
}

This approach works, but it can be cumbersome and add unnecessary complexity to your stylesheets.

I propose creating variations of the hx-indicator class to offer more flexibility:

  • hx-indicator: Retains the current visibility: hidden style.
  • hx-indicator-block: Uses display: block.
  • hx-indicator-inline: Uses display: inline-block.

This approach provides developers with more control over the indicator's display behavior, making it easier to integrate smoothly into various design contexts.

@Telroshan
Copy link
Collaborator

Htmx inserts a few style rules by default for indicators:

htmx/src/htmx.js

Lines 5020 to 5024 in 4177071

'<style' + nonceAttribute + '>\
.' + htmx.config.indicatorClass + '{opacity:0}\
.' + htmx.config.requestClass + ' .' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
.' + htmx.config.requestClass + '.' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
</style>')

These rules just play with the opacity (not visibility) that is animated through a transition, unlike display which cannot be interpolated.
These CSS rules are very basic and are just here to provide a default minimalistic styling to make an indicator be invisible / visible when a request is in-flight.

As you said, is can be undesirable in "certain" scenarios, which is why htmx provides the htmx.config.includeIndicatorStyles property. Setting it to false won't insert any CSS rules, and let you freely define how you want to style your indicators.

htmx.config.includeIndicatorStyles | defaults to true (determines if the indicator styles are loaded).

People might have very different styling desires, and I don't think it's relevant to embed more styling options into htmx itself, as it's not the library's goal. As you showed in your example above, you can quickly define custom CSS rules to customize the indicator's display.

@lesichkovm
Copy link
Author

The reason I placed this request actually exresses my frustration exactly with this feature. It took me couple of years to realize I could create custom styling for this, by finding the above solution on the internet, and I avoided using this functionality all together.

Providing sensible defaults for common use cases, like offering hx-indicator-block and hx-indicator-inline classes, wouldn't bloat the library but would drastically improve the developer experience.

By providing these simple, out-of-the-box styling options, HTMX can empower developers to quickly achieve polished results. This change wouldn't restrict customization; it would simply provide a more welcoming and efficient experience for everyone, promoting more consistent and robust HTMX implementations.

@lesichkovm
Copy link
Author

Here is the code that needs to be added. I was not able to do a PR, due to the tests requiring configuration and not able to run out of the box.

`<style${nonceAttribute}>
  .${htmx.config.indicatorClass} { opacity: 0; }
  .${htmx.config.requestClass} .${htmx.config.indicatorClass} { opacity: 1; transition: opacity 200ms ease-in; }
  .${htmx.config.requestClass}.${htmx.config.indicatorClass} { opacity: 1; transition: opacity 200ms ease-in; }

  .${htmx.config.indicatorClass}-block { display: none; }
  .${htmx.config.requestClass} .${htmx.config.indicatorClass}-block { display: block; }
  .${htmx.config.requestClass}.${htmx.config.indicatorClass}-block { display: block; }

  .${htmx.config.indicatorClass}-inline { display: none; }
  .${htmx.config.requestClass} .${htmx.config.indicatorClass}-inline { display: inline-block; }
  .${htmx.config.requestClass}.${htmx.config.indicatorClass}-inline { display: inline-block; }
</style>`

@Telroshan
Copy link
Collaborator

The hx-indicator documentation gives examples of customizing the styling rules, and links to the includeIndicatorStyles configuration property.
It's very likely that the documentation could/should be improved to make this clearer, but I think it's more a documentation issue than anything else.

Even if we added the classes you suggest, people would still need to stumble upon them in the docs to be able to know in the first place that they can use different default indicator classes.
So in my opinion again, I'm afraid this wouldn't address the core issue at all, as it would still be something that people would have to discover in the docs ; be it a section on how to configure styling, or a section of other default classes they could use, lead to the same end issue imho (though one requires adding extra lines to the core library while the other doesn't).

@lesichkovm
Copy link
Author

The hx-indicator page is the first a user sees, when starting with HTMX, and the classes would be available straight away to be used.

For instance, at the moment I am adding the additional CSS lines on every page I use HTMX on. I do not add any other CSS. It feeld rather backward, adding 1 line for the HTMX cdn, and 10 lines for the inline-block styling for the hx-indicator, everywhere where one wants to use it.

Adding the new classes would save all this hassle for hundred of developers.

@Telroshan
Copy link
Collaborator

Well, personal opinion again, but I'd be against adding more lines to the core library for this, especially literal strings that cannot be minified.

Adding the new classes would save all this hassle for hundred of developers.

I beg to differ on this one, sounds like a very specific situation to me to A) not include any CSS for a website, B) not want to add any CSS either to it, and C) would solely rely on a few CSS rules injected by a JS lib.
No hard feelings at all, but I'm really not convinced that "hundreds of developers" are in such a situation, as websites without any CSS are very uncommon nowadays.

@lesichkovm
Copy link
Author

@Telroshan if the problem is that 2 small lines of code will be added, then I would say the default style of the indicator to be changed to display:inline-block as it covers more use cases.

@Telroshan
Copy link
Collaborator

I would agree with a better default, the issue is that for backwards compatibility reasons, we can't change defaults unless we release a major version (that's why we made htmx 2 for example, to introduce breaking changes) as this could break existing apps, and at this point it's very unlikely that htmx 3 would ever happen in the future.

@lesichkovm
Copy link
Author

@Telroshan what would be the best way to resolve this? Is it by adding another class name? Or there might be a better solution.

@geoffrey-eisenbarth
Copy link
Contributor

@lesichkovm are you able to host your own copy of HTMX (with your changes) instead of relying on a CDN?

@lesichkovm
Copy link
Author

@geoffrey-eisenbarth I have no problem forking it, putting the changes in, and hosting it myself, but then how does it help the community? Does everyone have to do their own workaround, for a feature that has to be provided out of the box?

Definitely the indicator using a visibility CSS selector was an oversight, which is normal for the proptype stage HTMX was in. So it is better to be fixed. Everyone knows its never easy to make such a change, but its always better to be done sooner, rather than later. As when its gets widely adopted, we will have to stick with it, even though it is not optimal.

@Telroshan
Copy link
Collaborator

Definitely the indicator using a visibility CSS selector was an oversight

Not so sure about that, as stated above, opacity can be animated with a transition while display cannot. I personally precisely like to use opacity and use indicators as absolute-positioned overlays inside a relatively-positioned parent element. To each their own, I'm not saying your visual preference is invalid at all, but kindly encouraging you to not consider subjective preferences that you don't share to be so.
Again, people might have very different styling desires, and it's fine! CSS lets you customize your website to whatever your tastes are, and htmx lets you disable completely the default indicator styling if you want.

Again my personal opinion, but as said above I think that if it has to be fixed, it'll be at the documentation level.
You shared your own experience of frustration with that aspect which is perfectly understandable, but again, whether we need to better document how to customize styling, or to document alternative indicator classes, the end issue will be the same ; the user has to find out in the hx-indicator documentation that they can either create their own CSS or use alternative indicator classes.
In both scenarios, what we want to improve is the documentation.

If you hadn't stumbled upon the ability to customize indicators classes back then, then if that documentation had contained mentions to alternative indicator classes, you wouldn't have seen it either. And it's not your fault at all! That's why I'm saying that we need to fix this at the documentation level, to make sure newcomers don't miss out on this aspect.
So, it seems to me that adding alternative indicator classes is a solution to the wrong problem there, as the core, underlying issue remains the exact same.

Documentation improvements are always welcome so if you feel it could be improved to avoid the frustration you experienced to other newcomers, either by rearranging, adding precisions, more examples, or whatever else you think is relevant, please feel free to do so!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants