{"id":14990564,"url":"https://github.com/mt-bt/cljs-css-modules","last_synced_at":"2025-12-30T01:33:51.485Z","repository":{"id":62435309,"uuid":"60302103","full_name":"matthieu-beteille/cljs-css-modules","owner":"matthieu-beteille","description":"CSS modules in ClojureScript.","archived":false,"fork":false,"pushed_at":"2017-05-22T19:55:38.000Z","size":25,"stargazers_count":59,"open_issues_count":4,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T02:24:49.920Z","etag":null,"topics":["clj","clojure","clojurescript","css-modules","garden","macros"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matthieu-beteille.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-02T22:42:10.000Z","updated_at":"2024-05-31T07:52:12.000Z","dependencies_parsed_at":"2022-11-01T20:46:03.874Z","dependency_job_id":null,"html_url":"https://github.com/matthieu-beteille/cljs-css-modules","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-beteille%2Fcljs-css-modules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-beteille%2Fcljs-css-modules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-beteille%2Fcljs-css-modules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-beteille%2Fcljs-css-modules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthieu-beteille","download_url":"https://codeload.github.com/matthieu-beteille/cljs-css-modules/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248506316,"owners_count":21115416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clj","clojure","clojurescript","css-modules","garden","macros"],"created_at":"2024-09-24T14:20:23.124Z","updated_at":"2025-12-30T01:33:51.444Z","avatar_url":"https://github.com/matthieu-beteille.png","language":"Clojure","readme":"# Css Modules in ClojureScript\n\n[![Clojars Project](https://img.shields.io/clojars/v/cljs-css-modules.svg)](https://clojars.org/cljs-css-modules)\n\nFirst if you don't know what's a css modules, you should definitely read the specification:\nhttps://github.com/css-modules/css-modules\n\nUsing cljs-css-modules, you won't write pure CSS, but you'll use [garden](https://github.com/noprompt/garden) syntax to write your style in ClojureScript.   \n([Garden](https://github.com/noprompt/garden) basically allows you to use any feature of pure css, so no worries you're not losing any power here).\n\nThe idea of cljs-css-modules is to localise every classes (and soon animations) you define through the ```defstyle``` macro.\n\n## Example Project\n\ngmp26 put together a repository porting a css-modules project over to a cljs-css-modules/cljs one.\n\nYou can check it out, to see how this library can be used in a real project:\n\n- Original JS Repo:\nhttps://github.com/css-modules/webpack-demo\n- CLJS Repo:\nhttps://github.com/gmp26/css-modules-tester\n\n## Usage\n\nAdd this to your ```project.clj```:  \n\n\u003cimg src=\"https://clojars.org/cljs-css-modules/latest-version.svg\"/\u003e\n\nYou need to define your style using the ```defstyle``` macro.\n\nYour style will be written using [garden](https://github.com/noprompt/garden) syntax, so spend some time reading the [doc](https://github.com/noprompt/garden).\n\nEach time you'll define some style using ```defstyle```, this style will be localised (every classes and animations), translated to CSS,\nand automatically injected into the ```\u003chead\u003e``` tag. This works perfectly with figwheel, and you'll get live style reloading out of the box.\n\n(If you come from the javascript world and you've used webpack before, it replaces both *css-loader* and *style-loader*).\n\n*Example:*\n\nDefine your style:\n\n```Clojure\n(ns yourapp.namespace1\n  (:require [cljs-css-modules.macro :refer-macros [defstyle]]))\n\n(defstyle style\n\n  (at-media {:max-width \"200px\"}\n\n            [\".mobile-style-1\" {:margin \"5px\"}]\n\n            [\".mobile-style-2\" {:margin \"10px\"}])\n\n  [\".container\" {:background-color \"blue\"\n                  :font-size 55}\n    [\"a\" {:color \"green\"}]\n    [\"\u0026:hover\" {:background-color \"black\"}]]\n\n   [\".text\" {:font-size 14\n             :color \"brown\"}]\n\n   (at-keyframes \"keyframe-1\" [:from {:a 50}]\n                          [:to  {:b 50}])\n\n   [\"@keyframes keyframe-2\" [:from {:a 50}]\n                          [:to  {:b 50}]]\n\n   [\".title\" {:background-color \"blue\"\n              :font-size 60}]\n\n   [\".title2\" {:font-size 40\n               :color \"red\"}])\n```\n\nThe localised classes/keyframes will be available in the style object created.\n(Note: including classes in media queries).\n\n```Clojure\n(:container style) ;; =\u003e returns the unique generated class for \".container\"\n(:mobile-style-1 style) ;; =\u003e returns the unique generated class for \".mobile-style-1\"\n```\n\nTo use your style, you just need to inject them wherever you need:\n\nFor instance with reagent:\n\n```Clojure\n(defn simple-component []\n  [:div {:class-name (:container style)}\n   [:h1 {:class-name (:title style)} \"I am a big title\"]\n   [:h1 {:class-name (:title2 style)} \"I am smaller title\"]\n   [:p {:class-name (:text style)}\n    \"Here goes some random text\"]])\n```\n## Media queries\n\nTo define a media query you need to use the ```(at-media)``` form, and nest your style in it.\nIt's the same as garden's syntax, here is the documentation:\nhttps://github.com/noprompt/garden/wiki/Media-Queries\n\nExample:\n\n```Clojure\n(defstyle style\n  (at-media {:max-width \"400px\"}\n\n            [\".mobile-style\" {:margin \"5px\"}])\n\n  (at-media {:min-width \"400px\"\n             :max-width \"800px\"}\n\n            [\".tablet-style-1\" {:margin \"5px\"}]\n\n            [\".tablet-style-2\" {:margin \"10px\"}]))\n```\n\nThis will localise all the classes in your media queries, here: .mobile-style, .tablet-style-1, .tablet-style-2.\n\nNote:\nUsing cljs-css-modules, you don't need to import the at-media function from garden's library. The macro will recognise the at-media symbol.\n\n## Keyframes\n\nTo define an animation you need to use the ```(at-keyframes)``` form, or a string like \"@keyframes animation-name\":\n\nExample:\n\n```Clojure\n(defstyle style\n\n  (at-keyframes \"animation-1\"\n                [:from {:top \"0px\"}]\n                [:to {:top \"200px\"}])\n\n  (at-keyframes \"animation-2\"\n                [:from {:top \"0px\"}]\n                [:to {:top \"250px\"}])\n\n  [\"@keyframes animation-3\" [:from {:top \"0px\"}]\n                            [:to {:top \"250px\"}]])\n```\n\nThis will localise all the animations, here: animation-1, animation-2, animation-3.\n\nNote:\nUsing cljs-css-modules, you don't need to import the at-keyframes function from garden's library. The macro will recognise the at-keyframes symbol.\n\n## From Clojure\n\nIf you use the macro from clojure (and not clojurescript), it will define a map containing both the generated css and the map between original selectors and localised selectors.\n\n```Clojure\n(defstyle style\n\n  {:pretty-print? false}\n\n  (at-keyframes \"animation-1\"\n                [:from {:top \"0px\"}]\n                [:to {:top \"200px\"}])\n\n  (at-keyframes \"animation-2\"\n                [:from {:top \"0px\"}]\n                [:to {:top \"250px\"}])\n\n  [\"@keyframes animation-3\" [:from {:top \"0px\"}]\n                            [:to {:top \"250px\"}]])\n```\n\nIn this case style would be the following map:\n\n```Clojure\n{:map {:animation-1 \"animation-1--G__1524\"\n       :animation-2 \"animation-2--G__1524\"\n       :animation-3 \"animation-3--G__1524\"}\n :css \"@keyframes animation-1--G__1524{from{top:0}to{top:200px}}@keyframes animation-2--G__1524{from{top:0}to{top:250px}}@keyframes animation-3--G__1524{from{top:0}to{top:250px}}\"}\n```\n\nYou can then do whatever you want with these, and use it for you server side rendered apps!\n\n## Note\n\nYou might want to consider https://github.com/mhallin/forest which is not based on garden and provides the same kind of features using its own DSL.\n\n## License\n\nCopyright © 2016 Matthieu Béteille\n\nDistributed under the Eclipse Public License version 1.0\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmt-bt%2Fcljs-css-modules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmt-bt%2Fcljs-css-modules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmt-bt%2Fcljs-css-modules/lists"}