DEV Community

Cover image for Conditionally style elements in Turbo Frames with Tailwind Css
Eelco from Spinal for Spinal

Posted on

Conditionally style elements in Turbo Frames with Tailwind Css

Part of Hotwire are Turbo Frames. They allow you to insert a page, or just a part of it, into another page.

I've found this feature quite magical when it was released. 🪄

But it would be useful to apply some Css conditionally, based if the page was viewed standalone or within a turbo frame.

Previously, and still valid, way to do this was adding a wrapper/container class around the turbo-frame and nested the css within here.

With Tailwind Css this is easier to do. Let's take the following example from Helptail (Spinal's internally developed email support tool for calm SaaS companies):

This is the email composer on a standalone page.

The standalone page with the email composer

The the same page, but within a turbo frame:

The email composer shown in a turbo-frame

Notice how certain elements are not shown and some things look different. The changes in this example are basic for demonstration purposes, but you can imagine making it look completely different for each variant (similar how you would with the dark-variant).

How to do this

Set up a new variant in your Tailwind Css' config file, like so:

module.exports = {
// …
  plugins: [
    // …
    function ({ addVariant }) {
      addVariant('turbo-frame', 'turbo-frame[src] &')
    }
  ]
// …
}
Enter fullscreen mode Exit fullscreen mode

How it works: turbo-frame[src] matches a turbo-frame with any value for the src attribute. Check this mdn article for all the details. And refer to the Tailwind docs about the addVariant function.

Note: you can change the variant name to something else than turbo-frame, like inside-frame for example.

You now have the turbo-frame:-variant. It can be used in the same way as md:, dark:, etc.

<div class="block turbo-frame:hidden">
  <label for="from">From</label>
  <input type="email" name="email" id="email" />
</div>
Enter fullscreen mode Exit fullscreen mode

So above <div>-element will be visible on the standalone page and be hidden when shown within a turbo-frame.

And that is all there's to it. You can now create one page that can look completely different from when loaded in a turbo-frame.

Top comments (1)

Collapse
 
janmpeterka profile image
Jan Peterka

Thanks, this helped me!

It took me a while to make it work for my case, I needed to change it to addVariant('turbo-frame', 'turbo-frame[src]&') (without the space before &).