Flex WISHED It Supported CSS

I was reading a post about the Top 10 Flex Misconceptions and read in the 2nd section that “Flex also uses CSS for styling of components / applications.”

I know since day one Adobe has listed CSS styling as a feature of Flex. But anyone who has used CSS to style a web page knows that Flex does not support CSS. It supports, well, SS.

CSS stands for Cascading Style Sheets. Flex is missing the “Cascading” part of it. CSS is all about using a style sheet to describe the “presentation of the document” (World Wide Web Consortium CSS1). Because of the limited amount of the CSS standard that Flex supports, you really can’t define that without a LOT of verbosity.

Let’s take some examples of what I’d LIKE to do in Flex, sometimes I can, sometimes I can’t. I’d like to set the colors in my scrollbar buttons. Well, I can do this by using the many styles defined in ScrollBar such as upArrowUpSkin, upArrowOverSkin, and upArrowDownSkin. I had to look up the styles for ScrollBar to see if I could do that. Buttons have some nice styles that let you set the background color, but I can’t access that so I’ll have to replace the skin entirely.

ScrollBar {
  upArrowUpSkin: Embed("myUpArrowUp.png");
... etc.
}

Now if I wanted to change those colors for this area of my app or that area, or for popups only etc. I’d have to go through and make sure each ScrollBar had a styleName that I could then use in the stylesheet for that. Here’s what you SHOULD be able to do with CSS:

#certainPartOfMyApp ScrollBar Button.up {
  background-gradient-colors: #999, #555;
}
#certainPartOfMyApp ScrollBar Button.down {
  background-gradient-colors: #555, #999;
}

Beautiful! Flex component developers didn’t need to add a style on the ScrollBar component for every conceivable style that one might want to change for its buttons. With real CSS you can access them because the selectors allow your styles to cascade down to all scrollbars under the component with an ID of certainPartOfMyApp. I could have had one definition to style ALL buttons under that ScrollBar, but decided to use the styleNames which might be in place if Flex supported this to style each button separately.

Now if you were to use CSS pseudo selectors (e.g. a:hover) and mapped them to a component’s “state” then you could really get going. Say your main application has several states in which different areas of the APP are viewable.

/* setting the state of the app will automatically change what Canvas
is showing. Good-bye ViewStack! */
#app Canvas {
  visible: false;
}
#app:login #loginScreen {
  visible: true;
}
#app:catalog #catalogScreen {
  visible: true;
}
#app:checkout #checkoutScreen {
  visible: true;
}

/* We should even be able to set the width/height/x/y in styles shouldn't we? Not just top, left, bottom, and right */
#catalogScreen .leftColumn {
  width: 200;
}
#catalogScreen .rightColumn {
  width: 100%;
}
#catalogScreen:addToCart .leftColumn {
  width: 100%;
}
#catalogScreen:addToCart .rightColumn {
  width: 200;
}

Now when I change the state of my app a different view is presented. And when I change the state of my catalogScreen the columns change their size, perhaps throwing an effect in there for smoothness could be part of the CSS as well.

I’ve put together a full implementation of CSS2 as far as the format is concerned and the selectors etc. It doesn’t use the box model etc. that HTML uses, but I’ll post a demo of it up here soon. It will of necessity use my own components because there is no way to integrate it into the existing Flex styling framework. I’ve looked, I’ve tried. :)

Vote For CSS!

If enough of us ask for it Adobe will give it to us. It’s already too late to include in Flex 3 which should be coming out soon, but now is the time to be asking for big changes like this for Flex 4. Go sign up and vote for this feature in Adobe’s bug base.

UPDATE: Thanks to all those who voted this bug was fixed (or feature added) in Flex 4! Great job everybody. And thank you Adobe for listening to the community.

8 Responses to “Flex WISHED It Supported CSS”

  1. Lordy Says:

    See Ely greenfields, flex roadmap session where he talks about implmenting pseudo selectors, with (possibly) new MVC style components.

    http://www.onflexwithcf.org/index.cfm/2007/10/19/Flex-Roadmap-presented-by-Ely-Greenfield–Videos

  2. Jacob Wright Says:

    Lordy – I know, I was there for it at MAX. I am very excited about that step if they go with it. However, that is only a part of what I hope Flex will support.

    Update – We have 16 votes for this feature request so far. That brings the feature up to #4 in the Flex bug-base.

  3. CSS Support in Flash 9 (actionscript3) | leonardoPicado.com's blog Says:

    […] they both use the same plugin and both use AS3 their lines are equal, however it seems that a lot of people feels my pain and would like for Flex (and obviously Flash as well) to support the CSS Level 2 […]

  4. Nick Bilyk Says:

    “Flex is missing the “Cascading” part of it.”

    Too true, unfortunately. Currently causing me a big headache.

  5. Fahad Ansari Says:

    I don’t think it supports inheritance either. I may be wrong but it seems like I have to define background on every single component and it does not inherit background of the parent.

    I just started working with Flex so I may be wrong..

  6. nanu Says:

    Another misnomer from my perspective is runtime styling that Flex is capable of. In the real sense, this is not runtime styling, it is more runtime loading of canned stylesheets that have been precompiled using mxmlc – anything that requires a customer to compile is not dynamic from my perspective.

    In flex, there is no clean way to suck in a css that works perfectly when used at compile time but instead feed it at runtime to produce the same effect… Yes, I’ve seen CSSParsers and all but none of them really work to the full extent required.

    Yes you can use a urlloader, load the stylesheet and use the following pseudo code

    var sheet = new StyleSheet();
    sheet.parseCSS(cssdatareadfromurl);

    var styleCount:int = sheet.stylenames.length;

    for each style read into array
    currSelector = new CSSStyleDeclaration();
    set all styles using this selector
    i.e currSelector.setStyle(prop, value);

    StyleManager.setStyleDeclaration(stylename, currSelector, true);

    But you will notice that most of your styles do not work for many reasons.

    1. The stylesheet parser lowercases all style selector names – so you cannot really use any of this stuff…

    2. If you figure out a way to preserve the names, then things like gradients etc that require comma separated values would cause a runtime exception.

    3. To overcome problem 2, convert all comma separated values into arrays using the String.split() method. You will not see runtime exceptions anymore…

    4. But gradients don’t work, background images don’t work, and many of the styles that work when used at compile time just do not work when fed into the style manager at runtime…

    From my experience runtime styling or style overriding is a big can of worms (buggy code/design) using the Stylemanager.setStyle functionality…

    If you are doing dainty things like changing the background color then there are no problems!

  7. kingschnulli Says:

    I have build a little class that makes it possible to set properties through css, works for width/height but also for any other property if you use it carefully. Check it out here:

    http://myflex.wordpress.com/2009/12/20/adding-width-height-x-and-y-into-the-css-model-of-flex/

  8. Dan Orlando Says:

    Hah…the amazing thing is that so many Flex developers come from the world of web dev (including myself), and yet this is something that many of us just accepted as the way it is without a second thought. Not that doing so is a problem, it is the misuse of the CSS term that can cause confusion for future generations of developers.

    Kudos for pointing this out.
    -Dan