foundation / foundation-sites

The most advanced responsive front-end framework in the world. Quickly create prototypes and production code for sites that work on any kind of device.
https://get.foundation
MIT License
29.65k stars 5.49k forks source link

[Foundation 7] BEMIT - AppFramework level compiler. Edit: Foundation level Compiler also! #10430

Closed IamManchanda closed 6 years ago

IamManchanda commented 7 years ago

Hey Community,

Internally there has been a very deep discussion going on these days b/w yetinauts about the sass architecture and namespacing! Yes the first and foremost goal is to make the CSS Environment Agnostic But also concerned about lot of other goals and thus yeti's think that BEM (or BEMIT) is the solution for it.

BEM is applicable to all projects, whether its big or small, avoids the nestings/specificity issues, helps you encapsulates your code for reuse, Arguably a quick way to deliver prototypes and helps you make good decision (ensures that you plan) and most importantly is semantic But again we can't hide the stuff that its really a very long html Thus we yeti's are looking very deep on minimizing the effort of the end user

So last night @ncoden came up with the plan of compiling

Frankly what he said is this

<div bem="myBlock:myModifier as b">
    <div bem="b.myChild:myChildModifier">...</div>
</div>

By this, we can compile and achive the desired result! Not saying that this is the wrong approach but its not that semantic

So i thinked long today and here is what I think Why not create an AppFramework level compiler instead of Foundation level? What that mean is while starting out, we can create App Framework level compiler in three popular frameworks of today (Vue, React, Angular) and also let the community to contribute more compiler for the other framework

As i know bit of Vue.js, Here is the semantic Vue.js based example for the same

<accordion :modifier="{primary, large}">
  <item :parent="accordion" :objects="{bordered, rounded}">
    <heading :parent="{accordion, item}">
      Accordion Heading
    </heading>
    <content :parent="{accordion, item}">
      Lorem ipsum dolor
    </content>
  </item>
</accordion>

which will automatically convert the code into a BEMIT code like this into the DOM

<div class="c-accordion c-accordion--primary c-accordion--large">
  <div class="c-accordion__item o-bordered o-rounded">
    <div class="c-accordion__item__heading">
      Accordion Heading
    </div>
    <div class="c-accordion__item__content">
      Lorem ipsum dolor
    </div>
  </div>
</div>
ncoden commented 7 years ago

When you say that components need to be built a particular way in Sass to make SCA possible, are you referring to a structure such as this (...)

Yes.

If so, then I agree with your claim. But in that case, what do you mean by: "It's sad, it's too bad for the user and will probably cause problems, but at this point we don't care."

It's sad in my point of view, because we have a framework that is "SCA-compatible". You are sure it will not apply properties you don't want, fuck up your specificity, etc... And people will use Bootstrap-like selectors "because it's more convenient" then stack dirty fixs over dirty fixs to have the render they want.

But. "at this point we don't care.". We provide a framework, we don't rule the world. Let's create good tools and make people learn why they should use them. But we should not artificially restrict anyone, it's just useless.

Are you referring to the fact that you can't include a component with one mixin if you structure your Sass this way?

No (see above). But this is false too. We can provide (like we are doing sometimes) one mixin for each block/element/modifier AND a component mixin that generate the CSS component with arguments/configuration-based selectors. This is almost what we are doing for ZF grids.

This allows the user to change the generated selectors for all the components through the config, and to inherit a whole components (or a part of it) with one mixin call.

If that is the case, BTW, what's preventing this?

Nothing, that's the point. a SCA framework is compatible with and can be converted to any other architecture. The limitation is in the way you create your components.

I hope you're not meaning to claim that these are the only two options. For myself, I use neither the single-class pattern or the Bootstrap pattern.

I do not :D . I know there is a whole palette between BEM and Bootstrap. I like the "scope"/"scoping modifier" principles (I already talked about it on some issues I think) that are a good compromise in some contexts.

I was fully expecting my initial post in this thread to be disregarded or considered off-topic

I like playing the devil's advocate, it may help :).


If you can describe the problem in more detail, perhaps I can help solve it. :)

