State of CSS in Meteor

@arggh
Why are you abandoning Semantic-UI? Our app is now in production and Semantic is working very well. Even on mobile. We have a custom main.css which adds our own styling.

That being said, are you using the official Meteor package for Semantic, which allows you to customize your theme?

1 Like

Why are you abandoning Semantic-UI?

I am not using the official package, since it slows down the rebuilds a lot. I have a local custom Meteor package with all the Semantic-UI’s source files, build tools etc. that allows me to customize the build by declaring my own rules, overriding or changing pre-existing variables (the setup instructed in S-UI website). I think it’s the best way to use Semantic-UI if you need to to do changes to it (took almost 10 seconds away from my rebuild times pre-1.4)

I’m abandoning Semantic-UI because:

  • It’s really developed with the focus in desktop use
  • It’s huge in size and it’s hard to pick what you really use. You can pick modules and elements to include in the build, but if I end up using just four types of buttons in my app, I’m still getting all the gazillion different types that Semantic offers, together with their custom versions and combinations.
  • It’s buggy. I’ve spent so much time trying to fix an UI bug, just to find out it’s caused by S-UI.
  • Fixing the bugs takes a lot of time, since it’s this one guy pulling the strings and the library is huge. Even if there is a pull request, it might take 4 months to get it merged.
  • Some of the documentation are just plain false - sometimes I try to use a setting, but it doesn’t work. After reading the S-UI source code for 20 minutes I find out that “oh, that setting is not even used”.
  • it has a lots of surprising side effects. Add a sidebar to your app and suddenly it’s unusable on iOS because of really strange quirks.
  • It’s not respecting the HTML spec (for which I admire the project owner’s courage and vision)
  • It’s time consuming to customize. I found it a real pain to make a minor change in the styles, partly because the library is huge and every variable wraps another variable … it’s a labyrinth you have to solve every time you need to make a tiny miniscule change.
  • It relies heavily on using !important in it’s css rules, which makes it really hard to work with.
  • It’s slow. I have a habit of testing on low end devices (like a 6 years old Windows laptop or Samsung Galaxy S2). For example, building a popup component with Blaze vs. using S-UI, there can be a world of difference in usability. With Semantic-UI it might take 3-6 seconds just to have something happen on the screen, where as with Blaze it’s pretty instant even with lower end devices.
  • It restricts my creativity. I want to have absolute freedom when designing my UI’s.
  • Writing CSS with today’s tools, such as Sass and Autoprefixer, is really fast. I just have a vision and I code it, instead of doing yet-another dive into the selection of S-UI elements, then try to force them to my vision.

The reasons with most impact are emphasized. I think in the end I got fed up using so much time trying to fix Semantic-UI issues or trying to customize the components, when I could just “do it myself” in no time.

It literally takes me the same amount of time to write my own markup and styles for a new component from scratch, that it takes just to pick the right Semantic-UI element and learn it’s “syntax” and API.

Once you know the framework It’s great for prototyping, or if you don’t care about performance, how your app works on mobile or how it looks. I still use it in our project’s admin app, where it’s a perfect fit.

Overall I feel Semantic-UI will be even more popular in the future. I also doubt that the main pain points would be fixed in the near-future, since they would require substantial refactorings in the entire codebase.

1 Like

I re-read my post and want to clarify that I’ve been using Semantic-UI for years, initially fell in love with it and think it’s an amazing feat from it’s creator. However, it has now served it’s purpose for me and it’s time to let it go :slight_smile:

1 Like

I agree with a lot of your points. adding SUI creator @jlukic to the discussion

1 Like

Thanks @arggh,

It is true that it is becoming easier with pre-processors to have solid styles quickly, you do need to know what you are doing though, so not everyone can take that path.

I would like to comment onh a couple of points:

Agreed, but mobile works good regardless, and I feel there is an expectation that you will build your own css overrides for screen sizes.

Agreed, but that’s the same with most frameworks. Deeper customizations will be very expensive somewhere in the development chain, either for developer of the framework (including maintenance) or for us to painstakingly tweak everything.

Agreed, we stopped using sidebars altogether in our app.

Your are talking about six wide mobile two wide desktop kinda-thing? :slight_smile:[quote=“arggh, post:14, topic:33516”]
Some of the documentation are just plain false
[/quote]

Yes! I accepted that as part of using an open source package, there are a LOT of issues on GH. I think @jlukic needs to bring a community on board to help with dev. It might be critical for the future of the framework. Case in point, we use external calendar and range UI elements, which were developed FOR semantic. But could not be merged to the main repo, even though they work great.

Thanks for taking the time to outline your thoughts on SUI in a constructive and reasonable way @arggh et. all.

The most important thing I’ve wanted with SUI is not to just create a UI library that people can be used to build websites, but to promote a new way of thinking about writing front end code.

The core tenants being:

  • Begin with a list of tangible physical components which correspond 1:1 with language for describing websites.
  • Use a strict, internally consistent system for defining UI using single english words and fixed system of grammar (types, variations, state, etc)
  • Encapsulate rules using noun/modifier relationships (i.e. “small” has no absolute definition without context. i.e. small ant vs small planet)
  • Provide a tiered theming system so people can style it without modifying the base rules
  • Create behavioral modules built around simple (verb+predicate) relationships for describing an API for functionality (set active, get value etc,)
  • Provide, as best as possible, neutral default values for variables that express the most commonly used case
  • If something is arbitrary in the framework, make it a variable or a setting so that developers can change it
  • Include a system so that developers can extend the library as necessary (overrides)

Generally the thing I want developers most to take away, even if they dont decide the framework is for them, is that there are other ways to think about constructing meaning through physicality, and that it is most effectively modeled around natural language (not the existing vogue in abstraction)

With regards to the specific complaints, which are all real difficult and useful points of conversation.

w/r/t slow pace of dev, lack of community dev

I’ve decided for reasons of internal consistency and voice to generally maintain the direction of the project individually . To me this is like the difference between a novel written by one author vs. a academic paper co-written by multiple scientists. They are both effective strategies to expressing truth, but have trade-offs. I have personally been a fan of the novel approach for SUI because the aspirations of library might be an overreach for this generation of programming, and instead might be most useful as a roadmap for another generation on how this kind of thing, could be done.

w/r/t desktop use

I don’t believe that its the case that SUI is a “desktop use only” framework. I think generally mobile development is a mixture of three things: useful patterns for reducing complexity, (doubling/stackable), decisions about reducing complexity (what part of my app can i cut out for mobile), and correctly swapping out “mobile-first” UI, for example vertical menus from horizontal menus where appropriate.

I think SUI provides good patterns for handling mobile, but doing mobile effectively will require you to think critically about your specific content. I dont think adding classes like show mobile hide mobile etc will solve this issue entirely.

w/r/t gazillion options

I think the next version of SUI will include some strong decisions about separating ‘core UI’ (represented by usage stats, surveys etc) from non-core ui. This might include something like two packs for each component, “basic” (most commonly used styles) and “extended”.

w/r/t restricts creativity

I dont believe there is much time left for creating new salient UI. I do believe there are many new UI patterns which are not encapsulated in SUI, but I dont think a library that describes only some patterns is necessarily restrictive.

w/r/t meteor package

All credit to @flemay for the heroic effort of maintaining the port, but the meteor package is very slow. I use my own custom forked package in prod that uses the LESS only package.

The difficulty is allowing for flexibility in customizing the package while also allowing downstream updates.Its difficult but possible to do this in NPM with post-update hooks, but in meteor with atmosphere its not very viable. I wish I had a better solution here.


I know I’ve been on radio silence for the last year or so, and dev might seem to have slowed down, but this will be the year for important announcements around SUI. This is my core lifetime project so you can count on reliable updates to SUI, albeit with some dead time for life hiccups coming up along the way.

7 Likes

This thread went a bit off topic, but it’s nice to hear thoughts from @jlukic regarding Semantic-UI. Thanks for a thorough reply, appreciate it. I think you pretty much listed the reasons why I found SUI so intriguing in the first place few years ago.

Some of the given reasons to abandon SUI don’t have much to do with SUI, but UI frameworks in general, such as restricting creativity: With a framework, the components tend to be my first line of defense when solving a problem. I find myself browsing the API for a “suitable ready-made block” to fill the need. So, in a way it’s not the framework that’s restricting, it’s myself if I have the framework at hand. And the solution for me is to ditch the framework.

Regarding desktop vs. mobile,

I don’t believe that its the case its desktop use only framework

SUI definitely is not desktop use only, but in my experience it’s desktop first. Some of the components don’t play along that well with mobile, or then I lacked the skills to use them properly. Sometimes some SUI-components’s javascript would be doing undocumented DOM manipulations and that sort of sorcery, causing issues specifically on mobile devices. Or I was expecting a “huge padding” to be less huge on mobile, when it ended up eating all my screen space.

At the same time some of the things I really liked about SUI was the grid system, it works really well for mobile design, though I would have personally worked out a way to specify the different widths and alignments without duplicate class names.

For SUI’s future, I think the idea of separating SUI into two different packs would be great. Having a core of well thought and tested defaults that basically have nothing to override but provide easy styling, coupled with the natural language for describing the UI. That would be something. Maybe there already is something like that, but it’s not well known since the results wouldn’t be pretty out of the box or it’s lacking a date picker or some other fancy feature.

