Stylus CSS vs. less vs. sass

I like using either LESS or SCSS. There are a few benefits to SCSS like prefixing right out of the box whereas you have to do some extra work in LESS atm. Although, you can’t setup variables for file locations in SCSS, but you can in LESS. There are tradeoffs for each.

But, there are newer ones that are out now like CSS Next which is allowing you to use newer CSS features way before they are released (Like Babel for ES6). Not that much similar to LESS or SCSS.

@rgoomar speaking of ES6 how do I use ES6 in my project and what are the recommended packages ?

$0.02

Having used them all, I’d say less, sass, and stylus are all pretty similar, and roughly equal.

The best feature (imho) they provide is nested classes, which allow people to take css classes out of global scope and pseudo-scope them to a specific component/template. The most painful feature (again, imho) are variable mixins, since they require static linking/importing of files, which goes against the Meteor bundler paradigm. The grove:less package addresses that shortcoming; but even with it, the issue is still sort of there in the background.

I’d second the opinion of looking into JSS. I think it, or something like it, is the way of the future.

Edit: Be sure to take a look at JSS: The Important Parts for an example of how one would go about using JSS with Blaze; and keep in mind that the toString() method will allow one to write to a DOM element’s style attribute for dynamic layout & positioning.

1 Like

@awatson1978

Having worked with JSS , do you have a solution, or example , or even code snippet you can provide to show how I can try JSS with Meteor. I have tried it and haven’t seemed to get things working.

I haven’t looked at all the responses, but try {named:false} instead of {name:false}, and also make sure you wrap that code in a Meteor.startup block, otherwise it might execute before there’s any DOM to add the style element to. Does that work, if you put it in a Meteor.startup block?

I’m making one solution for that: rocket:module. There’s also some other solutions for using ES6, though many of them don’t provide ES6 Modules, only the language features.

On the contrary! It’s totally designed for the client side. Specifically, JSS is designed to make it easy to encapsulate styles on a per-component basis (React components for example). It’s a lot more dynamic than CSS, Less, Sass, and Stylus in that regard. JSS’ automatic namespacing prevents selector collisions for this purpose.

(Though you can totally use it on the server side if you wish!)

Should this go in server or client ?

Put the Meteor.startup block in the client. Meteor.startup is essentially Meteor’s version of jQuery’s $(document).ready().

Actually the error is now this .

Uncaught TypeError: Meteor.npmRequire is not a function

Meteor.startup(function () {
var jss = Meteor.npmRequire('jss');

var sheet = jss.createStyleSheet({
	'.test' : {
		background: 'blue'
	}
} , {named:false}).attach()
});

Can you post it to a repo? Then I can clone and check it out.

Oh! Yeah. Meteor.npmRequire is for the server side only, but JSS needs to run client side. This is a limitation of Meteor’s packaging ecosystem. I’m trying to provide a solution with rocket:module.

Its very basic meteor checkout but yes i’d be happy to do so

A possible solution would be to download the JSS code (assuming there’s a version of jss that adds itself to the window as jss) and place it in your project directly instead of trying to get it from NPM. Another solution can be to use cosmos:browserfiy to import npm stuff for the client. Cosmos:browserify similar to rocket:module, but rocket:module is taking some extra steps to share NPM dependencies across Meteor packages, and is using Webpack instead of Browserify.

ok is your project ready , and can you get a working example with the repo I created ? i’ll accept the PR to view.

https://github.com/rwatts3/jss-test

Either way for me I want the best proposed solution so if your solution works i’d like to use that .

@trusktr
Have you heard of this grigio/meteor-babel repo. . Is babel a good solution ?

I haven’t tried it, but it looks good. It will only provide you with language features (arrow functions, classes, etc), not ES6 Modules.

So, the quickest solution for you right now is to learn how to use cosmos:browserify. You’ll have to create a package in your app that depends on cosmos:browserify (rocket:module aims to work in applications without requiring code to be in a package), then you will use Npm.depends in your package’s package.js to specify it depends on JSS from NPM, then in your package you make an entry point whose file name ends with browserify.js. Inside that file you can do

var jss = require('jss')
Meteor.onStartup(function() {
  // do what you want right here with jss.
})

I’d suggest my project, but it’s not quite ready. I’m trying to finish it as soon as possible. Welcome to Meteor with its issue of not being able to easily import non-Meteor libraries. :smile:

I just went back and looked through the documentation. They really need to take the examples from JSS: The Important Parts and put them into the JSS Readme.md. I was thinking the only way to use JSS was with the sheet.attach() and sheet.detach() api (which is what I’d expect from a platform that didn’t have a single-page architecture). Seeing the examples from the Important Parts, though… yeah, that makes a lot of sense. I can see how that would work well with a component architecture. Makes me that much more convinced it’s the way to go.

@rwatts… start with the JSS: The Important Parts link. But also keep in mind that JSS isn’t limited to just generating composable style classes. It can also write directly to the style attribute

<template name="myComponent">
  <div class="myComponent" style="{{getSize}}">
    <!-- stuff -->
  </div>
</template>
Meteor.startup(function () {
  window.addEventListener('resize', function(){
    Session.set("appWidth", $(window).width());
    Session.set("appHeight", $(window).height());
  });
});
Template.myComponent.helpers({
  getSize: function(){
    return jss.createStyleSheet({
        "width": Session.get('appWidth') - 100 + "px;",
        "height": Session.get('appHeight') - 100 + "px;"
      }, {named: false}).toString();
  }
});

I haven’t used the above code exactly; but I’ve been using the general approach with much success (with a hand-rolled parseStyle() function). I’d very much like to replace my current hand-rolled methods with something like the above.

1 Like