Fx4 VIII: Soporte CSS ampliado

En esta cuarta versión de Flex se han producido cambios considerables en la arquitectura de componentes así como en el lenguaje MXML. Esto se ha hecho para potenciar varios aspectos como son la productividad, facilitar el workflow designer / developer o la integración con herramientas externas.
En esta entrada se verá en profundidad las novedades referentes al soporte CSS en Flex 4.

Espacios de nombre

A partir de Flex 4 todos los selectores CSS requieren de un espacio de nombres para evitar la ambiguedad entre nombres de clase definidos en halo y spark.
Un ejemplo de esta situación la podemos encontrar en la clase Button.
Para spark la clase Button se define en spark.components.Button, en cambio para halo se define en mx.controls.Button. Lo que se puede apreciar es que en ambos casos las clases se llaman igual. Si se hubiera mantenido el modelo CSS de Flex <= 3 tendríamos un problema de ambiguedad al querer redefinir los estilos de la clase Button como se puede ver.
El código que necesitamos para definir los estilos de Button para spark y halo a la vez sería el siguiente:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.                xmlns:s="library://ns.adobe.com/flex/spark"
  4.                xmlns:mx="library://ns.adobe.com/flex/mx">
  5.     <fx:Style>
  6.         @namespace s "library://ns.adobe.com/flex/spark";
  7.         @namespace mx "library://ns.adobe.com/flex/mx";
  8.         s|Button{ lineThrough: true; }
  9.         mx|Button{ icon: Embed('favorite.png'); }
  10.         .botonRedondeado{ cornerRadius: 10; }
  11.     </fx:Style>
  12.    
  13.     <s:layout><s:VerticalLayout paddingLeft="50" paddingTop="50" /></s:layout>
  14.    
  15.     <s:Button label="Spark Button 1" />
  16.     <s:Button label="Spark Button 2" styleName="botonRedondeado" />
  17.     <mx:Button label="Halo Button 1" />
  18.     <mx:Button label="Halo Button 2" styleName="botonRedondeado" />
  19.    
  20. </s:Application>

Obtenemos esto:
namespaces
Podemos observar dos peculiaridades con respecto a Flex3. La primera las declaraciones de espcios de nombre @namespace alias "URI"; y la segunda la forma de contextualizar las declaraciones con alias|ClassName.
Por otra parte vemos que podemos seguir utilizando los selectores de clase de siempre de la misma forma que antes y que son aplicables a componentes halo y spark indistintamente.

Selector de clase múltiple

Una forma muy potente de modularizar los estilos es definirlos de la forma más atómica posible. Cuanto más se especialice la declaración de un estilo más versatil será.
A partir de Flex 4 se pueden asignar múltiples selectores de clase a un mismo componente separados por un espacio:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.                xmlns:s="library://ns.adobe.com/flex/spark"
  4.                xmlns:mx="library://ns.adobe.com/flex/mx">
  5.     <fx:Style>
  6.         .iconoFavoritos{ icon: Embed('favorite.png'); }
  7.         .botonRedondeado{ cornerRadius: 10; }
  8.         .textoRojo{ color: #FF0000; }
  9.         .texto25{ fontSize: 25; }
  10.     </fx:Style>
  11.    
  12.     <s:layout><s:VerticalLayout paddingLeft="50" paddingTop="50" /></s:layout>
  13.  
  14.     <s:Button label="Spark Button 2" styleName="texto25 botonRedondeado textoRojo" />
  15.     <mx:Button label="Halo Button 2" styleName="iconoFavoritos textoRojo" />
  16.    
  17. </s:Application>

Obtenemos esto:
multiple_selectors

Selector por #id

Otra característica añadida es el soporte para selectores por identificador, al más puro estilo HTML:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.                xmlns:s="library://ns.adobe.com/flex/spark"
  4.                xmlns:mx="library://ns.adobe.com/flex/mx">
  5.    
  6.     <fx:Style>
  7.         #favoritos{
  8.             icon: Embed('favorite.png');
  9.             cornerRadius: 10;
  10.             fontSize: 25;
  11.         }
  12.     </fx:Style>
  13.    
  14.     <s:layout>
  15.         <s:VerticalLayout paddingLeft="50" paddingTop="50" />
  16.     </s:layout>
  17.  
  18.     <mx:Button id="favoritos" label="Favoritos" />
  19.    
  20. </s:Application>

Obtenemos esto:
id_selector

Selectores descendientes