The idea behind this is : instead of generating tons of CSS selectors, and making the inheritance when applying them in the HTML (for example <... class="house house--purple house--big my-house">, we could move all that to Sass and generate classes you use directly in the markup (<... class="this-house-for-this-context">). So you have two things: a markup that is oriented around the structure and semantic with classes applied for everything, and an associated stylesheet when you will create/inherit/customize all components and more or less generic styles.

See: https://designshack.net/articles/css/semantic-grid-class-naming-with-placeholder-selectors-in-sass-3-2/

The problem is: we cannot use @extend because your properties are ordered like your placeholders, and not like the components. So this can't be applied to a whole application because all components/utilities/etc priorities are mixed. And with @include, well this duplicate every component. Not better.

PS: I did not forgot your post above. I found back some aspects of BEM+compilor I did not liked and I'm looking for solutions.

marnen commented 7 years ago

[Look at your line-breaking after block quotes—it doesn't do what you think it does. :) ]

I'm still not quite understanding all of your issue, but I will say this: I consider @include to be usually the best way of removing duplication and presentation code in Sass. @extend, though useful, is IMHO a bit of a hack, and I only use it (with real selectors) when I'm depending on framework CSS that I don't control (as is the case with Bootstrap). I hardly ever use it otherwise. I've never actually used %placeholders with @extend as mentioned in the article, because I just don't see the point when @include exists. Maybe I don't understand what they're good for.

marnen commented 7 years ago

@ncoden Ah...I may have finally understood another piece of the puzzle. Are you objecting to the duplication that @include introduces into the generated CSS? If so, I agree that's slightly messy, but I'm not sure how much I care, since no human has to maintain the duplication.

ncoden commented 7 years ago

since no human has to maintain the duplication

Maybe, but for example a common grid with 3 columns generate 30+ properties. This is a piece the user should not duplicate to create its own semantical "layout classes". Generated CSS files would be around 10MB instead of 100KB

marnen commented 7 years ago

Yes, that would be a reason for @extend over @include, if it were actually measured to be a problem (otherwise it's just premature optimization), although @extend puts a lot of unused selectors into the generated CSS. I think your size estimates are inflated, though.

I'll admit that I don't generally worry much about the size of my CSS files (they don't wind up being very large, and they're cached anyway), but I understand that as a framework author you have to. (Of course, if a file is that repetitive, it's a good candidate for gzipped delivery, but we certainly don't want to force that.)

marnen commented 7 years ago

...and with this realization, I understand now what %placeholders might be good for: removing the unused selectors and having less repetition in the generated code. Hmm.

HansUXdev commented 6 years ago

@marnen and @ncoden thank you very much for your input. I feel like you guys are preaching to save the heart and soul of the framework lol

@IamManchanda if you disagree its cool but when you are the only one thumbs downing something/someone and not stating the reason(s) it comes across as kinda brash and discourages conversation about a serious issue...

That being said, I fully agree with marnen and ncoden when they talk about keeping it more like bourbon as a library of mixins for component. If the framework enforced BEM or any other type then I and a lot of others would probably stop using.

Personally I would like to see foundation 7 built on what made v6 great which is it's flexibility. So something like this would be nice to see:

// colors
@import 'theme';     
// framework settings
@import 'settings';

//import all framework mixins, styles html5 core tags and base components
@import 'foundation'; 
// import mixins for building-blocks, community driven components
@import 'building-blocks';

// import your name schema (to make everyone happy)
@include foundation-legacy;
// @include foundation-bem;

More over, I think the focus of Foundation 7 should be a component driven framework rather than a site driven framework like foundation 6 but avoiding the mistakes of foundation for apps.

One of the major (css) mistakes of F4A was the naming/grid. Lets face it, the grid was aweful. It was weirdly named and functioned strange (XY is a MAJOR improvement).

That being said, the original purpose of this topic "AppFramework level compiler" is interesting but I worry it could quickly become another F4A like scenario and that would be devastating to the community which primarily uses sites. I would love to see a working example (demo/proof of concept) for angular, react and vue before any major BEM, etc is implemented.

As for ugly syntax: I thought the example below was the ugliest css-like selector I have ever seen...

<div bem="myBlock:myModifier as b">
    <div bem="b.myChild:myChildModifier">...</div>
</div>

However the sematic version below is actually really interesting:

<accordion :modifier="{primary, large}">
  <item :parent="accordion" :objects="{bordered, rounded}">
    <heading :parent="{accordion, item}">
      Accordion Heading
    </heading>
    <content :parent="{accordion, item}">
      Lorem ipsum dolor
    </content>
  </item>
</accordion>
IamManchanda commented 6 years ago

No issue... thanks for your concern @HansUXdev

{ PS: Please don't use slang's which can be seen as double meant! FWIW I have edited your comment with a synonym! }

HansUXdev commented 6 years ago

@IamManchanda by the way, again I think a AppFramework level compiler is a great idea.

But being devils advocate, aside from maybe a vanillia-js approach that can be plugined into vue, react, angular, how is it different then advanced css modules?

More importantly why would a tool like this, require changing the entire framework's naming schema?

IamManchanda commented 6 years ago

Simple Answer => Because its not #CSSinJS

phifa commented 6 years ago

@IamManchanda how are we doing with the BEM plans? will this be for v7?

JeremyEnglert commented 6 years ago

Closing this issue out. We can reopen for discussion in V7.