mhallin / forest

CSS modules for Clojurescript
MIT License
63 stars 3 forks source link

Support for Media Queries #8

Open jupl opened 7 years ago

jupl commented 7 years ago

I've been looking for a CLJSy approach to CSS instead of inline styles. This nearly fits the bill with the exception of media queries. I assume it's not a simple solution and the syntax approach can vary, so I wanted to leave it open for thoughts/recommendations.

mhallin commented 7 years ago

Yeah, media queries would be nice. Some immediate ideas I get are:

  1. Add metadata to the defstylesheet tag itself:
    (defstylesheet mobile-styles
    {:media {:max-width "767px"}}
    [.my-class {:font-weight "bold"}])
  2. Add :media as a "magic" CSS selector:
    (defstylesheet all-styles
    [:media {:max-width "767px"}
            {:font-weight "bold"}])
  3. Add :media as a "magic" CSS property that's actually a sub-stylesheet:
    (defstylesheet all-styles
    [.my-class {:media [{:max-width "767px"}
                        {:font-weight "bold"}]}])

Of course, the detailed syntax is just a suggestion, but the general idea is that alternative 1 would provide the most isolation between different media classes, while alternative 3 would let you mix them freely inside a selector even.

From my experience, both ways are convenient at different times; if you just want to restyle a button for larger screens you usually just do it in-place, Sass style. However, if you want to change the entire layout or group together all mobile related styles, you go for something closer to raw CSS.

For this library, I don't really know what's most desirable. Maybe something like alternative 2 fits best in the CSS Modules way of thinking, though I'm not a big fan of having magic selectors/keywords.

statianzo commented 7 years ago

Option 1 reads the clearest to me and maps close to the output css:

@media(max-width: 767px) {
  .my-class {
    font-weight: bold;
  }
}

Option 1 would need to handle duplicate class names across stylesheets. For example, what's the generated class name of my-class when it's selected in both all-styles and mobile-styles stylesheets?

Option 2 does feel odd with the magical selector.

Option 3 would require either trying to intelligently group selectors inside a @media or having a separate @media for each selector.

jupl commented 7 years ago

I haven't had a chance to go in detail code wise but if option 1 is used I assume there would be no name clash if I use a class name in two stylesheets where one would be a media query?

(defstylesheet all-styles
  [.my-class {:font-size "1.2rem"}])

(defstylesheet mobile-styles
  {:media {:max-width "767px"}}
  [.my-class {:font-weight "bold"}])

Also what kind of syntax would be used for things like logical operators, aspect ratio, all, print, etc.? If it would be a big burden on forest to handle this perhaps the media query would be represented as a string?

https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries

EDIT: Garden looks like they have one way of handling this. https://github.com/noprompt/garden/wiki/Media-Queries