Closed GesJeremie closed 9 years ago
You could argue that inheritance is redundant since we have options. However I agree with you that this would be nice to have while trying to think CSS in terms of OOP.
In native Sass you can write
@extend .button;
which works as you'd expect.
Unfortunately it doesn't seem to work to pass function returns to the @extend directive, without escaping:
@function component($name) {
@return #{'.#{$name}'};
}
@extend component(button); // DOES NOT WORK
@extend #{component(button)}; // DOES WORK
Moreover, one could consider maybe a second argument to the component mixin:
@include component(submit, button) {
//
}
This would of course do the @extend #{$extend}
behind the scenes.
Or maybe, if we are focusing on explicit, comfortable syntax, we could have an extends
function, which just passes the parent component name to the said second argument:
@include component(submit, extends(button)) {
//
}
I would love to see an intuitive way to do this while preserving the clear syntax of csstyle.
Thanks @GesJeremie, this is a use case I hadn't thought of. Some good ideas there from @emilniklas. I especially like the explicit extends(parent)
idea. Let me play around with a few ideas and get back to you. Happy to hear additional input as well.
Here's one way we could accomplish this:
@mixin inherit($name){
@extend .#{$name};
}
@include component(fancytweet){
@include inherit(tweet);
color: blue;
}
Hmm. I wonder what the most commonly used term for this is. I personally like extends more than inherits. But maybe if we're breaking it out from the component
mixin, inherit is a more descriptive word.
Reading out "include" before whatever word we choose, for me, is relevant somehow. It seems "include extends" is just as weird as "include inherits". Another option might be "include parent". Hmm...
Maybe that ? (.sass) :
@include component(fancytweet)
@include use(tweet)
color: blue
or
@include component(fancytweet)
@include base(tweet)
color: blue
or
@include component(fancytweet)
@include version(tweet)
color: blue
or
@include component(fancytweet)
@include _(tweet)
color: blue
Once more we should be clear on when to use this instead of options. In @GesJeremie's example a fancy tweet should be .tweet.--fancy, right?
For me, that stuff is not an option, i don't know how we can do, but for example I finished a button component :
// ===========================================================
// Component Button (v.1.0)
// ===========================================================
//
// UI button component for csstyle.io
//
// Copyright (c) 2015 Ges Jeremie
// http://www.gesjeremie.fr/
//
// ===========================================================
// Config
// ===========================================================
$csstyle-button-namespace: "button" !default
$csstyle-button-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !default
$csstyle-button-font-weight: 300 !default
$csstyle-button-base-font-size: 15px !default
$csstyle-button-base-padding-top-bottom: 6px !default
$csstyle-button-base-padding-right-left: 12px !default
// ===========================================================
// Mixins
// ===========================================================
=csstyle-button-variant($background, $color, $border)
background-color: $background
color: $color
border-color: $border
=csstyle-button-size($font-size, $padding-top-bottom, $padding-right-left)
font-size: $font-size
padding: $padding-top-bottom $padding-right-left
// ===========================================================
// Component
// ===========================================================
@include component($csstyle-button-namespace)
// ===========================================================
// Default part
// ===========================================================
font-family: $csstyle-button-font-family
font-weight: $csstyle-button-font-weight
cursor: pointer
text-decoration: none !important
-ms-touch-action: manipulation
touch-action: manipulation
cursor: pointer
-webkit-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none
border-radius: 5px
border: 1px solid transparent
+csstyle-button-variant(#d6e1e5, #5e696d, #d6e1e5)
+csstyle-button-size($csstyle-button-base-font-size, $csstyle-button-base-padding-top-bottom, $csstyle-button-base-padding-right-left)
&:hover,
&:focus,
&:active,
outline: 0
+csstyle-button-variant(#e1eef3, #5e696d, #e1eef3)
// ===========================================================
// Sizes
// ===========================================================
// extra small button
@include option(xs)
+csstyle-button-size($csstyle-button-base-font-size * 0.8, $csstyle-button-base-padding-top-bottom * 0.6, $csstyle-button-base-padding-right-left * 0.6)
// small button
@include option(sm)
+csstyle-button-size($csstyle-button-base-font-size * 0.8, $csstyle-button-base-padding-top-bottom * 0.8, $csstyle-button-base-padding-right-left * 0.8)
@include option(md)
+csstyle-button-size($csstyle-button-base-font-size, $csstyle-button-base-padding-top-bottom, $csstyle-button-base-padding-right-left)
// large button
@include option(lg)
+csstyle-button-size($csstyle-button-base-font-size * 1.2, $csstyle-button-base-padding-top-bottom * 1.2, $csstyle-button-base-padding-right-left * 1.2)
// extra large button
@include option(xl)
+csstyle-button-size($csstyle-button-base-font-size * 1.4, $csstyle-button-base-padding-top-bottom * 1.6, $csstyle-button-base-padding-right-left * 1.6)
// ===========================================================
// Block
// ===========================================================
@include option(block)
width: 100%
display: inline-block
// ===========================================================
// Colors
// ===========================================================
// Default
@include option(default)
+csstyle-button-variant(#d6e1e5, #5e696d, #d6e1e5)
&:hover,
&:active,
&:focus
+csstyle-button-variant(#e1eef3, #5e696d, #e1eef3)
// Success
@include option(success)
+csstyle-button-variant(#3eb5ac, #fff, #3eb5ac)
&:hover,
&:active,
&:focus
+csstyle-button-variant(#45c8be, #fff, #45c8be)
// Primary
@include option(primary)
+csstyle-button-variant(#02baf2, #fff, #02baf2)
&:hover,
&:active,
&:focus
+csstyle-button-variant(#0fc7ff, #fff, #0fc7ff)
// Info
@include option(info)
+csstyle-button-variant(#a88cd5, #fff, #a88cd5)
&:hover,
&:active,
&:focus
+csstyle-button-variant(#b094de, #fff, #b094de)
// Warning
@include option(warning)
+csstyle-button-variant(#f58410, #fff, #f58410)
&:hover,
&:active,
&:focus
+csstyle-button-variant(#ff9324, #fff, #ff9324)
// Danger
@include option(danger)
+csstyle-button-variant(#f84545, #fff, #f84545)
&:hover,
&:active,
&:focus
+csstyle-button-variant(#ff5f5f, #fff, #ff5f5f)
// ===========================================================
// Disabled
// ===========================================================
// Disabled
@include option(disabled)
pointer-events: none
cursor: not-allowed
filter: alpha(opacity=65)
opacity: .65
// ===========================================================
// Icon
// ===========================================================
@include option(icon)
i
padding-right: 3px
When i will release that code on github, people will get the possibility to download and import the component in their projects via bower.
For sure someone will want to add new colors or new sizes, I imagine something like that :
@include component(mybutton)
// Here we import all options, part of the base button
@include clone(button)
// Now we can add parts or options
@include option(xxl)
+csstyle-button-size($csstyle-button-base-font-size * 2, $csstyle-button-base-padding-top-bottom * 1.6, $csstyle-button-base-padding-right-left * 1.8)
Make sense ?
So I just released my first component : http://csstyle-components.github.io/button/, and i'm waiting for other replies for that "issue", I think it's really important.
Very interested in this. A system to allow sharing and extending / modifying seems awesome
@GesJeremie I thought of another simple way to accomplish this:
For example, let's say this is your base button definition:
@include component(button){
background: blue;
@include option(active){
background: yellow;
}
}
You can override any style of this base definition, and even add additional options like so:
@include component(button){
@include option(warning){
background: red;
}
}
Notice that we didn't need to extend
or inherit
anything. The combined generated output of these files would then be:
.button {
background: blue;
}
.button.\--active {
background: yellow;
}
.button.\--warning {
background: red;
}
What do you think? The only gotcha would be making sure that the base styles are included before the user styles.
PS awesome project you're working on!
@geddski I didn't try that but it make sense. Sounds perfect and already done ahaha :)
For my job, i'm creating some base components (button, well, form, etc ...) to have a fresh UI when I start a new project.
For sure I will edit some components to match with the current design of the application I will build.
So I wanted to know how to extend a component (clean way).