I don’t understand why people complain about a missing date picker. I’m more likely to complain for adding too much. That’s probably also why I’m feeling the need to give up on SUI, it’s too big for me to handle elegantly. I find it easier to maintain my own tiny subset of styles - even if some of them will most likely end up being copy-pasted from SUI sources, like the grid :wink:

To finish off, I want to state that I didn’t mean to throw negativity at Semantic-UI, I was merely explaining my motives when asked. I hate it when people find nothing positive to say about the accomplishments of others, and I don’t wish to be regarded as such people :slight_smile:

@arggh

As I re-read the post and the different comments, here are some thoughts from a Semantic power user:

Edit: Understood … good constructive criticism is good. I just feel that some concerns are exaggerated. Examples: modals, dropdowns, form validations etc. that need JS back-end. That’s a LOT of work to develop from scratch. It’s not just CSS. Bootstrap doesn’t nearly offer as much.

Back to SUI and @jlukic

I applaud your mission. [quote=“jlukic, post:18, topic:33516”]
The most important thing I’ve wanted with SUI is not to just create a UI library that people can be used to build websites, but to promote a new way of thinking about writing front end code.
[/quote]

Seems a bit grandiose, but granted. Truth is, myself (and likely others) have our noses in the grindstone. We are not looking for great missions, we are just very happy and grateful for SUI.

From a PM perspective, I heard this before: to switch from one-person team to a multi-person team, you need to jump to three people right away, as the drop of productivity, meetings, docs etc. slows things down. So I understand. You are definitely (way) top-notch. Yet, there is obviously a risk for us with a single developer, but … it’s open source. So no complaints there.

On re-building, sure. But if there are no changes. We didn’t feel any delays … am I wrong? Should we use your package instead?

1 Like

I’m a fan of micro libraries of sort. Instead of hoping for one framework to do everything (especially, if there’s basically one guy trying to maintain that everything), I’d rather use another lib that’s solely focused on the task at hand. It’s a line drawn in sand of course, which components to include in a framwork and which to exclude… I think it’s great the community can & has provided additional components for SUI, such as the date picker!

When a framework tries to include everything, this kind of things tend to happen:

I wanted to use the form styling of Semantic-UI, but to handle the validation with ViewModel’s validation tools. If I include the form-element in my SUI build, it automatically includes a lot of form related JS in the SUI bundle, which I don’t need. That can easily go unnoticed, until you find out your JS bundle is 3Mb in size.

I guess the lesson that could be learnt here is, that with a huge framework such as SUI it is essential to provide the different elements, options, variations as opt-in rather than forced upon. Now it’s a lot of trouble trying to get rid of stuff that’s not needed, like form validations, popups, all the 15 different color themes for everything etc…

It is very slow, as it’s basically rebuilding SUI every time you change any file on the client. At least it used to, I don’t know with the latest speed improvements in the build tool or possible improvements in the package. Especially if you’re not making any changes to SUI, you could get huge performance improvements by creating a separate project for SUI that builds the .css and .js bundles for you to include in a Meteor package.

Setting up your package was a breeze, though I had to look up in the Wiki and the example repo to get a nice copy and paste the configs -experience :slight_smile:

One issue using node-sass, on every style change I get this in my console:

WARNING: version mismatch for node-sass; installed version is 4.4.0, but version 3.x is required by nathantreid:css-modules)

yet the package seems to be working just fine with node-sass@4.4.0

So far this is just awesome. Now I feel like a complete idiot for not switching earlier. Congrats on a great CSS package for Meteor!

Should admit SUI isn’t as modular and easy tool as ant/material frameworks but in terms of style… #onelove
On your side here! Most freedom i’ve seen among css frameworks though khm-lifecycle-khm

@nathantreid, I suppose this is not possible?

// /globals/fonts.m.css
$comicSans: 'Comic Sans';

$headerFont: $comicSans;
$buttonFont: $comicSans;
// package.json
"cssModules": {
    "extensions": [
      "m.css"
    ],
    "enableSassCompilation": [
      "m.css"
    ],
    "postcssPlugins": {
      "postcss-simple-vars": {
        "fileOptions": [
          "globals/fonts.m.css"
        ]
      },
      "postcss-modules-values": {},
      "postcss-nested": {},
      "postcss-modules-local-by-default": {},
      "postcss-modules-extract-imports": {},
      "postcss-modules-scope": {},
      "autoprefixer": {}
    }
  },
// myComponent.html
<template name="myComponent">
  <h1 class="{{styles.header}}">Header</h1>
  <button class="{{styles.button}}">Button</button>
</template>
// myComponent.m.css
.button {
 font-family: $buttonFont;
}

