Oct 28, 2009

A Dash of Rosemary on Your CSS

Everyone has a complaint about CSS. Everyone has a complaint about browser compatibility. This is something Rosemary attempts to address. This is not a CSS framework.

Rosemary is an open-source modular cascading filter-based modification system for CSS files; or commonly recognized as the acronym, OSMCFBMS4CSS. Your CSS files are run through a series of filters that modify it one after another. These filters can be toggled on/off, rearranged, or all of them disabled completely to give you raw output. It provides a scalable CSS wrapper that you can continue to use no matter what version of CSS is supported (or unsupported).

Rosemary Anyone with some PHP skills under their belt has the ability to create a filter to use with Rosemary. Combining filters in different arrangements will prove to offer diverse results. Developers and designers will both benefit from the ease of customization Rosemary provides. Filters can allow for deeply technical configurations for the devs or be simple as 1-2-3 Go! for designers.

A filter is an independent package of code that modifies your CSS or gives you new abilities when writing CSS. An example of this is the Browser Filter. The Browser Filter gives you new capabilities in CSS writing to define certain blocks or properties as browser specific. The filter will remove any blocks or properties labeled "IE" if the visiting user is running Firefox. There are also other filters, like the Compressor Filter, that don't give you any new capabilities but simply perform an action. In this case, the Compressor Filter removes all whitespace and line breaks in real time so you can edit clean code and send a small compressed file to the user.

Some of the key reasons this is better than salt and vinegar potato chips:
  • Versioning: Filters are isolated into different folders and act independently. If a new browser comes out or CSS changes, you can download a newer version of a filter and swap it out. When there are bug fixes or feature requests to a certain filter, you can just download a newer version.
  • Open Source: These are designed to be a community project. Everyone who has some coding experience can make filters where it suits their needs. If you find a bug in a filter and want to fix it, send in the changes to the author and it'll collaboratively improve. After enough participation, you may not even need to make one because it may already exist.
  • Simple and Light: The system couldn't be a whole lot simpler. One .htaccess file to push your CSS through the filter, a file to define what filters you want to use, and the Rosemary package where you decide what filters you want.
  • Never outdated: This relates back to the ability to version your filters. When things on the web change all the sudden, this can adapt just like any other plugin system.

We have created a small package of filters just to get things started. There are some to-dos and possible bug fixes awaiting on some of these filters so feel free to submit feedback, edit some files, and get this rolling. The existing filters are: Browser, Compressor, Inheritance, Reset, StripComments, Variables. There is further documentation, examples, and a test area in the attached zip file for you to play with. Expect some updates to the system in the near future to allow for more core functionality, but for now play with filters and different combinations.

If you're looking for some ideas, here are a few I haven't gotten around to yet:
  • Nesting: Allow object oriented nesting of selectors through multiple levels.
  • Selector Groups: This works very similar to nesting but is a little different approach. This would give you the ability to do: html body .myDiv [h1,h2,h3,h4,h5] instead of: html body .myDiv h1, html body .myDiv h2, html body .myDiv h3, html body .myDiv h4, html body .myDiv h5 .
  • Filter Packs: Some people want core functionality to tinker with, some people just want to install and go. Different filter packs of "7 Filter Designer Pack," or "Object Oriented Dev Pack," would make Rosemary a strong tool for any type of user, amateur to expert.
  • Full Width/Height: A lot of people don't understand the box model. If I say width is 500px with 20px padding and 5px border, why is it more than 500px wide? A good filter for designers would be two new properties called "full-width" and "full-height." It could rewrite the property to be `height` = `full-width` - `padding`-`border`. Same for height.

Give it a whirl and see where it takes you. Leave some comments below with feedback, bugs, or your thoughts on the weather.

Download Rosemary.zip

Edited: Added new filter to simulate "Mixins," a different type of inheritance. Use classes, IDs, and selectors as variables anywhere in your stylesheet.
Download Mixins Filter

Edited: New filter that allows you to include preprocessed or raw CSS files into one.
Download Include Filter