Los selectores descendientes nos ofrecen la posibilidad de contextualizar las declaraciones de nuestros estilos dentro del ámbito de una clase determinada.
Por ejemplo, si queremos declarar un estilo que afecte a todos los campos de texto que estén dentro de un formulario lo haríamos de la siguiente forma:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.                xmlns:s="library://ns.adobe.com/flex/spark"
  4.                xmlns:mx="library://ns.adobe.com/flex/mx">
  5.    
  6.     <fx:Style>
  7.         @namespace s "library://ns.adobe.com/flex/spark";
  8.         @namespace mx "library://ns.adobe.com/flex/mx";
  9.  
  10.         mx|FormItem s|TextInput{ color: #FF0000; }
  11.         mx|FormItem mx|TextInput{ color: #00FF00; }
  12.     </fx:Style>
  13.    
  14.     <s:layout>
  15.         <s:VerticalLayout paddingLeft="50" paddingTop="50" />
  16.     </s:layout>
  17.    
  18.     <s:TextInput text="TextInput fuera de Form"/>
  19.     <mx:Form>
  20.         <mx:FormItem label="Dentro FormItem">
  21.             <s:TextInput text="Spark TextInput"/>
  22.             <mx:TextInput text="Halo TextInput"/>
  23.         </mx:FormItem>
  24.     </mx:Form>
  25.    
  26. </s:Application>

Obtenemos esto:
descendant_selector

Pseudo selectores

Los pseudo selectores permiten aplicar estilos sobre un componente teniendo en cuenta el skin state en el que está. Para ello se debe tener conocimiento de los estados de skin disponibles para el componente en cuestión.
Por ejemplo, la clase spark.components.Button dispone de los estados up, over, down y disabled (cada componente tiene especificados sus skin states en la documentación ASDoc), por lo tanto podemos sacar partido de los pseudo selectores CSS del siguiente modo:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.                xmlns:s="library://ns.adobe.com/flex/spark"
  4.                xmlns:mx="library://ns.adobe.com/flex/mx">
  5.    
  6.     <fx:Style>
  7.         @namespace s "library://ns.adobe.com/flex/spark";
  8.         @namespace mx "library://ns.adobe.com/flex/mx";
  9.  
  10.         s|Button:up{ fontSize: 10; }
  11.         s|Button:over{ fontSize: 20; }
  12.         s|Button:down{ fontSize: 30; }
  13.     </fx:Style>
  14.    
  15.     <s:layout>
  16.         <s:VerticalLayout paddingLeft="50" paddingTop="50" />
  17.     </s:layout>
  18.    
  19.     <s:Button label="Spark Button"/>
  20.    
  21. </s:Application>

Obtenemos esto:
Up:
button_up
Over:
button_over
Down:
button_down

Combinando

Por supuesto lo más interesante de todo es que todas estas funcionalidades las podemos combinar:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.                xmlns:s="library://ns.adobe.com/flex/spark"
  4.                xmlns:mx="library://ns.adobe.com/flex/mx">
  5.    
  6.     <fx:Style>
  7.         @namespace s "library://ns.adobe.com/flex/spark";
  8.         @namespace mx "library://ns.adobe.com/flex/mx";
  9.  
  10.         mx|Panel mx|ControlBar s|Button:up{ color: #FF0000; fontSize: 6; }
  11.         mx|Panel mx|ControlBar s|Button:over{ color: #00FF00; fontSize: 30; }
  12.        
  13.         mx|Panel mx|Form #formItem2 s|TextInput{ color: #0000FF; }
  14.        
  15.     </fx:Style>
  16.    
  17.     <s:layout>
  18.         <s:VerticalLayout paddingLeft="50" paddingTop="50" />
  19.     </s:layout>
  20.    
  21.     <mx:Panel title="Ejemplo">
  22.         <mx:Form width="100%" height="100%">
  23.             <mx:FormItem label="Label">
  24.                 <s:TextInput text="Lorem Ipsum"/>
  25.             </mx:FormItem>
  26.             <mx:FormItem id="formItem2" label="Label">
  27.                 <s:TextInput text="Lorem Ipsum"/>
  28.             </mx:FormItem>
  29.         </mx:Form>
  30.         <mx:ControlBar horizontalAlign="right">
  31.             <s:Button label="Spark Button"/>
  32.         </mx:ControlBar>
  33.     </mx:Panel>
  34.    
  35. </s:Application>

Obtenemos esto:
Up:
combinando_up
Over:
combinando_over

Conclusión

Con Flex4 se dispone de una mayor versatilidad y control en lo que a declaración de estilos se refiere. La implementación CSS de Flex <= 3 dejaba bastante que desear y este paso sin duda está apuntando hacia el buen camino.
Cabe destacar que se dipone de una API AS3 para asignar todos estos estilos de forma programática y que no dudo se cubrirá en una futura entrada así que, manteneos atentos!

Notas

• Los selectores de clase son los que llevan punto '.' antes del identificador. Por ejemplo .botonRedondeado{}, los selectores de tipo son los que se asocian con una clase. Por ejemplo s|Button




2votos  Vota!!

Acerca de esta entrada