Skip to content

Instantly share code, notes, and snippets.

@espadrine
Created September 9, 2014 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save espadrine/775dac4b06af0cb49ee8 to your computer and use it in GitHub Desktop.
Save espadrine/775dac4b06af0cb49ee8 to your computer and use it in GitHub Desktop.
Classoid
Arguably, in `page.inadequate.css`, this `.left` class should be `.block.left`, and `.right-on-hover` ought to be `.block.right-on-hover`, or something like that.
Still, creating name conflicts is a trap made hard to avoid.
Using namespaces eases the process. Classoids provide hierarchical classes. In this example, our rules related to `left` specifically on a `button` only apply on a `button` classoid; the `left` class does not apply to it. This avoids the name clashing.
(Unfortunately, CSS namespaces is already a thing, extended from XML namespaces, not what we want. I picked the term "classoid", because it is like a class.)
The example is contrived, but the problem is present. See also the last slides here <http://www.slideshare.net/stubbornella/object-oriented-css>.
/* I am not sure that syntax would be compatible with CSS. Look at the semantic. */
/button {
/* Base button style */
display: inline-block;
line-height: normal;
white-space: nowrap;
vertical-align: baseline;
cursor: pointer;
text-decoration: none;
padding: 0.5em 1em;
}
/button(middle) {
text-align: center;
}
/button(left) {
text-align: left;
}
/button(left(right-on-hover)):hover {
text-align: right;
}
/button(rounded) {
border-radius: 4px;
}
/button(squared) { /* … */ }
/text-outline {
text-shadow: 1px 1px 0px black, 1px -1px 0px black,
-1px 1px 0px black, -1px -1px 0px black;
}
<!-- Somewhere we have this style: -->
<div classoid="button(middle) text-outline"> Click me </div>
<!-- Somewhere else: -->
<div classoid="button(middle squared)"> Click me </div>
<!-- Yet another place: -->
<div classoid="button(left(right-on-hover) rounded)"> Click me </div>
/* This is a problematic subset reimplementation of what we have in `page.css`. */
.button {
/* Base button style */
display: inline-block;
line-height: normal;
white-space: nowrap;
vertical-align: baseline;
text-align: center;
cursor: pointer;
text-decoration: none;
padding: 0.5em 1em;
}
.button.left {
text-align: left;
}
.button.left.right-on-hover:hover {
text-align: right;
}
/* Somewhere else in CSS code: */
.left {
float: left;
}
/* Somewhere else still: */
.right-on-hover:hover {
position: absolute;
right: 0;
}
@bkardell
Copy link

So, the idea is that you want to not use cascade, specificity, interitance and so on that CSS provides you? If you're really making some kind of module here, it seems like scope is what we're looking for, a membrane to say 'yeah, you could poke it if you really wanted to - but you really gotta try, otherwise my .left is just my .left'?

What I'm trying to get at I guess, with my questions is based on this: We have this idea of OO CSS. It has some really good concepts and it's helped a lot of designers do some good things. It's not a magic bullet or complete theorem of 'the one ultimate and true way' but it's got some good concepts. It has always been my position that CSS is too weak (both selectors and box exposure, before CSS 2.1 was everywhere especially), HTML too unexpressive (before HTML5 especially) and no kind of barrier like the one above (shadow dom or scoped styles) makes this an almost impossible tasks - that we have to work on those things and until then, OO CSS has some nice concepts. But, I definitely want to get those things - and they may make parts of (or at least specific examples of) OO CSS kind of less relevant.

It seems to me that am-css is really just a more legible/convenient syntax for OO CSS which, because it uses attributes actually does add a few new capabilities - but it's not radically dissimilar. I thought you were positing that it is somehow 'less' capable than the normal OO CSS approach, are you? If so, I'm still not seeing how - in fact, it seems slightly more capable (because classes are -only- values and can only be exact match and attributes are key + value and have a few variants like startswith or contains).

Looks to me like what you are trying to do with the / and () is similar in aim of not repeating the feature portion you are trying to 'extend'. But how is this materially different than, for example

.button[my-alignment="left"]
.button[my-shape="rounded"]

I really dislike this example because button should be a tag and I think these are stylistic names which seems kind of antithetical to the design of CSS, but used well, they could be factored out to what I think is more the original promise of CSS that you can semantically (combination well-known and local-semantics) describe something in rich markup and style it independently. If we actually practiced this now that we have richer selection abilities, markup possibilities, it seems like it would be much easier... Add custom elements and some kind of membrane, it seems like we could actually do pretty well.

@espadrine
Copy link
Author

You cannot implement the example I gave in AMCSS. How would you do right-on-hover? It wouldn't be one level down in the tree.

The benefit of namespaces is to be able to store symbols one level down. AMCSS only provides one level of depth.

button
  middle
  left
    right-on-hover  ← impossible in AMCSS
  rounded
  squared
text-outline

I am definitely not saying that AMCSS is less capable than OOCSS. It is a bit better by providing the tree-like module functionality seen above, except that it only goes one level down, which forbids right-on-hover here.

On the other hand, in certain ways, while more elegant, it is less capable than BEM, which can provide any depth.

.button__left__right-on-hover { /* … */ }

But BEM is inelegant:

<div class="button button__left button__left__right-on-hover"> Click me </div>

vs

<div classoid="button(left(right-on-hover))"> Click me </div>

As for scoping, do you mean the current design of HTML-centered scoping?

<section>
  <style scoped>
    /* insert scoped CSS here */
  </style>
</section>

If so, that is also a welcome addition to CSS, but not a silver bullet. We need SCSS' @extend, and classoids provide it and more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment