OOCSS - Poniendo OOrden en CSS.
¿Qué es OOCSS? Una forma de optimizar la organización y arquitectura de los estilos CSS. En esta presentación veremos qué problemas trata de resolver, qué principios sigue y cómo aplicarlos.
Esta versión de la presentación incluye las notas del presentador.
1. { OOCSS
Poniendo OOrden en CSS
}
@janogarcia · http://janogarcia.es
¿Qué es OOCSS? Una forma de optimizar la organización/arquitectura CSS. En esta presentación veremos qué problemas
trata de resolver, qué principios sigue y cómo aplicarlos.
7. e
ODIO
Heredar estilos de una
manera impredecible.
2
Sobrescribir y neutralizar estilos que están siendo heredados de una manera impredecible desde otros elementos de la
cascada.
8. CSS
ENV
ENE
6
N ADO
selectores #id
modificador!important
estilos en línea
Acabas recurriendo al modificador !important y a los estilos en línea, lo que complica aún más las situación. Specifity wars!
9. 1+1=2
Comportamiento
OOCSS
predecible.
La cascada, la especificidad y la herencia dejarán de ser tus enemigos, pudiendo identificar y controlar su efecto en todo
momento.
10. e
ODIO
3
Crecimiento sin control,
pesadilla de
mantenimiento.
12. O OOCSS
Arquitectura modular.
{
Se basa en la creación de objetos CSS
Reusables.
Extensibles.
Anidables.
- Reusables: módulos reusables a nivel de sitio o incluso entre diferentes proyectos. (botones de FGR)
- Extensibles: módulos derivados de un mismo módulo base y que representan diferentes variaciones del mismo. (widget-
title y container de FGR)
- Anidables: módulos compuestos por la agregación de diferentes módulos. (widgets del sidebar de FGR)
13. { }
Retoma el
CONTROL con OOCSS
OOCSS se inspira en algunos principios de la OOP (abstracción, herencia, composición...), aunque la interpretación que
hace de estos principios es un tanto libre (no muy ortodoxa para los puristas de la OOP), pero quizás no sea tan
importante la precisión de cómo se interpretan estos principios sino cómo nos ayudan a pensar en términos de módulos y
a plantear una arquitectura modular adecuada en el contexto de CSS.
14. OOCSS
{ Modular. Escalable.
Eficiente. Simple.
Semántico. Mantenible.
OOCSS busca el equilibrio
}
OOCSS trata de buscar una solución a todos estos problemas derivados de la falta de una arquitectura CSS y HTML
adecuada, considerando como arquitectura óptima aquella que cumpla con los siguientes objetivos de diseño:
- Modular: Un diseño modular que permita la creación de componente reusables y extensibles, evitando así el código
repetitivo (DRY) y sus problemas asociados.
- Escalable: Una arquitectura que sea aplicable a proyectos de cualquier tamaño.
- Eficiente: Un código lo más ligero posible, tratando de minimizar el impacto sobre el rendimiento.
- Simple: Un estilo claro y conciso (KISS). Un comportamiento predecible ("Only predictable components are reusable").
- Semántico: Una estructura HTML lo más semántica posible, aunque en ocasiones se vea comprometida por limitaciones
de CSS.
- Mantenible: Una arquitectura transparente que facilite tanto el desarrollo iterativo e incremental, como las futuras
revisiones del código. Una serie de convenciones que faciliten el trabajo colaborativo.
OOCSS busca un equilibrio entre todos estos objetivos de diseño, estableciendo un compromiso cuando estos entren en
conflicto.
15. { }
Sintaxis estándar de CSS
OOCSS=CSS
OOCSS es CSS, es decir, no difiere de la sintaxis estándar de CSS que ya conoces. Ni introduce elementos nuevos, ni se
comporta de manera diferente, OOCSS no es más que una serie de patrones o principios sobre cómo optimizar la
organización de los estilos CSS y la estructura HTML (y desacoplándolos al mismo tiempo).
16. ¿Alguien lo usa?
"Mailchimp reduced CSS by 40%, Facebook by 19% with OOCSS."
https://twitter.com/#!/darylsws/statuses/70408894312230912
18. Estructura Hoja de Estilos
FRAMEWORK
Reset Normaliza las inconsistencias
entre navegadores.
Base
Componentes reusables entre
Grid proyectos.
Widgets
Helpers
THEME
Widgets Modulariza, construye tu sitio
a partir de componentes reusables
Pages a nivel de proyecto.
FRAMEWORK
Reset: Normalize browser default styles.
Scope: elements and pseduo-elements, no namespaces.
Base: HTML elements (headings, paragraphs, quotes, anchors, forms, buttons, tables, lists...). Typography (fonts, font
rendering normalization, scale, baseline grid...).
Scope: elements and pseudo-elements, no namespaces.
Grid: Layout foundation.
Scope: class names as global namespaces.
Widgets: Reusable widgets across projects (menus, tabs, buttons, forms…).
Scope: widget class name as global namespace.
Helpers: Reusable helpers across projects. Clases auxiliares, no componentes. (.float_left, .float_right, .clear/.clearfix,
self-clear, .phark, .hidden…).
Scope: helper class name as global namespace.
THEME
Widgets: Project specific widgets/modules (navigation, notifications, help, tips, search, login, gallery, player,…)
Scope: widget class name as global namespace.
Pages: Page specific widgets or style overrides
Scope: body class name as global page namespace.
19. e OOCSS
Patrón recomendado.
{
Usa un Reset y un Base.
20. Estructura Hoja de Estilos > Reset y Base
FRAMEWORK
Reset Normalizan estilos entre navegadores,
eliminando inconsistencias y estableciendo
Base una base común.
Grid Sin ellos no podríamos partir de una base
conocida, nuestros estilos no tendrían un
Widgets comportamiento predecible en los diferentes
navegadores.
Helpers
Evitan el código repetitivo (DRY).
Usa una ya existente: 960.gs, formalize.me,
normalize.css, html5boilerplate, YUI... O crea
THEME la tuya propia.
Widgets
Pages
El único lugar, salvo pequeñas excepciones, donde tiene sentido usar elementos/pseudo-elementos HTML en los
selectores CSS, ya que estamos definiendo valores por defecto. Salvo contadas excepciones, en el resto de secciones
usaremos clases.
Nota: No uses el selector universal *. Más en el apartado sobre rendimiento.
21. Estructura Hoja de Estilos > Reset y Base
FRAMEWORK
Reset Normaliza estilos entre navegadores,
eliminando inconsistencias y estableciendo
Base una base común.
h
Grid Sin ellos no podríamos partir de una base
conocida, nuestros estilos no tendrían un
DEMO
Widgets comportamiento predecible en los diferentes
navegadores.
Helpers
Evitan el código repetitivo (DRY).
Usa una ya existente 960.gs, formalize.me,
normalize.css, html5boilerplate, YUI... O crea
THEME la tuya propia.
Widgets
Pages
Demo: Reset y Base de FGR. Comentar código, activar y desactivar.
23. Estructura Hoja de Estilos > Grid
FRAMEWORK
Reset “Some years ago, I found CSS Framework like Blueprint
to be a waste of time. I didn't want to clutter my HTML
Base markup with non-semantic classes for handling the styling.
Now I still don't think cluttering the HTML with span-6 pull-2
Grid is the best thing that happened to CSS, but I found it much
better than cluttering my CSS with endless overflow:hidden
Widgets and float:left; margin-right:10px declarations.”
http://www.pixelastic.com/blog/201:7-advices-to-start-using-oocss-as-a-coding-practice
Helpers
THEME
Widgets
Pages
24. Estructura Hoja de Estilos > Grid
FRAMEWORK
Reset O repites una y otra vez las reglas
necesarias para crear layouts1 o abstraes esas
Base reglas y las aplicas como clases2. Elige.
1 float:left,margin-right:10px, overflow:hidden...
Grid
2 .grid-6, .grid-10, .push-1...
Widgets
Evitan el código repetitivo (DRY). Abstraen
Helpers inconsistencias entre navegadores.
Usa una ya existente: 960.gs, 978.gs, blueprint,
YUI... O crea la tuya propia.
THEME
Widgets
Pages
El W3C no especifica ninguna recomedación sobre el nombre de las clases, no considera que la semántica resida en los
nombres de clase.
Nota: CSS3 contará con soporte nativo para Grids y Layouts, lo que seguramente hará innecesarios los frameworks
actuales. https://twitter.com/#!/janogarcia/status/56044926848352256
http://www.slideshare.net/chandleryu/everything-you-know-about-css-is-wrong
25. Estructura Hoja de Estilos > Grid
FRAMEWORK
Reset O repites una y otra vez las reglas
necesarias para crear layouts1 o abstraes esas
Base reglas y las aplicas como clases2. Elige.
h
1 float:left,margin-right:10px, overflow:hidden...
Grid
2 .grid-6, .grid-10, .push-1...
DEMO
Widgets
Evitan el código repetitivo (DRY). Abstraen
Helpers inconsistencias entre navegadores.
Usa una ya existente: 960.gs, 978.gs, blueprint,
YUI... O crea la tuya propia.
THEME
Widgets
Pages
Demo: Grids de FGR. Activar y desactivar.
26. e OOCSS
Patrón recomendado.
{
Crea Objetos reusables.
27. Estructura Hoja de Estilos > Widgets > Crea Objetos reusables
FRAMEWORK 1 2 3 4 5 6 7 8
Reset “Build HTML from the component library. New pages
should not generally require additional CSS.”
Base - Nicole Sullivan
Grid Crea una librería de componentes reusables para
el proyecto o incluso independientes del proyecto.
Widgets
Los objetos son un conjunto de clases CSS
Helpers relacionadas que responden a una funcionalidad
determinada. Estos objetos deben ser reusables,
extensibles y anidables.
La clave está en identificar esos objetos y en
THEME saber aprovechar la extensión y la composición.
Widgets Evitan el código repetitivo (DRY). Maximizan la
reusabilidad.
Pages
Itera, refactoriza!
Cuando disponemos del diseño completo del sitio será más fácil reconocer los objetos y los casos en los necesitaremos
extenderlos o anidarlos. Si sólo disponemos de parte del diseño no podremos anticipar de qué manera podrán ser
extendidos o compuestos, pero esto no es algo que nos deba detener, ya que como cualquier proyecto,
independietemente de su estado actual, seguirá evolucionando, por lo que serán necesarias continuas refactorizaciones.
Al crear componentes te detendrás a pensar más en la arquitectura/API y menos en los detalles de la implementación
(declaraciones de estilos). Slides 3 y 4: http://www.slideshare.net/stubbornella/what-is-object-oriented-css
“I think the single-line format bothers me less in #oocss because the very intent of the system is to highlight the cascade &
specificity.”
https://twitter.com/#!/sunpig/statuses/67249395002900480
“Do not abuse of presentational class names, don’t go that far so you completely abstract implementation.” (enterprise css
joke http://enterprise-css.com/9)
“Semántica”:
Cuanto más generalizas/abstraes el uso/la función de tus clases, menos semánticos parecerán sus nombres, ya que deja
de haber una relación 1:1 entre los estilos de esas clases y el módulo/snippet HTML y su función/localización. Al abstraer/
generalizar su uso ésta podra ser usada en diferentes módulos que pueden no estar relacionados, ni en función ni en
localización, la única manera de poder identificarlas será asignándoles un nombre más presentacional/genérico. Un
heading por ejemplo podría ser: .title-subsection. Si te preocupa la semántica, siempre puedes añadir una clase más
“semántica” al elemento HTML: .cabecera, <h2 class="title-subsection cabecera"></h2>. Dicho sea de paso, el W3C no
pone ninguna pega a usar nombres de clases "no semánticos" (la semántica está en el HTML no en las clases CSS). Otro
ejemplo son los grids, helpers y casi cualquier otro estilo perteneciente a la sección "Framework".
28. Estructura Hoja de Estilos > Widgets > Crea Objetos reusables
FRAMEWORK 1 2 3 4 5 6 7 8
Reset “Build HTML from the component library. New pages
should not generally require additional CSS.”
Base - Nicole Sullivan
h
Grid Crea una librería de componentes reusables para
el proyecto o incluso independientes del proyecto.
DEMO
Widgets
Los objetos son un conjunto de clases CSS
Helpers relacionadas que responden a una funcionalidad
determinada. Estos objetos deben ser reusables,
extensibles y anidables.
La clave está en identificar esos objetos y en
THEME saber aprovechar la extensión y la composición.
Widgets Evitan el código repetitivo (DRY). Maximizan la
reusabilidad.
Pages
Itera, refactoriza!
Demo: Revisar organización de código sección Widgets de FGR.
29. e OOCSS
Patrón recomendado.
{
Simplifica la cascada.
30. Estructura Hoja de Estilos > Widgets > Simplifica la Cascada
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Si la cascada no tiene un comportamiento
predecible tus estilos tampoco lo tendrán, por
Base lo que nunca podrán ser realmente reusables.
Grid Di adiós a los selectores #id, a los estilos en
línea y a las declaraciones !important. De lo
Widgets contrario no conseguirás que tus estilos tengan
un comportamiento predecible.
Helpers
THEME
Widgets
Pages
31. Estructura Hoja de Estilos > Widgets > Simplifica la Cascada > No #id
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 2.1 No uses #id como selector
Base Sólo puede haber uno en la página, impidiendo
la reusabilidad y limitando la modularización
Grid
Singleton, no puedes crear varias instancias,
Widgets no puede haber objetos extendidos o compuestos
en la misma página: #objeto y #objeto.extendido
Helpers
Complican la especificidad y la cascada, tienen
demasiado peso. No podremos crear reglas del
mismo peso cuando combinemos objetos basados
en .clase y en #id.
THEME
Úsalos únicamente en el HTML como hooks de
Widgets JavaScript o para accesibilidad (formularios,
Pages anclas...).
https://github.com/stubbornella/oocss/wiki/faq
http://oli.jp/2011/ids/
32. Estructura Hoja de Estilos > Widgets > Simplifica la Cascada > No #id
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 2.1 No uses #id como selector
Base Sólo puede haber uno en la página, impidiendo
la reusabilidad y limitando la modularización
h
Grid
Singleton, no puedes crear varias instancias,
DEMO
Widgets no puede haber objetos extendidos o compuestos
en la misma página: #objeto y #objeto.extendido
Helpers
Complican la especificidad y la cascada, tienen
demasiado peso. No podremos crear reglas del
mismo peso cuando combinemos objetos basados
en .clase y en #id.
THEME
Úsalos únicamente en el HTML como hooks de
Widgets JavaScript o para accesibilidad (formularios,
Pages anclas...).
Tests OOCSS en Espresso.
33. Estructura Hoja de Estilos > Widgets > Simplifica la Cascada > Ni estilos en línea ni !important
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 2.2 Ni estilos en línea ni !important
Base Úsalos únicamente para sobreescribir estilos de
una hoja externa fuera de tu control (por ejemplo,
Grid un widget externo de comentarios).
Widgets Si estás usando estilos en línea o el modificador
!important para sobreescribir estilos creados
Helpers por tí es un claro síntoma de que algo va mal, te
has cargado la cascada.
THEME
Widgets
Pages
https://github.com/stubbornella/oocss/wiki/faq
http://oli.jp/2011/ids/
34. Estructura Hoja de Estilos > Widgets > Simplifica la Cascada > ¡Olvida la cascada!
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 2.3 ¡Olvida la cascada!
Base - Olvídate de tener que calcular la especificidad de
los selectores.
Grid
- No dependas del orden del código fuente
Widgets (cascada).
- Usa valores absolutos para propiedades que se
Helpers heredan (evita tight coupling con el HTML).
Los estilos se deben heredar de una manera
simple y completamente predecible. De esta
manera tus objetos se comportarán de una forma
THEME predecible, elegirás tus selectores con total
seguridad, de una forma sencilla y sin sorpresas
Widgets desagradables, ya que no habrá dependencias ni
influencias desconocidas (loose coupling).
Pages
http://images.cheezburger.com/completestore/2010/10/26/3e0a8982-05e1-4952-af7b-e22650c4125c.jpg
ESPECIFICIDAD:
Para conocer más sobre cómo calcular la especificidad de selectores:
#id = 100, .clase = 10, elemento = 1
Ejemplo, de menor a mayor especificidad:
p=1
div p = 1+1 = 2
.tree = 10
div p.tree = 1+1+10 = 12
#baobab = 100
body #content .alternative p = 1+100+10+1 = 112
http://htmldog.com/guides/cssadvanced/specificity/
http://css-tricks.com/specifics-on-css-specificity/
http://www.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
PROPIEDADES HEREDABLES:
Para conocer más sobre cómo funciona la cascada y qué estilos se heredan:
http://blogs.globallogic.com/cascading-style-sheet-css-%E2%80%93-what-must-web-developer-know
http://reference.sitepoint.com/css/inheritance
http://www.communitymx.com/content/article.cfm?page=1&cid=2795D
http://www.w3.org/TR/CSS21/propidx.html
El peor de los casos es cuando usamos unidades relativas (%, ems...) en los valores de propiedades heredables. La
anidación se convierte en un infierno, altamente dependiente del HTML (tight coupling). Inflexible, tedioso y costoso en
tiempo. Herramientas para calcular em’s: http://riddle.pl/emcalc/, http://pxtoem.com/
El debate sobre una y otra opción continuará (font-size Relativo vs Absoluto, Incrementar tamaño de fuente vs Zoom de
página), personalmente he optado por la solución más pragmática, usar medidas absolutas.
“Before we get into the pedantic debate about pixel font sizes, let me just say — Let’s not go there. I’m aware of all the
arguments, and have even toyed with making elastic layouts. For me, it’s about ROI. You can spend countless hours toying
with font-size inheritance, like I did on the Geniant Blog, or you can set sizes in pixels and get on with your life.” Nathan
Smith - 960.gs, formalize.me
35. Estructura Hoja de Estilos > Widgets > Simplifica la Cascada > ¡Olvida la cascada!
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 2.3 ¡Olvida la cascada!
Base - Olvídate de tener que calcular la especificidad de
los selectores.
h
Grid
- No dependas del orden del código fuente
(cascada).
DEMO
Widgets
- Usa valores absolutos para propiedades que se
Helpers heredan (evita tight coupling con el HTML).
Los estilos se deben heredar de una manera
simple y completamente predecible. De esta
manera tus objetos se comportarán de una forma
THEME predecible, elegirás tus selectores con total
seguridad, de una forma sencilla y sin sorpresas
Widgets desagradables, ya que no habrá dependencias ni
influencias desconocidas (loose coupling).
Pages
Demo: sección Widgets de FGR. Ver anotaciones de más abajo.
Widgets por oden alfabético, no tratando de reproducir el orden en el que aparecen en el HTML, no tratando de controlar la
cascada en el código fuente. Tampoco se usan tabulaciones para indicar anidación, ya que lo módulos pueden ser
anidados en cualquier orden en el código HTML, además de visualizarse mejor la jerarquía de estilos de un módulo
escribiendo los estilos en una sola linea (peor para control de versiones y debugging/diffs). Las propiedades también están
en orden alfabético, para que sean mas fáciles de localizar, mas predecibles (al igual que lo hace Firebug), cualquier otra
opción siempre responderá a preferencias personales que no serán igual de intuitivas para otras personas.
Dentro de la sección de WIDGETS/objetos no debes tratar de controlar la cascada por el orden del código fuente, si no
mediante reglas explícitas de anidamiento, ya que no podrás controlar como serán anidados, en qué orden, estos objetos
en la estructura HTML. Sólo puedes saber cómo será la jerarquía/estructura HTML de las secciones FRAMEWORK y PAGES.
36. e OOCSS
Patrón recomendado.
{
Usa clases, no elementos.
37. Estructura Hoja de Estilos > Widgets > Usa clases, no elementos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Usa clases para tus objetos CSS, evita usar
elementos HTML en los selectores CSS.
Base
3.1 Nombra los elementos asignándoles una
Grid clase. Los estilos serán más reusables, ya
que no dependerán del markup (.title en vez
Widgets de h1, h2...).
Helpers 3.2 No especifiques el elemento HTML al que es
aplicado una clase CSS (sí: .miclase, no:
div.miclase).
Especificar el elemento al que es aplicado una
THEME clase es redundante, innecesario y crea más
dependencia entre la estructura HTML y el
Widgets estilo CSS, obligándonos a modificar el CSS
cada vez que modifiquemos la estructura
Pages HTML (por ejemplo, al cambiar de ol a ul).
USA CLASES, NO ELEMENTOS:
↑ Mayor rendimiento de los selectores, ya que evitamos el uso de selectores poco específicos/genéricos/elementos a la
derecha (más en el apartado sobre rendimiento).
↓ Como contrapartida, mayor peso del HTML.
Excepción: Elementos estructurales que no van a variar como los elementos de tabla (tr, th, td... generalmente es más
conveniente usar elementos de tabla que asignar una clase a cada tr, td... además que si se trata de datos tabulares es
muy improbable que el marcado cambie en le futuro) o los enlaces/anclas (a). Y áreas de contenido editable por el usuario
(WYSIWYG), ya que es muy complicado tener control o tener cierta garantía sobre las clases asiganadas a los elementos
HTML creados.
Excepción: Si definimos una clase helper como por ejemplo ".flatten, .flat o .linearize" para cambiar a disposición
horizontal un conjunto de elementos de bloques, en el caso de una "ul" necesitaríamos aplicar unos estilos (ul list-style-
type:none;overflow:hidden, li margin-left:0;float:left) y en el caso de una colección de "div" otros estilos completamente
diferentes. En este caso podríamos definir ul.flat y div.flat.
38. Estructura Hoja de Estilos > Widgets > Usa clases, no elementos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Usa clases para tus objetos CSS, evita usar
elementos HTML en los selectores CSS.
Base
3.1 Nombra los elementos asignándoles una
h
Grid clase. Los estilos serán más reusables, ya
que no dependerán del markup (.title en vez
DEMO
Widgets de h1, h2...).
Helpers 3.2 No especifiques el elemento HTML al que es
aplicado una clase CSS (sí: .miclase, no:
div.miclase).
Especificar el elemento al que es aplicado una
THEME clase es redundante, innecesario y crea más
dependencia entre la estructura HTML y el
Widgets estilo CSS, obligándonos a modificar el CSS
cada vez que modifiquemos la estructura
Pages HTML (por ejemplo, al cambiar de ol a ul).
Demo: widgets .nav-1 y .regatas de FGR, el primero usa el elemento anchor y el segundo elementos de table.
39. e OOCSS
Patrón recomendado.
{
Minimiza los selectores.
40. Estructura Hoja de Estilos > Widgets > Minimiza los selectores
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 4.1 Legibilidad: No definas selectores
innecesariamente cualificados como .usuarios
Base table thead tr th a, con .usuarios thead a es
suficiente.
Grid
Evita sobre detallar cada nivel de la
Widgets estructura HTML. En la mayoría de ocasiones
basta con indicar el primer y último elemento.
Helpers No definas elementos redundantes como
tr th o ul li, bastaría con indicar th o li ya que
no pueden estar contenidos por un padre
diferente.
THEME 4.2 Rendimiento: El selector descendiente
” ” (espacio) es el que requiere un proceso
Widgets más intensivo por parte del navegador,
el hijo ”>” algo menos. Trata de limitar su
Pages
uso, por ejemplo, un máximo de 3 selectores
simples.
41. Estructura Hoja de Estilos > Widgets > Minimiza los selectores
FRAMEWORK 1 2 3 4 5 6 7 8
Reset 4.1 Legibilidad: No definas selectores
innecesariamente cualificados como .usuarios
Base table thead tr th a, con .usuarios thead a es
suficiente.
h
Grid
Evita sobre detallar cada nivel de la
DEMO
Widgets estructura HTML. En la mayoría de ocasiones
basta con indicar el primer y último elemento.
Helpers No definas elementos redundantes como
tr th o ul li, bastaría con indicar th o li ya que
no pueden estar contenidos por un padre
diferente.
THEME 4.2 Rendimiento: El selector descendiente
” ” (espacio) es el que requiere un proceso
Widgets más intensivo por parte del navegador,
el hijo ”>” algo menos. Trata de limitar su
Pages
uso, por ejemplo, un máximo de 3 selectores
simples.
Demo: vista outline de sección Widgets de FGR en Espresso, raramente se superan los 3 selectores simples.
42. e OOCSS
Patrón recomendado.
{
No dependas del contexto.
43. Estructura Hoja de Estilos > Widgets > No dependas del contexto
FRAMEWORK 1 2 3 4 5 6 7 8
Reset “Separate container and content: Break the dependency
between the container module and the content objects it
Base contains.”
- Nicole Sullivan
Grid
Los estilos de los objetos deben ser
Widgets independientes del lugar que ocupen en la página:
footer, sidebar, content... Si dependen de la
Helpers estructura de la página no serán reusables fuera
de ese contexto.
No: .sidebar .last-comments {}
Sí: .last-comments {}.
THEME
Ésto permitirá mostrar el widget en cualquier
Widgets página y en cualquier parte de la misma. Incluso
en otro proyecto, conociendo en todo momento
Pages sus dependencias de estilo y cómo le afectará el
nuevo contexto (herencia y namespaces).
“A class must know what it contains, but it should never know who contains it. This is huge. This specifically relates to
separating structure and skin. Classes should be portable.”
http://emphaticsolutions.com/2011/03/19/object-oriented-css-for-programmers.html
“The benefit of the OOCSS/namespace/location independent method is that if someone moves a block of code from the
sidebar to the main content section, the appearance will remain the same. It's about having expectable behaviour.“
“Only predictable components are reusable.”
http://groups.google.com/group/object-oriented-css/browse_thread/thread/
cbfcfc4bea9a8777/15d914846ad0068a#15d914846ad0068a
Excepción: Style overrides. Si necesitas modificar el aspecto de un widget en un determinado contexto (página o área)
puedes anteponer un selector que identifique ese contexto y sobreescribir los estilos para el mismo.
.pagina-inicio .nombre-selector o .sidebar .nombre-selector
44. Estructura Hoja de Estilos > Widgets > No dependas del contexto
FRAMEWORK 1 2 3 4 5 6 7 8
Reset “Separate container and content: Break the dependency
between the container module and the content objects it
Base contains.”
- Nicole Sullivan
h
Grid
Los estilos de los objetos deben ser
DEMO
Widgets independientes del lugar que ocupen en la página:
footer, sidebar, content... Si dependen de la
Helpers estructura de la página no serán reusables fuera
de ese contexto.
No: .sidebar .last-comments {}
Sí: .last-comments {}.
THEME
Ésto permitirá mostrar el widget en cualquier
Widgets página y en cualquier parte de la misma. Incluso
en otro proyecto, conociendo en todo momento
Pages sus dependencias de estilo y cómo le afectará el
nuevo contexto (herencia y namespaces).
Demo: sección Pages de FGR y widgets .header y .footer, viendo de estos últimos que objetos están abstraidos y qué
componentes forman parte del propio objeto.
45. e OOCSS
Patrón recomendado.
{
No crees dependencias
innecesarias entre objetos.
46. Estructura Hoja de Estilos > Widgets > No crees dependencias innecesarias entre objetos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset No agrupes selectores de distintos objetos,
creando dependencias innecesarias entre ellos
Base (Loose Coupling, Component Singularity).
Grid No uses el operador de agrupación ”,” para
combinar selectores de diferentes objetos. Úsalo
Widgets únicamente para agrupar selectores dentro de
un mismo objeto.
Helpers
Si estás creando bien tus objetos, y aplicando
bien la extensión y la composición te darás
cuenta que apenas necesitas usar el operador
de agrupación ”,”.
THEME
Widgets
Pages
“Loose Coupling. Coupling is the degree to which components of a system rely on each other. The less components
depend on each other the more reusable and flexible the system becomes. Our goal was a very loosely coupled system.”
“Component Singularity. Singularity is the degree to which components have a narrowly focused purpose. In CodeIgniter,
each class and its functions are highly autonomous in order to allow maximum usefulness.”
Compromiso: DRY vs Desacoplamiento y singularidad. Cuantas menos dependencias tienen nuestros objetos, éstos serán
más autonónomos y por lo tanto más portables y reusables.
DRY: Si es necesario repite el mismo conjunto de estilos en diferentes objetos. Si ves que repites una y otra vez ese mismo
conjunto de estilos en diferentes objetos, quizás significa que debes abstraerlos (por ejemplo grids, u otros contenedores)
y aplicar la composición.
47. Estructura Hoja de Estilos > Widgets > No crees dependencias innecesarias entre objetos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset No agrupes selectores de distintos objetos,
creando dependencias innecesarias entre ellos
Base (Loose Coupling, Component Singularity).
h
Grid No uses el operador de agrupación ”,” para
combinar selectores de diferentes objetos. Úsalo
DEMO
Widgets únicamente para agrupar selectores dentro de
un mismo objeto.
Helpers
Si estás creando bien tus objetos, y aplicando
bien la extensión y la composición te darás
cuenta que apenas necesitas usar el operador
de agrupación ”,”.
THEME
Widgets
Pages
Demo: widgets .regatas y .regata de FGR, los pocos casos en los que se usa el operador de agrupación “,”.
48. e OOCSS
Patrón recomendado.
{
Extiende los objetos.
49. Estructura Hoja de Estilos > Widgets > Extiende los objetos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Extiende los objetos a través de múltiples clases.
Base .objeto{}, es un objeto padre
.objeto.hijo{}, es una extensión de .objeto{}
Grid
Similar a cómo funciona la extensión en OOP.
Widgets Las clases hijas heredan las propiedades de la
clase padre, estas propiedades podrán ser
Helpers modificadas o ampliadas por las clases hijas.
Las clases hijas, al contrario que en OOP, no
requieren ser declaradas después de la clase
padre, pero se recomienda hacerlo para una
THEME mayor legibilidad.
Widgets
Pages
Nota: Olvídate de IE6.
50. Estructura Hoja de Estilos > Widgets > Extiende los objetos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Extiende los objetos a través de múltiples clases.
Base .objeto{}, es un objeto padre
.objeto.hijo{}, es una extensión de .objeto{}
h
Grid
Similar a cómo funciona la extensión en OOP.
DEMO
Widgets Las clases hijas heredan las propiedades de la
clase padre, estas propiedades podrán ser
Helpers modificadas o ampliadas por las clases hijas.
Las clases hijas, al contrario que en OOP, no
requieren ser declaradas después de la clase
padre, pero se recomienda hacerlo para una
THEME mayor legibilidad.
Widgets
Pages
Demo: .widget-title de FGR, multiples extensiones/variaciones de un mismo objeto base.
51. e OOCSS
Patrón recomendado.
{
Crea objetos compuestos.
52. Estructura Hoja de Estilos > Widgets > Crea objetos compuestos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset “Favor 'object composition' over 'class inheritance'.”
- http://en.wikipedia.org/wiki/Design_Patterns
Base
Algunos componentes de la página pueden
Grid estar compuestos de varios objetos
independientes.
Widgets
En este caso no aplicaremos la extensión de un
Helpers objeto base, sino la composición o anidamiento
de objetos.
Al utilizar este patrón nos encontramos con
uno de los mayores problemas de CSS, la falta
THEME de control total sobre la herencia de estilos y la
cascada.
Widgets
Pages
Un determinado componente sólo debe estar asociado a un objeto CSS en cada momento (Clase o Clase extendida), pero
puede estar compuesto por varios objetos en su interior (Composition, Reference).
“Sin quererlo he ideado una propuesta de namespaces para CSS. Tendríamos control total sobre la herencia y cascada.
Posibilitaría OOCSS real.”
https://twitter.com/#!/janogarcia/status/68641939947393024
Si queda tiempo lo veremos: https://sites.google.com/site/janogarciaes/css
53. Estructura Hoja de Estilos > Widgets > Crea objetos compuestos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Los problemas de anidación surgen por dos
motivos: propiedades CSS heredables, nombres
Base de clases compartidas (sin namespace).
Grid 8.1 Crea reglas específicas para cada caso de
anidación, de forma bidireccional y con el
Widgets mismo nivel de especifidad, así no
dependerás del orden en el código fuente.
Helpers En ellas especificaremos los estilos a
neutralizar o sobreescribir del módulo padre.
8.2 Todos los nombres de clases están en el
namespace global de CSS. Sé consistente
THEME con el formato de namespaces que uses, sé
consciente de sus ventajas e inconvenientes.
Widgets
Pages
A igualdad de especificidad de los selectores, la prioridad de los estilos vendrá determinado por la posición de los mismos
en el código fuente (cascada). Cuanto más tarde, mayor especificidad.
Hasta cierto punto podemos controlar/limitar la cascada con el selector hijo ">". Pero no sin limitaciones. Se trata de un
selector más posicional que el selector descendiente "(espacio)", es decir, depende más de la estructura HTML de la página
(tight coupling). Basta con que introduzcamos un wrapper para que el selector deje de funcionar.
Un selector más interesante es la pseudoclase CSS3 :first-of-type http://reference.sitepoint.com/css/pseudoclass-
firstoftype, la cual no presentaría el problema del selector hijo ">" y su estrecha dependencia con la estructura HTML. IE no
lo soporta hasta su versión 9.
No hay una solución ideal con las posibilidades actuales de CSS. No podemos crear un "reset wrapper" (algún preprocesador
lo hace... un tanto agresivo, peor rendimiento, no heredamos estilos de la sección framework por lo que tendríamos que
repetirlos) o limitar/controlar las clases de las que un selector hereda sus estilos, ya que no sólo depende del código CSS, si
no también del contexto HTML.
“La herencia en CSS es como la del heredero al trono, que sólo por estar ahí hereda todo lo que le rodea.”
https://twitter.com/#!/janogarcia/status/68722532341133312
Básicamente, quedan dos posibles soluciones:
1) Reordenar el código CSS teniendo en cuenta el sentido de las anidaciones (el módulo anidado debe aparecer en el código
fuente después del módulo contenedor/padre) y neutralizando los estilos heredados del módulo padre.
2) Crear reglas específicas para cada caso de anidación que tengan el mismo nivel de especifidad (para que no dependan
del orden en el código fuente), en ellas especificaremos los estilos a neutralizar o sobreescribir del módulo padre.
https://sites.google.com/site/janogarciaes/css
Si estás aplicando correctamente la herencia y la composición de objetos, raramente tendrás que sobreescribir/neutralizar
estilos heredados no deseados, salvo en los casos de anidaciones de módulos, ya que depedendemos del modelo de
herencia/cascada de CSS y éste no lo podemos controlar/limitar. Si por el contrario te encuentras sobreescribiendo/
neutralizando reglas en casos que no sean anidaciones, esto será un indicio de que algo va mal.
54. Estructura Hoja de Estilos > Widgets > Crea objetos compuestos
FRAMEWORK 1 2 3 4 5 6 7 8
Reset Los problemas de anidación surgen por dos
motivos: propiedades CSS heredables, nombres
Base de clases compartidas (sin namespace).
h
Grid 8.1 Crea reglas específicas para cada caso de
anidación, de forma bidireccional y con el
DEMO
Widgets mismo nivel de especifidad, así no
dependerás del orden en el código fuente.
Helpers En ellas especificaremos los estilos a
neutralizar o sobreescribir del módulo padre.
8.2 Todos los nombres de clases están en el
namespace global de CSS. Sé consistente
THEME con el formato de namespaces que uses, sé
consciente de sus ventajas e inconvenientes.
Widgets
Pages
Demo: “nesting” de widgets en FGR, se añade y resuelve cada una de las anidaciones posibles.
55. Estructura Hoja de Estilos > Pages
FRAMEWORK
Reset La sección Pages es opcional, sus objetos podrían
formar parte de la sección Widgets. Dependerá
Base de la complejidad del proyecto.
Grid Dos funciones:
Widgets 1 Agrupar los objetos de páginas/secciones con
estilos completamente independientes, no
Helpers reusables en otro contexto. Facilitamos su
localización y posible separación a otra hoja.
2 Definir las anidaciones necesarias de objetos
cuyo estilo depende de la página. No deja de
THEME ser un caso de composición.
Widgets
Pages
En este caso de composición el objeto anidado responde modificando su comportamiento en función al contexto (página).
Sí hay una dependencia del contexto en este caso, pero es una dependencia que buscamos, no una imprevista.
En la mayoría de los casos de anidación que hemos visto el objeto anidado no trataba de modificar su comportamiento,
sino restablecer su comportamiento normal neutralizando los efectos del contexto. Pero no siempre será el efecto que
busquemos (ver anidación .buttons .button de FGR).
Por tanto, hay casos de composición que sí implican la extensión/modificación de los objetos anidados, sí deben
responder al contexto.
56. Estructura Hoja de Estilos > Helpers
FRAMEWORK
Reset Los Helpers son pequeñas clases auxiliares
reusables entre proyectos.
Base
Evitan la repitición del código (DRY).
Grid
Ejemplos: .clear, .clearfix, .hidden...
Widgets
Helpers
THEME
Widgets
Pages