Example snippet using Variables Filter:
 
                define red: #ff0000;
                define full wide: "600px";
 
                #myDiv {
                    /* Color will be red */
                    color: @red;
                    /* Width will be `"600px"` */
                    width: @full wide;
                }
 
                define red: #0000ff;
 
                #myDiv2{
                    /* Color will be blue */
                    color: @red;
                }


Example snippet using Browser Filter:
 
                ~!ie #myDiv{
                    /** This block only appears for NON-IE browsers **/
                }
 
                ~gecko #myDiv{
                    /** This block only appears for Gecko-type browsers **/
                }
 
                ~firefox3 #myDiv{
                    /** This block only appears for Firefox3.0 browsers **/
                }
 
                #myDiv{
                    /** Can be applied to properties inside blocks **/
                    ~ie height: 100%;
                    ~!ie height: 500px;
                }

Share this Post


                           

Comments


Matt Kenefick     Dec 09, 2009
That's happening from a misconfiguration of the .htaccess file. An .htaccess file is required in your CSS directory. In it has a RewriteRule that points to your Rosemary directory.

What you need to be concerned with is that it points to Rosemary/core/Controller.php correctly. If it doesn't, you'll get the 500 error.

Jens     Dec 06, 2009
Hi,

This looks great. I am looking forward to trying it out.

Am I doing this right? I get a 500 internal server error. Do you have any more detailed instructions on setting up?

Thanks

Jordan     Nov 24, 2009
Very nice work, I've been developing a similar system for a while now, but I've only implemented css variables, since that's current all we really needed.

While I was looking into it, I found a proposal for css variables:

http://disruptive-innovations.com/zoo/cssvariables/

This is the syntax I ended up using, since it might someday end up in the official CSS spec. It's very similar to the way you're defining variables, but I thought it might be valuable, or at least an interesting read for you.

Again, very nice work!

Matt Kenefick     Nov 12, 2009
@James Cready
Actually, it's neither. The content type from the server is regular CSS. The client's machine is what processes and renders the output, just as it does for everything else. As said before, it doesn't create tmp flat files for it yet on the server, but regardless..the output is normal CSS so the rendering time for the client is the same. (if not faster by removing the bulk of things you don't need before it goes out.)

James Cready     Nov 11, 2009
Rosemary outputs an actual CSS file to the server so client side rendering will be the same, if not faster.


This is either naïve or a flat out lie.

Brian Klepper     Nov 10, 2009
Great work! Excited to try this out. I have yet to find something that actually works well and is easy enough to incorporate into my daily workflow. This is obviously important for the people willing to work with the system. I can see the hesitation because you're turning CSS into a more complicated workflow, but in the end having the control that will benefit your work.


Charlie     Nov 04, 2009
You are far too clever.

Matt Kenefick     Nov 02, 2009
@Joe
There is a Browser filter that lets you determine what you want to apply. The PHP renders the CSS from there. If you wanted to actually generate cache files for that, it would involve creating a filter to piggyback on the Browser filter to serve up compile files instead of regenerating every request. (which is probably in the works soon)

@Sam
Your suggestion is good and can definitely be used. The only problem that creeps in is that some of filters are conditional per user, like the Browser filter. This would require evaluation each time. A cache filter could be created and used similar to what you're thinking for sheets that are static. This will need more thought to keep it simple but also efficient. I like where your heads at. Will probably be working on something similar soon. Then again, this is open-source so I encourage everyone to give their ideas a shot.

@JP
Thanks!

JP DeVries     Nov 01, 2009
i'll use this on every php site i ever do! you guys rock

Sam     Oct 31, 2009
This is a great great addition to CSS. I would love to implement this on my next project but my concern is the unnecessary need to rewrite the CSS file each time is requested by a user. This could potentially create a huge overhead on a large site. ( this would the case on my project )

Why not just output the new css to a new stylesheet called main-min.css or main-rosemary.css and then have a conditional so if the site is in development then keep rosemary on and right before pushing live just set it to production, produce the main-min.css file and use that instead of original main.css. I know this creates more files to deal with, but we could go a step further and create an "output" folder within the CSS folder to keep them away from the developers.

Just an idea, this is the most exciting CSS project I've seen in a while.

Joe     Oct 30, 2009
Would it be possible to have rosemary find out what browser is being used, send that information to php, then have the php or rosemary generate the specific CSS that would work for that browser? So you would only have to write one css file and rosemary could apply the certain bug fixes for each browser.


Matt Kenefick     Oct 29, 2009
@KevinSweeney
Because it's all filter-based, I'd like to leave that up to whether or not you include that particular filter. I just added the start of an include filter in the post under the downloads for you to try. There's a readme.txt that should help you get started with it. Basically you can include other CSS files by using a command "include ./myFile.css;" There are two ways to do it in that version, raw or preprocessed. That means you can run your included file through its own set of filters FIRST, and then bring the results in; OR you can just include the raw data and let it all get processed at once.

So if you wanted to get a preprocessed file, you would create a "*.rosemary" file for the file that will be included... ie:
./myInclude.css
./myInclude.rosemary
./main.css
./main.rosemary

The "myInclude" file will be completely processed and then injected into main.css if you do this:
#file: main.css
body{ /* properties*/ }
include ./myInclude.css;
#endfile

--------------------

You can include it completely raw by doing this:
#file: main.css
body{ /* properties*/ }
include ./myInclude.css -raw;
#endfile
Does that work?

Kevin Sweeney     Oct 29, 2009
I'd be curious to know how multiple CSS files are handled. Will the system merge all CSS files, run through the filter, and return a single compressed CSS file, or is each file run through Rosemary separately?

Rich     Oct 29, 2009
What a waste of development time, all I can see from this is that added workflow is needed for every revision of new CSS per browser.

Corrine     Oct 29, 2009
Very cool. Any word on when OSMCFBMS5CSS is due for release?

Matt Kenefick     Oct 29, 2009
@Trevor
Hey, thanks! I just found that a bit ago thanks to DavidHund. It looks pretty good! I don't have a lot of experience with haml but it's an interesting syntax you have for SASS. Feels very much like yaml. Certainly wouldn't mind seeing some of that ported over! :)

@DavidHund
I haven't heard of either solution before but I briefly looked into them. I really liked some things about both options. The inheritance in LessCSS is very clean and simple; unfortunately it looks exclusive to Ruby. The line of separation between Rosemary and those options is that you can recreate LessCSS or SASS using a combination of filters (filter paaacks); which could be made by anyone.

@DaneHesseldahl
Thanks! I actually know somebody here that might be more than happy to do that ha. "Python python python!"

Trevor Gerzen     Oct 29, 2009
This is what we (at the company I am working for) have been doing with Haml { http://haml-lang.com/ } & Sass { http://sass-lang.com/ }

Definitely awesome to know that the next time I go to code up a site in plain 'ol HTML & CSS there is some awesomeness available

Dane Hesseldahl     Oct 29, 2009
This is stellar guys - excellent work.

Now someone port it to Python for me.

David Hund     Oct 29, 2009
Interesting idea and I'll check it out.

There's a lot of stuff happening regarding 'extending CSS': I have just started fiddling with Lesscss.org and SASS. I'd love to see where this goes.

Matt Kenefick     Oct 28, 2009
@justin
Thanks! This does not generate raw compile files at the moment. Caching is a feature I look forward to implementing a little later in the project. This round is to get some feet wet to what this is all about through an extremely simple yet potentially robust version.

In comparison to native CSS executions, it should have the same executional speed but the overhead from the server will be a little more because it is being processed through the PHP engine first. Rosemary outputs an actual CSS file to the server so client side rendering will be the same, if not faster (depending on what filters you use), but the only overhead would be server side. This is not a big deal for most cases but will be addressed as time goes on.

@George
Thanks! OSMCFBMS4CSS are all over the place so that's nice to hear.

George     Oct 28, 2009
Well, well, well. That is the very best OSMCFBMS4CSS that I have ever seen. It's very windy out here by the way.

justin     Oct 28, 2009
looks sweet. so are dynamic files served to the user or are you using this script to generate a static file that gets cached? how does performance compare to native css executions?


Speak






Submit »