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

Missing support for core-supported dynamic breakpoints #16

Open
brandonmcconnell opened this issue May 12, 2023 · 14 comments · May be fixed by tailwindlabs/tailwindcss#13389
Open

Missing support for core-supported dynamic breakpoints #16

brandonmcconnell opened this issue May 12, 2023 · 14 comments · May be fixed by tailwindlabs/tailwindcss#13389

Comments

@brandonmcconnell
Copy link

brandonmcconnell commented May 12, 2023

What version of @tailwindcss/container-queries are you using?

v0.1.1

What version of Node.js are you using?

v18.16.0

What browser are you using?

Chrome v112.0.5615.137

What operating system are you using?

macOS v13.1 (22C65)

Tailwind Play Reproduction

https://play.tailwindcss.com/iyNosSvgd1

Describe your issue

Purpose / Problem

There currently exists no way AFAIK to use the dynamic breakpoints functionality newly introduced in TailwindCSS v3.2, or anything comparable when it comes to container queries.

There is this arbitrary syntax supported: @[17.5rem]:underline however…

  • no max- equivalent exists
  • the syntax for this departs a bit from the core non-container-related implementation of min-*

Proposed Solution

It might be helpful to follow the core implementation's lead by adding support for min-* and max-* dynamic breakpoints for arbitrary values:

<div class="@container grid h-screen w-screen">
  <div class="bg-[red] @min-[1px]:bg-[green]"></div>
  <div class="bg-[red] @max-[1px]:bg-[green]"></div>
</div>

This way, it works identically to the core implementation but is prepended with @, which is already being used by this plugin to denote container-related queries.

Support for width/height distinction

Furthermore, per a related PR to the core implementation to add support for an explicit w:/h: prefix to the arbitrary value to determine the dimension (e.g. min/max-width/height), implementing the same pattern could be helpful here if that PR passes, which could work like this:

<!--
  `w:` is implied when no `w:`/`h:` prefix is specified,
  but it can also be included explicitly, optionally
-->
<div class="@min-[h:100px]:@max-[100px]:font-bold" />

Syntax consideration

It may be worth considering which of these syntaxes makes more sense in line with the core implementation:

@ before min/max

(as shown above)

  • @min-[1px]:
  • @min-[w:1px]:
  • @min-[h:1px]:
  • @max-[100vw]:
  • @max-[w:100vw]:
  • @max-[h:100vw]:

@ before […]

(as shown above)

  • min-@[1px]:
  • min-@[w:1px]:
  • min-@[h:1px]:
  • max-@[100vw]:
  • max-@[w:100vw]:
  • max-@[h:100vw]:
@akbar-idwise
Copy link

we can't also define custom screen sizes

@christian-wantia
Copy link

christian-wantia commented Jul 8, 2023

I would like to try my hand at extending the plugin code accordingly. And I would also like to create a pull request if it works.

How the return value (i.e. the container query) could be adjusted to implement the different variants is obvious.

Since within the function matchVariant the variable value is available, I could also imagine something like [h:42rem]. But the sizes defined in the theme should work too.

Could someone give me a hint how to get the text between the @ and for example 2xl or [42rem]?


Update:

I would like to be able to implement one of the following two alternatives.

  1. @min-h-2xl:sr-only
  2. @min-h:2xl:sr-only

I would also appreciate any recommendations on what would be a better fit for the Tailwind standard.

@brandonmcconnell
Copy link
Author

brandonmcconnell commented Jul 8, 2023

Hi @christian-wantia, thanks! If you want to take a stab at it, and have any questions along the way, let me know.

I would recommend using my related PR (tailwindlabs/tailwindcss#11225) as a guide, as it does the same operation we're striving for here but for media queries.

Some notes / gotchas

  • 🚨 Avoid those alternative syntaxes you mentioned like @max-h-2xl as that syntax wouldn't work for the core media queries, since max-h is already a dedicated utility for max-height CSS property, and the heart of this issue is to align the two.

    Let's stick with the optional w:/h: modifier. 🙂

  • It's also crucial that the container queries are sorted in the correct order, same as the sorting for the core container queries, so they should always be sorted as (no modifier), w:, h:, and each respective group being sorted in ascending/descending order accordingly (order flipped for max vs. min queries).

Thanks again for contributing here! I really appreciate it. Let me know how I can help.

@christian-wantia
Copy link

christian-wantia commented Jul 10, 2023

Reading through the conversation, file changes, and your notes, I realized that I still need to figure out a few things before I dive into the code.

I'll try my hand at it, and would appreciate feedback on whether my assumptions are correct.


Topic

Media and Container Queries in general

For Responsive Web Design, the concept of Media Queries has been around for a long time. These allow CSS rules to be applied depending on, for example, the width of the viewport.

New is the concept of Container Queries. These are now (as of 2023-07-10) supported by most browsers, and allow CSS rules to be applied depending on, for example, the width of a parent HTML element.

Tailwind

Tailwind (up to and including v3.3) makes Responsive Design implementable with media queries - either via predefined Breakpoint prefixes or via Arbitrary values.

Examples from the documentation:

  • Mobile first: w-16 md:w-32 lg:w-48
  • Breakpoint range: md:max-xl:flex = md to xl excluding the last pixel (max-* uses @media not all and ...)
  • Single breakpoint: md:max-lg:flex = md to lg excluding the last pixel (max-* uses @media not all and ...)
  • Arbitrary values: max-[600px]:bg-sky-300 = 0 to 600px including the last pixel.

Support for container queries can be added using the Tailwind plugin container-queries. The plugin so far only allows (min-width: ...).

Examples from the documentation:

  • Regular: @lg:underline
  • Named containers: @lg/main:underline
  • Arbitrary container sizes: @[17.5rem]:underline

What screens are for media queries in the Tailwind theme, containers are for container queries. Let's call them design tokens. (Or is there already a term for this?)

Goal

The goal is to find a syntax and elegant implementation for the container queries that allows dynamic min-* and max-*, as well as choosing the dimensions width and height, while matching the existing syntax for the media queries — and related utilities, such as min-w-* or min-h-*.


Next, I will first get an systematically overview of what is already available in terms of min and max, width and height, design tokens and arbitrary values, ... before and after a colon.

@brandonmcconnell
Copy link
Author

brandonmcconnell commented Jul 11, 2023

@christian-wantia Thank you for the detailed design review. Most of that is correct!

Re the syntax discovery phase, let's stick with the two syntax options proposed earlier in my original post.

Thanks!


Notes:

The existing syntax should likely be deprecated to support the new syntax exclusively to be inform with the core syntax.

Much of the required logic is likely already set up. I'd suggest studying what this plugin is already doing and compare with the PR I linked previously from core.

@christian-wantia
Copy link

Most of that is correct!

Cool. What do I need to correct in my mental model? (because you wrote „most“)

Re the syntax discovery phase, let's stick with the two syntax options proposed earlier in my original post.

Okay. Do you have an idea, how we can integrate the design tokens (md, xl, …) in your syntax?

The existing syntax should likely be deprecated to support the new syntax exclusively to be inform with the core syntax.

Hmm. I don't understand that. Maybe it's because English is not my native language. Even with Deepl I don't get behind the sense of this statement. Would you explain this to me?

Much of the required logic is likely already set up. I'd suggest studying what this plugin is already doing and compare with the PR I linked previously from core.

I have already started with it in a free moment. I have understood some of it, but not everything yet. I'll have to set up some more time for that. It's super helpful that I can build on this. Thank you!

@brandonmcconnell
Copy link
Author

@christian-wantia Sure! Please excuse my "most" — I only meant to clarify a few points, and I can respond to your questions below 🙂

  • Most of that is correct!
    Cool. What do I need to correct in my mental model? (because you wrote „most“)

    Nothing in particular. I thought that doing something like min-[100px]:max-[200px] actually generated @media (min-width: 100px) and not (min-width: 200px), but it appears I was mistaken and that your assumption there was correct. That should already be set up in the plugin and can be reused without redefining this functionality.

  • Re the syntax discovery phase, let's stick with the two syntax options proposed earlier in my original post.
    Okay. Do you have an idea, how we can integrate the design tokens (md, xl, …) in your syntax?

    Yes, the syntax for all these breakpoints would be as follows:

    Syntax Example
    @sm:
    @sm:underline
    @max-sm:
    @max-sm:underline
    @min-[?]:
    @min-[100px]:underline
    @max-[?]:
    @max-[200px]:underline
  • The existing syntax should likely be deprecated to support the new syntax exclusively to be inform with the core syntax.
    Hmm. I don't understand that. Maybe it's because English is not my native language. Even with Deepl I don't get behind the sense of this statement. Would you explain this to me?

    Sure, this is the syntax we would deprecate and what it would be replaced with:

    Before After
    Syntax
    @[?]:
    @min-[?]:
    Example
    @[100px]:
    @min-[100px]:
  • Much of the required logic is likely already set up. I'd suggest studying what this plugin is already doing and compare with the PR I linked previously from core.
    I have already started with it in a free moment. I have understood some of it, but not everything yet. I'll have to set up some more time for that. It's super helpful that I can build on this. Thank you!

    That sounds great! It's really great to have someone else interested in seeing this implemented and collaborating on the fix. Please let me know if you have any other questions that I can help to clarify or think through together.

@christian-wantia
Copy link

Very nice. Thank you. Now I see much clearer. :-)

So do I understand it correctly that the intended syntax for both - viewport (screen) and container queries - is now the following? Except that the container queries get an @ sign in front, and can get a name?

(The round brackets are there to signal that the @ is optional.)

  • Mobile first: w-16 (@)min-md:w-32 (@)min-lg:w-48
  • Breakpoint range: (@)min-md:max-xl:flex
  • Single breakpoint: (@)min-md:max-lg:flex
  • Arbitrary values: (@)max-[600px]:bg-sky-300

BTW: Was it a conscious decision that the variant with design tokens (max-lg) behaves differently at the last pixel than the variant with arbitrary values (max-[600px])?

  • Regular: @min-lg:underline
  • Named containers: @min-lg/main:underline
  • Arbitrary container sizes: @min-[17.5rem]:underline

How do we integrate the width/height distinction? For the arbitrary values, the h: and w: would work inside the square brackets. But how do we implement that for the design tokens?

After the colon there are already the utilities min-h-*, max-h-*, min-w-* and max-w-*. Do we have to choose a different syntax on the left side of the colon?


Oh yes, I am very interested. I just hope I can make it work. Because I'm not a full time developer. Normally I'm more of a product owner or scrum master type. But in this case, I'd like to try it myself.

@brandonmcconnell
Copy link
Author

brandonmcconnell commented Jul 16, 2023

@christian-wantia For non-arbitrary men sizes, it would just be @lg:.

For the w/h distinction (only available for arbitrary values), that's where the w:/h: comes in, e.g.: min-[h:100px]. That distinction is totally optional, though, and if omitted, it defaults to using the width.

For guidance on implementing that inner-bracket detail, see my related PR here: tailwindlabs/tailwindcss#11225

@christian-wantia
Copy link

I hope I'm not straining your nerves too much. But before I can get to work on the implementation, I need clarity.

Moreover, I am not completely free of my own and third party interests. Therefore, I would like to at least check if our ideas match those of the Tailwind project.

For non-arbitrary min sizes, it would just be @lg:.

Okay. Exclusively @lg:, or optionally also @min-lg:?

I am in favor of allowing both. This makes the code more readable when min and max are used side by side.

For the w/h distinction (only available for arbitrary values)

Is there anything against allowing the height for the design token variant as well?

I think it's great that we can quickly try out arbitrary values when developing a design system. But ultimately, at least I always strive to systematize sizes.

BTW: Was it a conscious decision that the variant with design tokens (max-lg) behaves differently at the last pixel than the variant with arbitrary values (max-[600px])?

I was very surprised when I noticed that the two variants behave differently. Therefore, I ask if there is a reason for this.

@brandonmcconnell
Copy link
Author

@christian-wantia Not at all — I appreciate you seeking clarity on all this!

For non-arbitrary min sizes, it would just be @lg:.

Okay. Exclusively @lg:, or optionally also @min-lg:?

As they should match the syntax, supported by the court package, the intention, at least, for this issue is to support the former, but not the latter for named (non-arbitrary) usage.

For example, in core TailwindCSS, lg:hidden will work, but min-lg:hidden will not.

While it could be more uniform to support min/max, in all cases, I doubt the core team would want to support two alternative syntax is for the same functionality, and the existing option is more concise.

For the w/h distinction (only available for arbitrary values)

Is there anything against allowing the height for the design token variant as well?

I think it's great that we can quickly try out arbitrary values when developing a design system. But ultimately, at least I always strive to systematize sizes.

Syntax like (min/max)-(w/h)- would be in direct conflict the existing utilities of the same name for their related property uses (not media/container queries).

Besides, there's a drastically smaller use case for named height queries vs. width queries. In many cases, even when there is a simple solution available, the core team avoids implementing features that don't have reasonable IRL uses.

For example, they recently implemented utilities like h-dvh but intentionally omitted w-dvw as it's not a utility with any real use cases.
tailwindlabs/tailwindcss#11317

BTW: Was it a conscious decision that the variant with design tokens (max-lg) behaves differently at the last pixel than the variant with arbitrary values (max-[600px])?

I was very surprised when I noticed that the two variants behave differently. Therefore, I ask if there is a reason for this.

I think I may know the difference you're speaking of, but to validate my assumption, could you please clarify the difference you noticed?

@christian-wantia
Copy link

Sorry, @brandonmcconnell, for getting back to you so late - and then without good news.

After our last exchange, one by one my son, myself, my daughter and my wife got sick. This has put me behind in business. And in the meantime, our business has evolved, so I don't have time for side projects at the moment.

With a little luck, next year I will not only have time for side projects again myself, but I may even be able to sponsor some work time.

Thanks for your support in my attempt to understand the connections.

@leo-cheron
Copy link

@christian-wantia do you think the PR proposed by @brandonmcconnell could be reviewed and eventually merged?

@brandonmcconnell
Copy link
Author

@leo-cheron That PR isn't directly related to this issue, but rather it includes an improvement to standard media query variants to support height, in addition to width.

I would encourage you to follow up in that PR's thread directly.

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

Successfully merging a pull request may close this issue.

4 participants