.header {
  font-family: $headerFont;
}

Actually this is possible, but I need to add it to the documentation - sorry about that!
Since you’re using SASS, the variables are interpreted by SASS instead of PostCSS - use the globalVariables option instead:

"globalVariables": [
  "globals/fonts.m.css"
],

The reason for that message is that I haven’t tested node-sass version 4 yet, and the major version bump signifies potentially breaking changes. I don’t want users to get stuck if node-sass changes their library in a way that prevents my package from working with it. I’ll think about adjusting the message and think about the frequency, though.

Thanks, awesome! I was about start filing a pull request to fix an error in the docs regarding where those globals should be defined, but apparently they just work differently based on the key in configs.

I’m still trying to orient myself to this new paradigm, and one thing I find confusing is triggering animations with classes.

Say I used to do something like this (the class is assigned by a ViewModel binding based on the value of isBacksideVisible )

// html
<div {{b "class: { flip: isBacksideVisible }"}} class="card">
  <div class="front">
     <img src="nicepic.jpg"/>
  </div>
  <div class="back">
    <p>it was a cat pic</p>
  </div>
</div>

// card.scss

.card {
   &.flip {
     .front {
        transform: rotateY(180deg);
     }
     .back {
        transform: rotateY(0deg);
     }
   }
   ...
}

How would I accomplish this in the most elegant possible way using CSS Modules, Blaze (and possibly ViewModel if you’re comfortable with that)?

My initial solution:

// card.html
<div class="{{styles.card}} {{#if isBacksideVisible}}{{styles.flip}}{{/if}}">
  <div class="{{styles.front}}">
  ...
</div>

// card.m.css
.card {
  ...
}
.flip {
  .front {
    transform: rotateY(180deg);
  }

  .back {
    transform: rotateY(0deg);
  }
}

My first impression on using this package is “wow”, but I also feel that polished documentation and more examples would make it so much easier to adopt!

I tried this, and this type of error appears in my console:

=> Started proxy.                             
=> Errors prevented startup:                  
   
   While processing files with nathantreid:css-modules (for target
   web.browser):
   native: Cannot convert undefined or null to object
   at hasOwnProperty (native)
   at _has
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:174:48)
   at mergeWithKey
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:2691:29)
   at f3
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:477:22)
   at mergeWith
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:5891:16)
   at
   /Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:454:28
   at Object.f2
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:434:22)
   at packages/mss/postcss-plugins.js:57:30
   at forEach
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:1874:13)
   at
   /Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:390:80
   at Object.f2
   (/Users/arggh/.meteor/packages/nathantreid_css-modules/.2.3.1.v8aqot++os+web.browser+web.cordova/plugin.mss.os/npm/node_modules/meteor/mss/node_modules/ramda/dist/ramda.js:434:22)
   at loadPlugins (packages/mss/postcss-plugins.js:50:5)arggh
   at new CssModulesProcessor (packages/mss/css-modules-processor.js:27:27)
   at CssModulesBuildPlugin.processFilesForTarget
   (packages/mss/css-modules-build-plugin.js:54:32)
   
   
=> Your application has errors. Waiting for file change.

My config is here:

"cssModules": {
    "globalVariables": [
      "client/styles/global/fonts.m.css",
      "client/styles/global/colors.m.css",
      "client/styles/global/variables.m.css"
    ],
    "extensions": [
      "m.css"
    ],
    "enableSassCompilation": [
      "m.css"
    ],
    "postcssPlugins": {
      "postcss-simple-vars": {
        "fileOptions": [
          
        ]
      },
      "postcss-modules-values": {},
      "postcss-nested": {},
      "postcss-modules-local-by-default": {},
      "postcss-modules-extract-imports": {},
      "postcss-modules-scope": {},
      "autoprefixer": {}
    }
  },

I’ll respond to both of these later today.

1 Like

With the same config as above, except the globals defined in fileOptions instead, this doesn’t work as I thought it would:

// /client/styles/shared/input.m.css
.a {
  composes: b from ('./utils.m.css');
}

// /client/styles/shared/utils.m.css
.b {
  font-weight: bold;
}

I get this error:

Processing Step: CSS Modules / PostCSS compilation
Unable to compile /Users/arggh/Development/modulesapp/client/styles/shared/input.m.css
CssSyntaxError: postcss-modules-scope: /Users/arggh/Development/modulesapp/client/styles/shared/input.m.css:2:3: referenced class name "b" in composes not found
.a {
  composes: b from ('./utils.m.css');
  ^
}

/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This was a handy starter-kit: https://cdn.rawgit.com/joeybaker/styleguide-css/a2a7f31c/decks/CSS-Modules.html#1

:slight_smile: