Instantly share code, notes, and snippets.
Last active
December 31, 2021 08:01
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save chipx86/11a5f1eb696039fbf1a1a66719281689 to your computer and use it in GitHub Desktop.
CardStock: Experiments in layered component-based CSS generation and LessCSS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Layer 1: Button structure factory | |
*/ | |
#cs-ns-widget-structures() { | |
/** | |
* Mixins for creating button structures. | |
*/ | |
.button() { | |
/** | |
* Create a button structure. | |
* | |
* This will construct rules to place in a button-like component. Rules | |
* can be provided for the button or for various button states (on-hover, | |
* disabled, primary buttons, and dangerous buttons). | |
* | |
* If any of those provided, suitable rules will be added to enable those | |
* states. | |
* | |
* DOM Attributes: | |
* disabled: | |
* The button is disabled. This will be added if ``@disabled-rules`` | |
* are provided. Alternatively, set the ``-is-disabled`` attribute. | |
* | |
* Modifiers: | |
* -is-danger: | |
* The button performs a dangerous action. This will be added if | |
* ``@danger-rules`` are provided. | |
* | |
* -is-disbled: | |
* The button is disabled. This will be added if ``@disabled-rules`` | |
* are provided. Alternatively, set the ``disabled`` attributes. | |
* | |
* -is-primary: | |
* The button performs a primary action. This will be added if | |
* ``@primary-rules`` are provided. | |
* | |
* -js-hover: | |
* The button is in a hover state. This can be used by JavaScript | |
* to simulate hovering over the button (if, for example, a sibling | |
* component is currently being hovered over). | |
* | |
* This will be added if ``@hover-rules`` are provided. | |
* | |
* Args: | |
* @main-rules (ruleset, optional): | |
* Theme rules for the main ``cs-c-button``. | |
* | |
* @hover-rules (ruleset, optional): | |
* Theme rules for when the user hovers over a button. | |
* | |
* @danger-rules (ruleset, optional): | |
* Theme rules for the button when using the ``-is-danger`` | |
* modifier. | |
* | |
* @disabled-rules (ruleset, optional): | |
* Theme rules for the button is disabled. | |
* | |
* @primary-rules (ruleset, optional): | |
* Theme rules for primary buttons. | |
*/ | |
.create(@main-rules: null; | |
@hover-rules: null; | |
@danger-rules: null; | |
@disabled-rules: null; | |
@primary-rules: null) { | |
#cs-ns-widget-factory.base(); | |
.add-rules(@main-rules); | |
&:hover, | |
.js-hover { | |
.add-rules(@hover-rules); | |
} | |
&.-is-danger { | |
.add-rules(@danger-rules); | |
} | |
&[disabled], | |
&.-is-disabled { | |
.add-rules(@disabled-rules); | |
} | |
&.-is-primary { | |
.add-rules(@primary-rules); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Layer 2: Component component creator/styler | |
*/ | |
@import (reference) "button-structure.less"; | |
#cs-ns-widgets() { | |
/** | |
* Mixins for creating and styling button widgets. | |
*/ | |
.button() { | |
/** | |
* Create a cs-c-button component. | |
* | |
* This should be called by the theme to construct the styled rules for | |
* ``cs-c-button``. | |
* | |
* DOM Attributes: | |
* disabled: | |
* The button is disabled. This will be added if ``@disabled-rules`` | |
* are provided. Alternatively, set the ``-is-disabled`` attribute. | |
* | |
* Modifiers: | |
* -is-danger: | |
* The button performs a dangerous action. This will be added if | |
* ``@danger-rules`` are provided. | |
* | |
* -is-disbled: | |
* The button is disabled. This will be added if ``@disabled-rules`` | |
* are provided. Alternatively, set the ``disabled`` attributes. | |
* | |
* -is-primary: | |
* The button performs a primary action. This will be added if | |
* ``@primary-rules`` are provided. | |
* | |
* -js-hover: | |
* The button is in a hover state. This can be used by JavaScript | |
* to simulate hovering over the button (if, for example, a sibling | |
* component is currently being hovered over). | |
* | |
* This will be added if ``@hover-rules`` are provided. | |
* | |
* Args: | |
* @main-rules (ruleset, optional): | |
* Theme rules for the main ``cs-c-button``. | |
* | |
* @hover-rules (ruleset, optional): | |
* Theme rules for when the user hovers over a button. | |
* | |
* @danger-rules (ruleset, optional): | |
* Theme rules for the button when using the ``-is-danger`` | |
* modifier. | |
* | |
* @disabled-rules (ruleset, optional): | |
* Theme rules for the button is disabled. | |
* | |
* @primary-rules (ruleset, optional): | |
* Theme rules for primary buttons. | |
*/ | |
.create(@main-rules: null; | |
@hover-rules: null; | |
@danger-rules: null; | |
@disabled-rules: null; | |
@primary-rules: null) { | |
.cs-c-button { | |
#cs-ns-widget-structures.button.create( | |
@main-rules: { | |
cursor: pointer; | |
display: inline-block; | |
line-height: normal; | |
text-decoration: none; | |
.add-rules(@main-rules); | |
}; | |
@hover-rules: { | |
text-decoration: none; | |
.add-rules(@hover-rules); | |
}; | |
@danger-rules: @danger-rules; | |
@disabled-rules: @disabled-rules; | |
@primary-rules: @primary-rules | |
); | |
} | |
button, | |
input[type="button"], | |
input[type="submit"] { | |
&:extend(.cs-c-button all); | |
} | |
} | |
/** | |
* Style an existing cs-c-button. | |
* | |
* This can be used to add new theme rules to top-level or nested | |
* ``cs-c-button``, with or without a media selector. | |
* | |
* Args: | |
* @media (string, optional): | |
* An optional media selector for these styles. | |
* | |
* @main-rules (ruleset, optional): | |
* Theme rules for the main ``cs-c-button``. | |
* | |
* @hover-rules (ruleset, optional): | |
* Theme rules for when the user hovers over a button. | |
* | |
* @danger-rules (ruleset, optional): | |
* Theme rules for the button when using the ``-is-danger`` | |
* modifier. | |
* | |
* @disabled-rules (ruleset, optional): | |
* Theme rules for the button is disabled. | |
* | |
* @primary-rules (ruleset, optional): | |
* Theme rules for primary buttons. | |
*/ | |
.style(@media: null; | |
@main-rules: null; | |
@hover-rules: null; | |
@danger-rules: null; | |
@disabled-rules: null; | |
@primary-rules: null) { | |
#cs-ns-widget-factory.base.for-media( | |
@media: @media; | |
@rules: { | |
.cs-c-button { | |
#cs-ns-widget-structures.button.create( | |
@main-rules: @main-rules; | |
@hover-rules: @hover-rules; | |
@danger-rules: @danger-rules; | |
@disabled-rules: @disabled-rules; | |
@primary-rules: @primary-rules; | |
); | |
} | |
} | |
); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Layer 3: Button theme and CSS generation | |
*/ | |
@import (reference) "button-component.less"; | |
#cs-ns-widgets.button.create( | |
@main-rules: { | |
background: grey; | |
border: 1px outset solid; | |
}; | |
@hover-rules: { | |
background: blue; | |
}; | |
@danger-rules: { | |
font-size: 500%; | |
background: red; | |
color: white; | |
}; | |
); | |
/* Let's make a dark mode version. */ | |
#cs-ns-widgets.button.style( | |
@media: ~"prefers-color-scheme: dark"; | |
@main-rules: { | |
color: white; | |
background: black; | |
}; | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import (reference) "button-structure.less"; | |
@import (reference) "button-component.less"; | |
/* Let's specialize the hover state of any nested buttons in this class. */ | |
.something-specializing-button { | |
#cs-ns-widgets.button.style( | |
@hover-rules: { | |
background: orange; | |
color: red; | |
} | |
); | |
} | |
/* | |
* Let's make something that is not a cs-c-button, but is structured like one, | |
* with nothing but primary button rules. | |
*/ | |
.something-button-like { | |
#cs-ns-widget-structure.button.create( | |
@main-rules: { | |
border: 1px blue solid; | |
color: blue; | |
}; | |
@primary-rules: { | |
background: yellow; | |
}; | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* @main-rules */ | |
.cs-c-button, | |
button, | |
input[type="button"], | |
input[type="submit"] { | |
cursor: pointer; | |
display: inline-block; | |
line-height: normal; | |
text-decoration: none; | |
background: grey; | |
border: 1px outset solid; | |
} | |
/* @hover-rules */ | |
.cs-c-button:hover, | |
.cs-c-button .js-hover, | |
button:hover, | |
button .js-hover, | |
input[type="button"]:hover, | |
input[type="button"] .js-hover, | |
input[type="submit"]:hover, | |
input[type="submit"] .js-hover { | |
text-decoration: none; | |
background: blue; | |
} | |
/* @danger-rules */ | |
.cs-c-button.-is-danger, | |
button.-is-danger, | |
input[type="button"].-is-danger, | |
input[type="submit"].-is-danger { | |
font-size: 500%; | |
background: red; | |
color: white; | |
} | |
/* Dark mode styling */ | |
@media (prefers-color-scheme: dark) { | |
.cs-c-button, | |
button, | |
input[type="button"], | |
input[type="submit"] { | |
color: white; | |
background: black; | |
} | |
} | |
/* Let's specialize the hover state of any nested buttons in this class. */ | |
.something-specializing-button .cs-c-button:hover, | |
.something-specializing-button .cs-c-button .js-hover, | |
.something-specializing-button button:hover, | |
.something-specializing-button button .js-hover, | |
.something-specializing-button input[type="button"]:hover, | |
.something-specializing-button input[type="button"] .js-hover, | |
.something-specializing-button input[type="submit"]:hover, | |
.something-specializing-button input[type="submit"] .js-hover { | |
background: orange; | |
color: red; | |
} | |
/* | |
* Let's make something that is not a cs-c-button, but is structured like one, | |
* with nothing but primary button rules. | |
*/ | |
.something-button-like { | |
border: 1px blue solid; | |
color: blue; | |
} | |
.something-button-like.-is-primary { | |
background: yellow; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment