Hojas de Estilo en Cascada, CSS1
La estructura de un documento HTML... otra vez
- Hola, hacía ya tiempo que no nos veíamos.
- Pues sí, pensaba que te habías olvidado de mí. Hoy hablamos de hojas de estilo ¿verdad?
- Sí, y en primer lugar vamos a hablar de la estructura de un documento HTML.
- ¿Otra vez?
- Sí, para manejar las hojas de estilo correctamente es indispensable comprender perfectamente cómo está estructurado un documento HTML.
- Muy bien.
- En un tutorial anterior te dije que a menudo se asemeja un documento HTML con un árbol.
- Si me acuerdo del dibujito.
- En realidad, a mí me gusta más imaginarlo como un montón de cajas que se contienen unas a otras. La caja mayor, equivaldría al elemento del documento, el elemento HTML, y a cada elemento le correspondería una caja más pequeña, así:
Aquí se ve claramente como unas cajas están contenidas en otras, es decir, cómo unos elementos están contenidos en otros. Si entiendes este modelo, habremos avanzado gran parte del camino.
- Yo creo que está bastante claro, sí.
- Bien. En jerga se habla de elementos padres, elementos hijos y elementos hermanos. En el modelo, un elemento padre corresponde a una caja que contiene otras cajas, que serían sus elementos hijos, y que serían hermanos entre sí. También se habla de ascendientes y descendientes. Los elementos ascendientes son los padres, los abuelos, etc., y los descendientes son los hijos, los nietos, etc.
- Vamos, que es como un árbol... de familia.
- Exactamente. Esto es importante porque una parte fundamental de las hojas de estilo es la herencia. Como sucede normalmente en la vida real, muchas de las propiedades de los padres son heredadas por sus hijos, pero no al revés.
- ¿Qué tipo de propiedades? ¿Las tierras, la casa?
- Las propiedades de estilo, hombre. Por ejemplo: el tipo de letra. Cuando especificas un tipo de letra para los contenidos de un elemento P
, los elementos EM
contenidos también tendrán en principio ese tipo de letra. Aunque que no todas las propiedades se heredan.
- Creo que más o menos lo entiendo.
- Bien, pues vamos a empezar ya.
Selectores
- Mira, esta es nuestra primera hoja de estilo, ¿te acuerdas?
body {
color : rgb(151,0,0);
background-color : rgb(255,201,0);
font-family : Verdana, Arial, Helvetica, Helv, sans-serif;
}
- ¡Sí, qué tiempos aquellos!
- Esto es una de hoja estilo muy sencilla formada por un solo conjunto de reglas. La parte que va antes de las llaves, se llama selector (en este caso body
), y sirve para seleccionar las partes del documento a las que queremos que se apliquen las reglas de estilo que están entre llaves.
- Ya veo, entonces en este caso las reglas se aplican al elemento BODY
, ¿verdad?
- Sí, eso. Pero CSS nos permite ser un poco más específicos con los selectores.
- ¿Qué quieres decir?
- Por ejemplo, con este conjunto de reglas:
EM { font-family : monospace }
todos los elementos EM
del documento se representarían con una fuente no proporcional, es decir, con todos los caracteres de la misma anchura (siempre que una fuente así estuviera disponible, claro).
- Sí...
- Pero de esta otra forma podemos afinar un poco más:
OL EM { font-family : monospace }
Ahora la regla sólo se aplicará a los elementos EM
que sean descendientes de algún elemento OL
. Los elementos EM
que no estén contenidos en un elemento OL
no se verán afectados por esta regla.
- Anda, pues eso podría ser útil.
- Sí que lo es. A este tipo de selectores se les llama selectores contextuales. Otro ejemplo más:
TD OL EM { font-family : monospace }
se aplicará a los elementos EM
que sean descendientes de algún elemento OL
, que a su vez sean descendientes de algún elemento TD
.
- Ya entiendo.
- Pero podemos ser aún mucho más específicos.
- ¿Cómo?
- Usando los atributos de HTML id
y class
. Con id
y class
podemos darle un poco más de significado a la estructura HTML de nuestro documento.
- No entiendo eso.
- Es sencillo, mira. En HTML, P
es un párrafo, todos los P
son párrafos. Pero para nosotros, desde el punto de vista estilístico, puede haber diferencias entre unos párrafos y otros. Por ejemplo, en un manual de instrucciones, la mayoría de los párrafos se dedicarán a explicar el funcionamiento de un aparato, pero en ocasiones pueden aparecer párrafos con advertencias, que queremos que aparezcan en cursiva. Así:
<h1>Instrucciones de seguridad</h1>
<p>Lea todas las instrucciones y conserve este manual de
instrucciones. Siga las advertencias e instrucciones existentes
sobre el monitor.</p>
<p class="advertencia">Atención: Nunca trate de abrir el
monitor usted mismo. En caso de avería diríjase siempre a
nuestro servicio técnico oficial.</p>
<p>Más instrucciones...</p>
<p class="advertencia">Atención: Otra advertencia...</p>
<p>Más instrucciones...</p>
- ¿Y cuál sería el selector para esos párrafos?
- El selector para todos los párrafos de la clase "advertencia"
sería p.advertencia
, es decir, separando con un punto el tipo de elemento, y la clase de elemento. Por ejempo:
p.advertencia { font-style : italic }
- ¿Es sencillo, no?
- Sí, pero es incluso algo más potente. Mira, imagina que en vez de un párrafo con una advertencia, ponemos una lista de advertencias. Pues sencillamente escribiríamos:
<ul class="advertencia">
<li>Antes de manipular el monitor desenchúfelo de la toma
de corriente.</li>
<li>Más advertencias...</li>
</ul>
Y ahora podríamos tener unas reglas para todos los elementos UL de clase advertencia:
ul.advertencia { font-style : italic }
O directamente, podríamos declarar unas reglas de estilo para cualquier elemento de clase advertencia:
.advertencia { font-style : italic }
- Ya veo, y eso se aplicaría cualquier tipo de elemento, siempre que tuviera class="advertencia"
, ¿no?
- Sí. Así que el atributo class
nos permite clasificar elementos.
- ¿Y el atributo id
?
- El atributo id
nos permite identificar elementos. Como has visto, un atributo class
se puede aplicar a varios elementos. Pero el atributo id
toma un valor único para cada elemento de un documento. Es decir, podemos dar a los elementos que queramos un identificador único que lo diferencie del resto, y eso es muy útil para hacer excepciones.
- ¿Por ejemplo?
- Por ejemplo:
<p class="advertencia" id="advertencia-final">Nota importante:
Si el usuario no sigue las instrucciones de seguridad
proporcionadas, se anulará automáticamente la garantía del
producto.</p>
Este párrafo se verá como el resto de las advertencias, pero además queremos aplicar unos estilos adicionales. Es tan sencillo como esto:
#advertencia-final { color : red }
- Ya veo, o sea que el carácter #
se usa cuando el selector se refiere a un atributo id
, ¿no?
- Exactamente. Otra cosa importante de los selectores es que se pueden agrupar, por ejemplo:
h1, .info h2, h3#notas { font-weight : bold }
indica que queremos que se escriban en negrita: los elementos H1
, los elementos H2
que tengan algún elemento de clase "info"
entre sus ascendientes, y el elemento H3
con identificador "notas"
.
- ¡Increíble, creo que lo entiendo!
- Hay otro tipo de selectores, que se llaman pseudo-clases y pseudo-elementos, pero de esos hablaremos más tarde. Ahora tenemos que hablar un poco de elementos en bloque y elementos en línea.
- Muy bien, vamos a ello.
Elementos en bloque y elementos en línea
- Ya hemos hablado en varias ocasiones de elementos en bloque y elementos en línea.
- Sí, siempre estás hablando de lo mismo...
- La diferencia entre unos y otros es fundamentalmente estilística o de presentación, porque los elementos en bloque normalmente se representan con un salto de línea antes y otro después, mientras que los elementos en línea forman parte de una línea.
- Sí, sí, lo sé.
- Lo que tienen en común entre sí es que son rectángulos, por ejemplo:
Cada rectángulo o cuadro tiene un área de contenido y opcionalmente un borde. Entre el borde y el contenido hay un área de relleno y entre el borde y los límites del cuadro hay un área de margen. El margen es lo que separa unos elementos en bloque de otros:
La anchura del elemento es la anchura del área del contenido, y la anchura del cuadro es la suma de las anchuras de elemento, relleno, borde y margen. Lo mismo con la altura: la altura del cuadro es la suma de las alturas de elemento, relleno, borde y margen. ¿Me sigues?
- Sí, creo que sí.
- La diferencia está en que, en general, para los elementos en bloque puedes especificar la anchura y la altura del elemento, mientras que para los elementos en línea la anchura y la altura del elemento es en general la mínima para que quepa el elemento.
- Aaaah... mmh, no sé si te entiendo...
- Lo vamos a ver con una figura, así estará más claro:
El modelo de cuadros es en realidad más complejo: hay elementos flotantes, elementos objeto de lista, elementos reemplazados... Te aconsejo que te leas el capítulo 4 de CSS1 (en español), y tendrás una visión completa del modelo de formato visual de CSS1.
- Bueno, intentaré sacar un poco de tiempo.
- Y el modelo de cuadros de CSS2 es aún más complejo, pero de eso hablaremos en su momento. Por ahora vamos a hablar un poco más de los elementos en bloque.
- Muy bien, lo que tú digas.
Modelo de cuadros CSS para elementos en bloque
- Dentro de los elementos en bloque se consideran, además de los elementos en bloque en sí, los elementos objetos de lista y los elementos flotantes.
- ¿Qué es un elemento flotante?
- El caso típico de un elemento flotante es una figura metida en un párrafo, a un lado. El texto rodea a la figura, ajustándose automáticamente a la anchura disponible, así:
- Ah, ya entiendo.
- En esta figura se representa un elemento en bloque (el elemento UL) y elementos objeto de lista (los elementos LI):
Como hemos dicho antes, cada elemento en bloque define un cuadro, y los márgenes son los que fijan la distancia que queda entre los cuadros. Pues bien, los márgenes verticales de dos elementos en bloque adyacentes no se suman, sino que se reducen al mayor de los dos.
- No entiendo.
- Mira. El cuadro azul tiene un margen inferior de 4 centímetros. El cuadro rojo tiene un margen superior de 2 centímetros. Si colocamos el cuadro rojo a continuación del cuadro azul, la distancia que los separa es de 4 centímetros, que es el máximo de 4cm y 2cm, y no 6cm, que es lo que podría parecer lógico en un principio:
- Ajá...
- Se supone que así se obtienen resultados más acordes con lo que espera el diseñador.
- Ya.
- La especificación también habla de cómo calcular la anchura de los elementos en bloque, y la de sus márgenes, rellenos y bordes derechos e izquierdos, pero no dice nada de la altura. En principio la altura no es relevante, porque los elementos en bloque se van colocando unos a continuación de otros, y no hay mucho control sobre el formato vertical. Ten en cuenta que no todos los medios que acceden a la Web contemplan el concepto de "página". La especificación CSS2 es mucho más completa en ese sentido, y más compleja, porque hay muchas más posibilidades a la hora de controlar la posición exacta de cada cuadro, y de especificar reglas para medios concretos (pantallas, impresoras, sintetizadores de voz, etc.).
- Sí, pero de eso ya hablaremos en el futuro, ¿verdad?
- Verdad. De los elementos objeto de lista, debes saber que la única particularidad que tienen es que se representan con un marcador. Lo veremos con más detalles cuando hablemos de las propiedades de estilo. Y sobre los elementos flotantes, pues... la verdad es que es un pequeño lío...
- Uf, pues si para ti es un lío, imagina para mí...
- Lo mejor es saber que si un cuadro es flotante, el texto de los demás cuadros lo rodearán, respetando siempre los márgenes del elemento flotante, como se ve en esta figura:
Como ves, los márgenes del elemento flotante se suman a los márgenes del cuadro del párrafo, y no sucede como te he indicado antes para el margen superior.
- Mmm, ya veo...
- Hablemos un poco de los elementos en línea.
- Hablemos, hablemos...
Modelo de cuadros CSS para elementos en línea
- Los elementos en línea son elementos que ocupan una o varias líneas del texto de un elemento en bloque. Por ejemplo, un elemento EM
será un elemento en línea. En una misma línea puede haber varios elementos en línea, cada uno de los cuales define su propio cuadro:
Si un elemento no cabe en una línea, crea un cuadro diferente para cada línea en la que está presente:
En general no podemos especificar la anchura y la altura de un elemento en línea, aunque sí sus márgenes, bordes y rellenos.
- ¿Por qué dices "en general"?
- Porque existe un tipo especial de elementos para los que sí se puede: los elementos reemplazados. Un elemento reemplazado puede ser un elemento en bloque o en línea. Lo que lo define es el hecho de que sus dimensiones en principio son desconocidas.
- Mmmm, ¿por ejemplo?
- Por ejemplo, el elemento IMG
, si recuerdas del tutorial anterior, tiene esta forma:
<img src="imagen.png" alt="Texto alternativo para la imagen">
El navegador sustituirá el elemento por una imagen. La imagen tendrá una anchura y altura intrínsecas, pero en el código HTML esas dimensiones no vienen. Hasta que el elemento no es reemplazado por la imagen correspondiente, las dimensiones no se conocen.
- Aah, ya entiendo. Pero recuerdo que me dijiste que se puede poner la anchura y la altura con los atributos width
y height
del elemento IMG
.
- Sí. Puedes especificar la anchura y la altura con esos parámetros, o puedes hacerlo en una hoja de estilo. Y puedes poner los valores reales del tamaño de la imagen, u otros valores más grandes o más pequeños. Y este es el caso en que para un elemento en línea (un IMG
normalmente es un elemento en línea) se pueden especificar la anchura y la altura.
- Ajá. Sí, creo que te sigo.
- Lo que sí se puede especificar para los elementos en línea es la altura de las líneas. Existe un atributo que permite definir la altura de las líneas, o sea, la distancia que separa cada dos líneas de un párrafo. Lo veremos más a fondo después.
- Muy bien.
- Genial. Un detalle más antes de empezar con el repaso de las propiedades de estilo. El fondo sobre el que todo se representa, el lienzo, corresponde típicamente el elemento BODY
. Esto quiere decir que para especificar por ejemplo el color de fondo, los márgenes, etc. del documento, habrá que aplicar estas propiedades de estilo al elemento BODY
.
- Entiendo.
- En CSS2 la noción del lienzo es conceptualmente más abstracta y suele dar lugar a quebraderos de cabeza. De momento, para nosotros, la anchura del lienzo es para que nos entendamos la anchura de la ventana del navegador, y la altura del lienzo es la mínima necesaria. ¿De acuerdo?
- Está bien...
- Supongo que ahora mismo tendrás un lío morrocotudo con todo lo de elementos en bloque y en línea...
- ¡Lo puedes jurar!
- Bueno, en cuanto tengas un poquito de experiencia te darás cuenta de que en cierto sentido la especificación CSS1 es muy simple. Unas párrafos van a continuación de los otros, y la altura de los párrafos casi siempre viene definida simplemente por sus contenidos y por la altura de sus líneas. Lo único que se escapa a este "flujo normal" son los elementos flotantes, que se pueden llevar a la izquierda o a la derecha, y a los que el resto del texto se adapta ocupando el ancho que dejan libre.
- Ya veo.
- Donde nos permite actuar CSS1 por tanto es: en los estilos de las letras (fuentes, negrita, cursiva, etc.), colores de texto y fondos, estilos de texto (separación entre palabras, alineación, altura de líneas...), propiedades de cuadros (márgenes, rellenos, bordes, tamaño), y estilos para las listas (tipo de marcador, tipo de lista, etc.). Si te parece vamos a ver las propiedades de CSS1 una a una.
- Ok, me parece bien.
Propiedades de fuente
- Empezamos con las propiedades de fuente. Se definen las siguientes propiedades:
font-family
: familia tipográfica (el nombre de la fuente)font-style
: estilo de fuente (normal, itálica, inclinada)font-variant
: variante (normal, versalitas)font-weight
: peso (normal, negrita)font-size
: tamaño de fuentefont
: una propiedad abreviada, que permite resumir todas las anteriores en una sola regla
- Ok.
- font-family
toma como valores nombre de fuentes, en orden de preferencia. Si el nombre de la fuente contiene espacios, se entrecomilla. Al final de la lista conviene siempre poner un nombre de familia genérica que actúa como "red de seguridad", y que se refiere a un tipo general de fuente. Por ejemplo:
font-family : Georgia, "Times New Roman", Times, serif;
font-family : Verdana, Arial, Helvetica, sans-serif;
font-family : "Courier New", courier, monospace;
Las familias genéricas son: \'serif\' (p.ej. Times), \'sans-serif\' (p.ej. Arial), \'cursive\' (p.ej. Zapf-Chancery), \'fantasy\' (p.ej. Western) y \'monospace\' (p.ej. Courier).
- Bueno, vale...
- Seguimos. font-style
permite especificar si queremos que la fuente esté en itálica. Puede tomar los valores normal
, italic
y oblique
. Por ejemplo, ¿qué significa esto?
H1, H2, H3 { font-style: italic }
H1 EM { font-style: normal }
- Mmm, veamos, a ver si lo digo bien: que los contenidos de los elementos H1
, H2
y H3
se representarán en itálica, excepto los contenidos de los elementos EM
que sean descendientes de algún H1
, que se verán normal.
- ¡Muy bien! Muy bien. font-variant
puede tomar los valores normal
y small-caps
(versalitas).
- ¿Qué es eso?
- En una fuente con letras versalitas las letras minúsculas son similares a las mayúsculas, pero más pequeñas.
- Vale. Y con poner font-variant : small-caps
vale, ¿no?
- Sí, si hay alguna fuente disponible en el sistema para ello sí. Si no, es posible que simplemente salgan todas las letras en mayúscula.
- Ok.
- font-weight
puede tomar los valores normal
, bold
(negrita), bolder
(más negrita que el padre), lighter
(menos negrita que el padre), 100
, 200
, 300
, 400
, 500
, 600
, 700
, 800
ó 900
.
- Eso sí que es raro.
- Sí. El valor 400
equivale a peso normal
, y el valor bold
equivale a 700
. Lo habitual es poner simplemente normal
o bold
.
- Me parece bien...
- font-size
permite especificar el tamaño de la fuente. Aquí hay bastantes opciones. Puede tomar los siguientes valores:
- un tamaño absoluto:
xx-small
,x-small
,small
,medium
,large
,x-large
,xx-large
; - un tamaño relativo (al elemento padre):
larger
(más grande),smaller
(más pequeño) - una longitud, por ejemplo,
2cm
(2 centímetros),3em
(3 veces el tamaño normal), etc. - un porcentaje (del tamaño de fuente del elemento padre): por ejemplo,
150%
equivale a1.5em
, o 1,5 veces el tamaño normal.
Cuando hagas una hoja de estilo para pantallas, conviene usar valores que le resulten cómodos al usuario, porque como sabrás leer en la pantalla cansa más que leer de un papel. En general, lo mejor es no especificar ningún tamaño de fuente, y si especificas algo, que sea una medida relativa al tamaño normal: un múltiplo de em
, para que el usuario pueda escalar fácilmente los textos.
- ¿Qué es un em
?
- Es un término tipográfico. Simplificando, es la altura de la fuente.
- Ah.
- En CSS, cuando hablamos de longitudes, hablamos de un número y su unidad. No puedes decir que algo mide 6. ¿6 qué? ¿6 centímetros, 6 metros?
- Hombre, claro.
- Las unidades que se pueden usar son las siguientes: em
(la altura de la fuente), ex
(la altura de la letra x), px
(píxeles de pantalla), in
(pulgadas, una pulgada son 2,54cm), cm
(centímetros), mm
(milímetros), pt
(puntos, 72 puntos son una pulgada), y pc
(picas, 1pc=12pt). Para impresoras y otros medios las unidades absolutas son apropiadas (in
, cm
, mm
, pt
, pc
), pero para pantallas lo mejor es usar em
o medidas porcentuales, ya que no se sabe a cuántos píxeles equivale por ejemplo un centímetro. La unidad px
es un híbrido de medida absoluta y relativa, y de momento es aconsejable no utilizarla.
- Bueno, entonces no me quedan muchas opciones...
- La sintaxis es siempre el número y pegado a él la unidad. Se usa un punto decimal, no una coma decimal. Y cuando el número sea el cero, no hace falta unidad.
- Mmm, bastante lógico, sí.
- Bueno, pues seguimos. Finalmente, la propiedad font
es un compendio de las anteriores. Aquí tienes un ejemplo completo:
font : italic small-caps bold 1.5em/3em Arial, sans-serif
Los tres primeros valores (font-style
, font-variant
y font-weight
) son opcionales y pueden aparecer en cualquier orden. El cuarto (font-size
) es obligatorio. El quinto (line-height
, altura de línea) es opcional y si aparece debe estar precedido de una barra inclinada. Y al final se pone obligatoriamente la familia tipográfica (font-family
). Otro ejemplo más simple:
font : 80% monospace
- Muy bien.
- Vamos al siguiente grupo de propiedades.
Propiedades de color y fondo
- El siguiente grupo son las propiedades de color y fondo, y son las siguientes:
color
: color del textobackground-color
: color del fondobackground-image
: imagen de fondobackground-repeat
: patrón de repetición de la imagen de fondo (si se repite, y cómo se repite)background-attachment
: imagen fija o desplazablebackground-position
: posición de la imagen de fondobackground
: propiedad abreviada para las propiedades de fondo.
La propiedad color
es sencilla. Todas estas reglas significan lo mismo:
color : red;
color : rgb(255,0,0);
color : rgb(100%,0,0);
color : #ff0000;
color : #f00;
- ¿Todo eso significa lo mismo?
- Sí. Como ves hay cinco maneras de especificar un color en CSS:
- Usando uno de los nombres de color predefinidos por CSS1:
aqua
(celeste),black
(negro),blue
(azul),fuchsia
(fucsia),gray
(gris),green
(verde),lime
(verde lima),maroon
(marrón),navy
(azul marino),olive
(verde oliva),purple
(púrpura),red
(rojo),silver
(gris claro),teal
(verde azulado),white
(blanco) yyellow
(amarillo). - Especificando las componentes RGB (rojo, verde y azul) del color, de acuerdo a alguna de las cuatro notaciones siguientes:
#rrggbb
, en hexadecimal, cada componente de00
aFF
. Por ejemplo#4f6ac9 = RGB(4*16+15,6*16+10,12*16+9) = RGB(79,106,201)
#rgb
en hexadecimal. Por ejemplo#369 = #336699 = RGB(51,102,153)
RGB(R,G,B)
en decimal, cada componente de 0 a 255. Por ejemplo,RGB(255,255,255)
=blanco,RGB(0,0,0)
=negro,RGB(0,0,255)
=azulRGB(R%,G%,B%)
en porcentajes. Por ejemplo,RGB(0,100%,0)
=verde
- ¡Uf, es un poco lío!
- Sí, ya le irás pillando el truco. Vamos con las propiedades de fondo. El color de fondo se especifica con background-color
y es igual que antes:
background-color : valor de color
También puede tomar el valor:
background-color : transparent
o sea, ningún valor, que es el valor por defecto. Por ejemplo:
P { background-color : #ff0 }
- Veamos, eso sería #ffff00
, máximo rojo, máximo verde, mínimo azul... mmm, no sé...
- Amarillo puro.
- Ah.
- Venga, esto deberías entenderlo, léete los artículos que te recomendé en el segundo tutorial.
- Bueeeno, vaaale.
- Seguimos. background-image
permite especificar una imagen de fondo. Conviene especificar al mismo tiempo una imagen de fondo y un color de fondo, por si no se puede cargar la imagen:
body { background-image : url(ajedrez.gif) ; background-color : white }
El valor por defecto es none
, ningún fondo:
p { background-image : none }
- Muy bien.
- Con background-repeat
decimos si la imagen de fondo se repite, y cómo lo hace. Los valores que puede tomar son:
repeat
: repetir horizontal y verticalmenterepeat-x
: repetir horizontalmenterepeat-y
: repetir verticalmenteno-repeat
: no repetir
- Está claro...
- Por ejemplo:
body {
background-image : url(ajedrez.gif);
background-color : white;
background-repeat : repeat
}
- Muy bonito.
- background-attachment
dice si la imagen está pegada al fondo, o si se mueve con el resto de los contenidos. En el primer caso el valor es fixed
, en el segundo caso es scroll
:
body {
background-image : url(ajedrez.gif);
background-color : white;
background-repeat : repeat;
background-attachment : fixed;
}
- Ya me lo estoy imaginando...
- Y background-position
dice la posición inicial de la imagen de fondo. Son dos valores, y hay varias maneras de especificarlos, pero es un poco difícil de explicar. Lo mejor es que lo leas en la especificación. Si no lo entiendes no te preocupes, no es normal utilizar esto.
- Muy bien, allí lo leeré.
- Vale. Por último, background
nos permite declarar todas las reglas de una tacada, así:
background : white url(ajedrez.gif) repeat fixed;
Todos los valores son opcionales y van en cualquier orden. Podrías poner:
background : red
- Genial.
- En realidad no es lo mismo background-color : red
que background : red
, pero no nos vamos a enrollar más.
- Vale, vamos al siguiente grupo.
Propiedades de texto
- El siguiente grupo son las propiedades de texto, y son las siguientes:
word-spacing
: espacio entre palabrasletter-spacing
: espacio entre letrastext-decoration
: decoración del textovertical-align
: alineación verticaltext-transform
: transformación del textotext-align
: alineación del textotext-indent
: sangría o indentación de la primera línealine-height
: altura de línea
- Vaya, son unas cuantas...
- word-spacing
puede tomar el valor normal
, o una longitud que se añade al valor normal. Puede ser un valor negativo:
p { word-spacing : 1em }
- Muy bien.
- letter-spacing
es lo mismo, puede tomar el valor normal
, o una longitud que se añade al valor normal, y puede tomar un valor negativo:
h1 { letter-spacing : 1cm }
- Entiendo, muy fácil.
- text-decoration
puede tomar el valor none
(ninguna decoración), o una combinación de los siguientes, underline
(subrayado), overline
(una raya por encima), line-through
(tachado) y blink
(intermitente). Por ejemplo:
.antiguo { text-decoration : line-through }
- Vale, sigue.
- vertical-align
dice cómo será la alineación vertical de un elemento en línea, y puede tomar cualquiera de estos valores (pero sólo uno): baseline
, sub
, super
, top
, text-top
, middle
, bottom
, text-bottom
, o un porcentaje.
- ¡Hala, casi nada!
- Las descripciones las tienes en la especificación, y lo mejor es que lo leas allí.
- Muy bien.
- text-transform
puede tomar uno de estos cuatro valores:
capitalize
: convierte en mayúscula el primer carácter de cada palabrauppercase
: convierte en mayúsculas todas las letras del elementolowercase
: convierte en minúsculas todas las letras del elementonone
: neutraliza el valor heredado
- Mmm, ok.
- text-align
dice cómo alinear horizontalmente el texto contenido en un elemento en bloque, y puede vale left
(justificar a la izquierda), right
(justificar a la derecha), center
(centrar) y justify
(justificar a ambos márgenes). Por ejemplo:
blockquote.introduccion { text-align : center }
Eso haría que los contenidos de los elementos BLOCKQUOTE
de clase introduccion
aparecieran centrados en su cuadro.
- Ya entiendo.
- text-indent
especifica el margen de la primera línea. Puede ser una longitud (por ejemplo, text-indent : 2em
) o un porcentaje de la anchura del elemento padre.
- Mmm, creo que eso podría ser útil.
- Posiblemente. Y por último line-height
establece la altura de línea, o sea, la distancia entre las líneas de base de dos líneas sucesivas. Puede tomar uno de estos cuatro valores: normal
, un número, una longitud o un porcentaje del tamaño de la fuente del elemento.
- ¿Un número, sin unidad? ¿Qué indicaría un número?
- Es un multiplicador del tamaño de la fuente del elemento. Por ejemplo, las tres declaraciones siguientes son equivalentes:
div { line-height: 1.2; font-size: 1em }
div { line-height: 1.2em; font-size: 1em }
div { line-height: 120%; font-size: 1em }
- Sí, creo que lo entiendo.
- ¿Pasamos al siguiente grupo?
- Pasamos
Propiedades de cuadro
- El siguiente grupo son las propiedades de cuadro y son bastantes:
- para establecer los márgenes:
margin-top
,margin-right
,margin-bottom
,margin-left
,margin
- para establecer el relleno:
padding-top
,padding-right
,padding-bottom
,padding-left
,padding
- para establecer los bordes:
border-top-width
,border-right-width
,border-bottom-width
,border-left-width
,border-width
;border-color
;border-style
;border-top
,border-right
,border-bottom
,border-left
;border
- otras:
width
,height
,float
,clear
- ¡Uf, creo que aquí nos van a dar las uvas!
- Tranqui, a ver si lo resumimos bien. Las propiedades de margen (margin-top
, margin-right
, margin-bottom
, margin-left
) pueden tomar como valor una longitud, un porcentaje o el valor auto
(automático). El porcentaje se refiere al margen del ascendiente en bloque más cercano. Se permiten valores negativos. Por ejemplo: margin-left : 2em
- Pues vale...
- En margin
englobas las cuatro propiedades de margen, dando cuatro valores consecutivos, para el margen superior (top), derecho (right), inferior (bottom) e izquierdo (left) respectivamente. Por ejemplo, margin : 1em 2em 1em 3em
. Más información en la especificación.
- Ok, ok.
- Las propiedades de relleno (padding-top
, padding-right
, padding-bottom
, padding-left
) puede tomar como valor una longitud, o un porcentaje, que también se refiere al relleno del ascendiente en bloque más cercano. Aquí no se permiten valores negativos. En padding
englobas los valores para los cuatro rellenos en el mismo orden que antes. ¿Ok?
- Ok.
- Por ejemplo:
p {
background-color : yellow;
padding : 1em;
margin : 1em;
}
Aquí el párrafo y un área de 1em
a cada lado (el área de relleno) tienen fondo amarillo. El margen es de fondo transparente:
- Ajá, ya veo, o sea que el margen es siempre transparente, ¿no?
- Sí. Las propiedades de anchura de borde (border-top-width
, border-right-width
, border-bottom-width
, border-left-width
) pueden tomar uno de los siguientes valores: thin
(delgado), medium
(mediano), thick
(grueso) o una longitud. Con border-width
especificas los cuatro a la vez, en el mismo orden que antes. Por ejemplo:
p {
background-color : yellow;
padding : 1em;
margin : 1em;
border-style : solid;
border-width : thin thick thick thin
}
No te preocupes por lo de border-style
, en seguida lo vemos.
- Muy bien, sigue.
- border-color
es como border-width
, pero en vez de anchuras, ponemos colores. El valor por defecto para el color de los bordes es el mismo que el de la propiedad color
del elemento:
p {
background-color : silver;
padding : 1em;
margin : 1em;
border-width : medium thick thick medium;
border-color : white gray gray white;
border-style : solid;
}
- Qué bonito.
- border-style
dice el estilo de los cuatro bordes, y puede tomar uno de estos valores: none
(ninguno), dotted
(punteado), dashed
(a trazos), solid
(continuo), double
(doble), groove
(canal), ridge
(cresta), inset
(bajorrelieve), o outset
(altorrelieve).
Para los cuatro últimos tienes que dar un valor a la propiedad color
si quieres ver el efecto. Por ejemplo:
p {
background-color : silver;
color : maroon;
padding : 1em;
margin : 1em;
border-style : inset
}
Las propiedades border-top
, border-right
, border-bottom
y border-left
permiten especificar, para cada borde, su anchura, su color y su estilo:
p {
border-top : 3px #000 dashed;
border-bottom : 3px #000 dashed;
border-right : 3px #000 double;
border-left : 3px #000 double;
}
- Muy bien.
- Y la propiedad border
es un resumen de las cuatro anteriores, que permite especificar, para los cuatro bordes, la anchura, el color y el estilo:
p { border : 3px black double }
- Je je, mucho más sencillo.
- Finalmente, width
y height
especifican la altura de un elemento en bloque o un elemento reemplazado, como una imagen. Pueden tomar el valor auto
, una longitud, y width
también puede ser un porcentaje de la anchura del elemento padre. Por ejemplo:
IMG.icono {
width : 100px;
height : 100px;
}
div.nota { width : 50% }
Un par de comentarios respecto a estas propiedades.
- A ver...
- Si recuerdas, te dije que la anchura del cuadro de un elemento en bloque es: la anchura del contenido, más la anchura de relleno, borde y márgenes.
- Sí.
- Por otra parte, la anchura del cuadro de un elemento es igual a la anchura del contenido de su elemento padre, por ejemplo:
- Mmmm, sí.
- Esto quiere decir que los valores que demos a los márgenes, bordes y rellenos derecho e izquierdo, más la anchura del elemento, deben ser igual a la anchura del cuadro del elemento, no pueden ser cualesquiera.
- Claro...
- Por eso CSS1 define unas reglas para que esto siempre se cumpla. Las puedes encontrar en la especificación. Al principio parecen un lío pero en realidad son bastante lógicas.
- Bueno, vale.
- Y con respecto a la altura, en CSS1 es más útil para elementos reemplazados que para elementos en bloque, porque no es necesario que el navegador tenga en cuenta la altura para elementos en bloque.
- Aaaah...
- Lo propiedad float
indica que un elemento flota a la izquierda (float:left
), a la derecha (float:right
) o que no es un objeto flotante (float:none
), por ejemplo:
img.figura {
float : right;
margin-left : 1em;
margin-right : 0;
}
- Entiendo.
- Y por último la propiedad clear
indica si un elemento puede tener objetos flotantes a sus lados. Con clear:left
, el elemento se mueve hacia abajo hasta que quede por debajo de un hipotético objeto que flote a la izquierda. Con clear:right
lo mismo pero a la derecha. Con clear:both
no se permite que haya un objeto flotante a ningún lado, y con clear:none
se permiten objetos flotantes a ambos lados:
h1 { clear : both }
- Ya entiendo.
- Estupendo, pues pasamos al último grupo.
- Genial.
Propiedades de clasificación
- El último grupo son las propiedades de clasificación, que nos permiten especificar cómo se comporta el elemento. Son las siguientes: display
, white-space
, list-style-type
, list-style-image
, list-style-position
y list-style
.
- Muy bien, empieza.
- display
dice si un elemento es en bloque (display:block
), en línea (display:inline
), si es un objeto de lista (display:list-item
) o si no debe ser representado (display:none
).
- No entiendo, ¿esto quiere decir que puedo decir por ejemplo em { display : block }
?
- Sí, lo que eso querría decir es que los elementos EM
, en vez de abrir un cuadro en la misma línea, abrirían un nuevo cuadro en bloque. Pero lo mejor es no hacer estas cosas a menos que sea absolutamente necesario.
- Ok, muy bien.
- white-space
es una propiedad que dice cómo tratar a los espacios contenidos en un elemento en bloque. Con el valor normal
, varios espacios seguidos se convierten en uno solo, que es a lo que estamos acostumbrados. Con el valor pre
obtienes el comportamiento del elemento de HTML PRE
, en el que todos los espacios se conservan. Y con el valor nowrap
sólo se producen saltos de línea donde haya elementos BR
.
- Mmmm, muy bien.
- Bien, y para finalizar, una serie de propiedades que se aplican a elementos con display:list-item
. La propiedad list-style-type
dice el tipo de estilo de numeración de la lista. Puede ser: disc
(un círculo relleno), circle
(un círculo hueco), square
(un cuadrado), decimal
(números), lower-roman
(números romanos en minúscula), upper-roman
(números romanos en mayúscula), lower-alpha
(letras minúsculas), upper-alpha
(letras mayúsculas) o none
(ningún marcador).
- Muy bien.
- A no ser que pongamos una imagen con list-style-image
:
ul { list-style-image: url(imagenes/flecha.gif) }
- Anda, mira qué bien.
- La propiedad list-style-position
indica el tipo de presentación de la lista, según dónde se coloque el marcador, y puede tomar los valores inside
(interior) y outside
(exterior):
Y por último la propiedad list-style
es un resumen de las anteriores, y puedes indicar al mismo tiempo: el tipo de marcador, el estilo de posición y la imagen del marcador. Si la imagen no está disponible, se colocará un marcador del tipo especificado:
ul { list-style : url(imagenes/flecha.gif) circle }
- Estupendo, bien pensado.
- Muy bien, estamos a punto de terminar, pero tenemos que hablar aún de dos cosas importantes: las pseudo-clases y los pseudo-elementos, y en especial del mecanismo de cascada.
- Venga, vamos.
Pseudo-clases y pseudo-elementos
- Como hemos visto, los selectores se refieren a partes estructurales del documento: un tipo de elementos, los elementos que son descendientes de otros, los elementos de una clase, etc. Pero a veces es útil seleccionar elementos no sólo por su papel estructural, sino también por su presentación.
- A ver, explícate un poco.
- Por ejemplo, para seleccionar un elemento A
, nos bastaría con el selector A
, pero ¿qué pasa si quiero dar una apariencia diferente a los vínculos visitados y a los que aún no han sido visitados? Otro ejemplo, ¿cómo selecciono la primera línea de un párrafo, si hasta que no está representado no sé cuál es la primera línea?
- Sí, ya veo a qué te refieres.
- En CSS1 existen tres pseudo-clases para los elementos A
que tengan un atributo href
, que son link
(no visitados), visited
(visitados) y active
(activos, por ejemplo, mientras el usuario está haciendo clic con el ratón sobre el vínculo). La manera de representar estas pseudo-clases es la siguiente:
A:link { color: blue }
A:visited { color: red }
A:active { color: lime }
Es decir, con dos puntos en lugar de uno solo.
- Ah, qué cosas.
- Es importante que A:active
sea la última que declares por cuestiones de herencia, pero de eso hablaremos después.
- Vale.
- Hay otra pseudo-clase definida en CSS2 que a todo el mundo le gusta mucho, la pseudo-clase hover
, que es para cuando el ratón pasa por encima del vínculo, y se debe poner justo antes de A:active
:
A:link { color: blue }
A:visited { color: red }
A:hover { color : yellow }
A:active { color: lime }
- Muy bien.
- Los pseudo-elementos definidos en CSS1 son el correspondiente a la primera línea de un párrafo, y el correspondiente a la primera letra de un párrafo. Para hacer referencia a la primera línea de un párrafo, se hace lo siguiente:
P:first-line { font-weight : bold }
- Ya veo, en este caso la primera línea saldría en negrita, ¿no?
- Sí. Y para acceder a las propiedades de la primera letra, P:first-letter
, por ejemplo:
p { font-size: 1em; line-height: 1.2em; text-align : justify }
p:first-letter { font-size: 200%; float: left; font-weight: bold }
p:first-line { text-transform: uppercase }
- ¡Eh, eso está genial!
- Bien, pues vamos a hablar del mecanismo de cascada y acabar el tutorial.
- Muy bien.
La cascada
- Una de las características fundamentales de las hojas de estilo, es que se pueden combinar.
- ¿Qué quiere decir eso?
- Pues que puedes aplicar a un mismo documento HTML más de una hoja de estilo. Por ejemplo, una empresa puede tener una hoja de estilo común, y cada departamento de la empresa su propia hoja de estilo.
- Sí, podría ser útil.
- A eso hay que añadirle que cada usuario puede definir su propia hoja de estilo y aplicarla también el mismo documento.
- Pues qué lío ¿no? ¿Qué pasa si aplicamos al mismo elemento propiedades diferentes, o incluso opuestas?
- Sí, y no sólo eso, porque como te dije al principio, algunas propiedades se heredan de padres a hijos, lo cual complica aún más las cosas. Por eso CSS1 define unas reglas precisas para determinar cuáles son los valores que se aplican finalmente a las propiedades de estilo de cada elemento. A estas reglas se les llama el mecanismo de cascada.
- Pues a ver, enséñame ese mecanismo.
- Es un poco complicado, y voy a intentar explicártelo a grandes rasgos. Como siempre, la especificación contiene la descripción completa.
- Sí, venga, no seas tan vago y desembucha.
- Las hojas de estilo se dividen en dos grupos: hojas del autor, y hoja del lector. En CSS1, las reglas del autor tienen más peso que las del lector, a menos que el lector declare sus reglas como "importantes", así, por ejemplo:
body { font-size : 2em !important }
- ¿Y el autor no puede declarar sus reglas importantes también?
- Sí, y en ese caso sus reglas prevalecen sobre las del lector. Pero esto es así en CSS1, en CSS2 ha cambiado, y una regla importante del lector siempre tiene preferencia.
- Bueno, a mí me parece más lógico.
- Las hojas del autor se pueden importar básicamente de dos maneras: con varios elementos LINK
desde el documento HTML, y con reglas @import
en la hoja de estilo. Por ejemplo, una hoja de estilo podría ser así:
@import url(empresa.css);
@import url(dep-comercial.css);
h1 { font-style : italic }
Esto quiere decir que primero se cargan las reglas de empresa.css
, a continuación las de dep-comercial.css
y finalmente se añade la regla de esta hoja. ¿Lo ves?
- Sí.
- Pues bien, para cada propiedad de cada elemento, el valor especificado por la última regla es el que tiene preferencia, es como si anulara a los anteriores. Si por ejemplo en dep-comercial.css
se hubiera especificado:
h1 { font-family : monospace; font-color : blue; font-style : normal }
los valores de las propiedades de estilo resultantes para los H1
serían:
h1 { font-family : monospace; font-color : blue; font-style : italic }
- Ya entiendo.
- Estupendo. La regla @import
debe ir obligatoriamente al principio de una hoja de estilo. Las reglas que empiezan con el símbolo @
se llaman reglas tipo arroba (at-rules en inglés), y en CSS2 además de @import
existen algunas más.
- Muy bien.
- Visto eso, veamos cómo se resuelven los conflictos. Para ello, CSS se basa en dos conceptos: el orden en la cascada (como acabamos de ver), y la especificidad. Por ejemplo, imagina que, en el caso anterior añadimos una nueva declaración:
@import url(empresa.css);
@import url(dep-comercial.css);
div.resumen h1 { font-style : normal }
h1 { font-style : italic }
¿Qué valor de font-style
le darías a los H1
que aparecen dentro de un DIV
de clase resumen
?
- Pues, no sé, en principio normal
, pero después aparece la regla font-style:italic
para todos los H1
... no sé.
- Aplicaríamos font-style:normal
, porque los selectores más específicos prevalecen sobre los más generales. Solamente en el caso en que dos selectores sean igual de específicos, se imponen las reglas del último declarado.
- Ya, ¿y cómo se mide la especificidad?, porque eso parece un concepto un poco abstracto...
- El concepto de especificidad está definido en la especificación. Cuentas el número de atributos id
en el selector, por ejemplo "a"; cuentas el número de atributos class
(y pseudo-clases), por ejemplo "b"; y el número de nombres de elementos (y pseudo-elementos), por ejemplo "c". Concatenando los tres números obtienes la especificidad "abc". Estos son algunos ejemplos sacados de la especificación CSS1:
LI {...} /* a=0 b=0 c=1 -> especificidad = 1 */
UL LI {...} /* a=0 b=0 c=2 -> especificidad = 2 */
UL OL LI {...} /* a=0 b=0 c=3 -> especificidad = 3 */
LI.red {...} /* a=0 b=1 c=1 -> especificidad = 11 */
UL OL LI.red {...} /* a=0 b=1 c=3 -> especificidad = 13 */
#x34y {...} /* a=1 b=0 c=0 -> especificidad = 100 */
- Vaya, ya veo que han atado todos los cabos...
- Por cierto, esos asteriscos, antes de que se me olvide, son la forma de poner comentarios en las hojas de estilo. No habíamos hablado de esto y es importante.
- Tsk, tsk...
- Se pueden poner comentarios en un documento HTML de la siguiente manera:
<!-- Esto es un comentario HTML -->
El comentario no aparecerá representado, pero te puede ser útil cuando repases tus documentos días o meses después de haberlos creado. En CSS los comentarios son diferentes:
/* Esto es un comentario CSS */
Sólo es eso, es muy sencillo y son útiles para no volverte más loco de lo necesario.
- Demasiado tarde para eso...
- Bueno, nunca es tarde para volverse más loco. En realidad todo esto de la cascada es más complicado de lo que te he explicado, y además en CSS2 las cosas varían ligeramente. Por no decir que la implementación que hacen los navegadores actuales de CSS no es precisamente perfecta...
- Calla, calla, no me asustes más.
- Bueno, creo que es el momento de ver unos cuantos ejemplos de HTML 4 y CSS1 auténtico y de verdad, ¿te parece?
- ¡Por supuesto!
Ejemplos
Muy bien, veamos algunos ejemplos. Recuerda que CSS1 no nos da muchas opciones, simplemente nos ayuda a adornar el documento. Lo que vamos a ver aquí sería un sueño para los primeros desarrolladores de HTML, pero con el posicionamiento CSS2 del que hablaremos en el futuro se pueden conseguir cosas mucho más avanzadas.
- Hala, hala, no te enrolles tanto y enséñame esos ejemplos.
- Bueno, bueno, pero espera. Es aconsejable que veas estos ejemplos con Netscape 6.1 o superior, Opera 5 o superior o Mozilla, que son los navegadores que mejor implementan CSS1. Explorer 5.0 o superior dan resultados aceptables, aunque tienen muchos errores. Otros navegadores, como Navigator 4 o inferiores o Explorer 4 o inferiores dan resultados bastante malos. Algunos de los ejemplos utilizan algunos trucos para que las páginas sean compatibles con ellos, pero...
- Sí, sí, lo sé, ya hablaremos de esto en el futuro.
- Je, je, sí. Bueno, aquí tienes una lista de ejemplos:
- Esta es una de las primeras páginas que hizo uso real de CSS1: http://www.danielgreene.com/style.html, realizada por Daniel Greene. Actualmente no está en HTML 4, sino XHTML1.0, pero básicamente son lo mismo.
- Aquí tienes una página muy sencilla, pero muy elegante, de la Oxford Computer Gaming Society: http://users.ox.ac.uk/~gaming/.
- Otra página del mismo estilo, también en HTML 4.01 estricto y CSS1, es esta: http://www.geocities.com/marcoschmidt.geo/java.html
- Esto son unas pruebas mías: ejemplo6.html
- Esta página es bastante bonita en mi opinión: http://www.henkhaverhoek.nl/
- Una de las páginas "tradicionales", y que contiene un montón de información relacionada con hojas de estilo (en inglés, sorry), es esta del CSS Pointers Group: http://css.nu/pointers/
- Esto es de Jan Roland Eriksson, que es una de las personas que más sabe de esto: http://member.newsguy.com/~jrexon/
- Otro ejemplo, y una página muy interesante es ésta de Todd Fahrner, otro gran especialista: http://style.cleverchimp.com/.
- Esta página es de Rijk van Geijtenbeek (ni que decir tiene, otro que sabe mucho): http://rijk.op.het.net/info/niwo/
- En http://www.w3.org/StyleSheets/Core/ puedes ver una colección de hojas de estilo básicas del W3C, que se pueden usar libremente y sin necesidad de conocer CSS.
Bueno, pues yo creo que es suficiente. CSS es a la vez sencillo y complejo. Debes recordar siempre que en la Web no controlas, sólo sugieres, y que CSS no sirve para controlar, sólo para sugerir. Crea siempre en primer lugar tu página HTML, con su estructura lógica correcta, y a continuación, encima de eso, crea una hoja de estilo que le dé la apariencia que tú quieras, con las limitaciones, pero también con la flexibilidad, del medio.
- Bueno, pero si quieres que te sea sincero, creo que tengo el síndrome del escritor. Hemos visto todo el HTML y todo el CSS1, pero ahora no es tan fácil sentarse frente a una pantalla en blanco y empezar a escribir...
- Ya lo sé, pero tú empieza por lo fácil y ve experimentando, en un par de meses o tres verás como dominas bastante todo esto. Y cuando quieras preguntar, pregunta. La lista de correo está para eso.
- Vale, vale, ojalá tengas razón.
- Bueno, el próximo tutorial va a tratar sobre cómo subir un sitio a la Web con FTP, hablaremos de caracteres acentuados, y veremos algunos truquitos para ocultar las hojas de estilo a los navegadores antiguos que no las entienden bien.
- Estupendo, nos vemos entonces, ¡y no tardes tanto como esta vez!
- ¡Hago lo que puedo! Hasta pronto.
- Adiós, adiós.