CSS1
CSS1
1 Presentación
En este documento se profundizará acerca del Lenguaje de Hojas de Estilo en Cascada (CSS).
CSS son las abreviaturas en inglés para Cascading Style Sheets (Hojas de Estilo en Cas-
cada, en español). Esencialmente, es un lenguaje que rige el diseño y presentación de los
sitios y páginas web, en otras palabras, cómo se ven cuando un usuario las visita. CSS es un
mecanismo complementario del lenguaje HTML que permite indicarle al navegador el estilo
que debe darle a los distintos elementos al desplegar la información de un sitio web.
2 A tener en cuenta
• En este curso se utilizará el editor de texto ”Visual Code Studio”. El mismo ya posee
una extensión muy útil llamada Emmet que permite escribir código HTML y CSS de
una forma más rápida. En el caso de utilizar otro editor de texto, esta extensión deberá
instalarse.
• Una buena fuente de información acerca de HTML, CSS e incluso JavaScript es MDN
(Mozilla Developer Network). Además, para conocer las propiedades que se le pueden
dar a los elementos HTML, se usa la página cssreference.
• La página de CanIuse es muy útil para decidir si utilizar o no una etiqueta o un atrib-
uto, en función de los navegadores para los que tenga que estar disponible la página
web.
Algunos de los navegadores o browsers para los que ofrece información son: Internet
Explorer IE, Edge, Firefox, Chrome, Opera, iOS Safari, Android Browser, Samsung
Internet, Chrome for Android, etc..
• Una buena guı́a para aprender buenas prácticas de HTML y CSS es CodeGuide.
1
3 Presentación
Una regla CSS consta de dos partes:
1) Selector
2) Bloque de declaraciones {
atributo: valor;
atributo-de-mas-de-dos-palabras: valor;
}
Ejemplo:
h1 {
color: red;
background-color: green;
}
4 Tipos de selectores
• Selectores básicos
Dar estilos usando ids se considera una mala práctica pues un id es único y darle a
otros elementos el mismo id carece de sentido. Por lo tanto, no vamos a poder reutilizar
lo que hayamos puesto en el bloque de declaraciones en otro elemento html.
Dar estilos con clases nos permite reutilizar nuestro código CSS.
2
Código HTML:
Código CSS:
• Selectores de hijos
El selector ”mayor qué” (sı́mbolo >) es utilizado en CSS para seleccionar to-
dos los elementos que sean directamente descendientes de otro, es decir, que sean
hijos directos de un determinado elemento padre.
3
4
– Selector de hijos descendientes:
• Selectores de hermanos
Hay que tener en cuenta que los dos tipos de selectores de hermanos que hay, apli-
can los estilos a los elementos que son hermanos y que estén por debajo del elemento
de referencia.
5
• Selectores de atributos
Los selectores de atributos permiten elegir elementos HTML en función de sus atribu-
tos y/o valores de esos atributos.
Ejemplo:
Cód. HTML:
6
Cód. CSS:
Resultado:
• Selector universal
7
5 Agrupación de selectores
Los selectores se pueden agrupar para simplificar las hojas de estilo cuando varios elementos
comparten una serie de declaraciones iguales. Ası́, en vez de crear varias reglas iguales en las
que sólo cambia el selector, se crea una única regla con todos los selectores necesarios para
apuntar a los distintos elementos.
Código HTML:
Código CSS:
6 Pseudoclases
Una pseudoclase CSS es una palabra clave que se le añade a los selectores y que dan es-
tilos dependiendo del contexto, posición o estado del elemento. Para ver cada una de las
pseudoclases ir a MDN-Pseudoclases.
8
• Pseudoclases de estado e interactivos
Código HTML:
Código CSS:
9
Y, otro dato a tener en cuenta es que la pseudo-clase :hover es problemática en las pan-
tallas táctiles. Dependiendo del navegador, la pseudo-clase :hover podrı́a no coincidir,
coincidir solo por un momento después de tocar un elemento, o continuar coincidiendo
incluso después de que el usuario haya dejado de tocar y hasta que el usuario toque
otro elemento.
• Pseudoclases de posición
Código HTML:
Código CSS:
10
• Pseudoclases de posición y al tipo de etiqueta
Código HTML:
Código CSS:
7 Pseudoelementos
Dan estilos a partes especı́ficas de un elemento. Para diferenciarlos de las pseudoclases,
utilizaremos: ”::”. Para ver cada una de los pseudoelementos ir a MDN-Pseudoelementos.
Código HTML:
11
Código CSS:
Código HTML:
Código CSS:
• Pseudoelemento ::selection
12
Código HTML:
Código CSS:
8 Algoritmo CSS
El algoritmo CSS es la forma en que el navegador aplica los estilos al documento HTML. Para
entender cómo lo hace, tendremos que comprender algunos de los conceptos fundamentales
de CSS (cascada, especificidad y herencia) que controlan cómo se aplica el CSS al HTML y
cómo se resuelven los conflictos.
• LA CASCADA
El navegador, para saber que bloque de estilos tiene prioridad sobre los demás, analiza
(por orden) tres conceptos clave del código CSS: su importancia, su especificidad y su
orden. Veamos en que se basa cada uno de ellos.
– Importancia
13
– Orden
En CSS, es posible crear múltiples reglas CSS para definir un mismo concepto.
En este caso, la que prevalece ante todas las demás depende de ciertos factores,
como es la altura a la que está colocada la regla.
• ESPECIFICIDAD
14
1. Especificidad de las etiquetas Aclaración: los pseudo-elementos también se
15
3. Especificidad de los identificadores
16
La cláusula !important:
• HERENCIA La herencia está relacionada con cómo los elementos del etiquetado de
HTML heredan propiedades de sus elementos padres (los que los contienen) y los trans-
miten a sus hijos. Un ejemplo caracterı́stico de una propiedad heredada es la propiedad
color.
No todas las propiedades CSS son heredadas, porque algunas de ellas no tendrı́a sen-
tido que lo fueran. Por ejemplo, los márgenes no se heredan porque es poco probable
que un elemento hijo necesite los mismos márgenes que su padre. Normalmente, el
sentido común dicta qué propiedades se heredan y cuáles no, pero para estar del todo
seguros, debemos consultar cada propiedad en la tabla de resumen de propiedades de
la especificación CSS.
¿Por qué tiene CSS un mecanismo de herencia? Probablemente, la manera más sen-
cilla de responder a esta pregunta sea pensar qué pasarı́a si no existiera la herencia.
Se deberı́an especificar cuestiones como la familia de fuentes, el tamaño de la fuente y
el color del texto individualmente para todos y cada uno de los tipos de elemento.
La palabra clave inherit hace que el valor de una propiedad en un elemento sea el
mismo que el valor de su elemento padre. En otras palabras, inherit obliga a que la
herencia se produzca incluso en situaciones en las que normalmente no funcionarı́a.
Por otro lado, ponerle el valor initial a una propiedad, lo que hace es regresar al valor
que el navegador le da por defecto a dicha propiedad.
17
Código HTML:
Código CSS:
9 Modelo de caja
CSS ve a los elementos HTML como si fueran cajas con las siguientes propiedades:
2. El relleno (padding): son las distancias internas (la distancia del borde al contenido).
4. El margen (margin): son las distancias extrnas (la distancia entre el elemento html y
sus elementos hermanos o padres).
Dentro del modelo de caja hay que considerar que una caja tendrá 4 lados:
1. Arriba (top).
2. Derecha (right).
3. Abajo (bottom).
4. Izquierda (left).
18
9.1 Ancho y alto
9.2 Border
19
9.3 Margin y padding
Usaremos dos div para mostrar las propiedades de los margin y padding puesto que dicha
etiqueta los navegadores no le aplican ningún espaciado por defecto, lo cual servirá para ver
el efecto de padding y margin.
20
Existe un valor especial para la propiedad margin: el valor ”auto”:
Para solucionar este problema, lo que se hace es usar un solo margin vertical, es decir,
que todos los elementos tengan margin-top o todos margin-bottom, pero no ambos.
11 Propiedad display
Display es la propiedad más importante para controlar estructuras. Cada elemento tiene un
valor de display por defecto dependiendo de qué tipo de elemento sea. El valor por defecto
para la mayorı́a de los elementos es usualmente block (de bloque) o inline (en lı́nea).
El valor más sencillo de display es none que hace que el elemento no genere ninguna caja. El
resultado es que el elemento desaparece por completo de la página y no ocupa sitio, por lo
21
que los elementos adyacentes ocupan su lugar. Si se utiliza la propiedad display: none sobre
un elemento, todos sus descendientes también desaparecen por completo de la página.
Si se quiere hacer un elemento invisible, es decir, que no se vea pero que siga ocupando
el mismo sitio, se debe utilizar la propiedad visibility. La propiedad display: none se utiliza
habitualmente en aplicaciones web dinámicas creadas con JavaScript y que muestran/ocultan
contenidos cuando el usuario realiza alguna acción como pulsar un botón o un enlace.
Los otros dos valores más utilizados son block e inline que hacen que la caja de un ele-
mento sea de bloque o en lı́nea respectivamente.
Uno de los valores más curiosos de display es inline-block, que crea cajas que son de bloque
y en lı́nea de forma simultánea. Una caja de tipo inline-block se comporta como si fuera
de bloque, pero respecto a los elementos que la rodean es una caja en lı́nea. Una caja con
display inline-block puede modificar sus dimensiones (ancho y alto).
Para empezar a utilizar flexbox lo primero que debemos hacer es conocer algunos de los
elementos básicos de este nuevo esquema, que son los siguientes:
• Contenedor: Es el elemento padre que tendrá en su interior cada uno de los ı́tems
flexibles. En Flex establecemos las propiedades al elemento padre.
• Eje principal: Los contenedores flexibles tendrán una orientación principal especı́fica.
Por defecto, es en horizontal (en fila).
• Eje secundario: De la misma forma, los contenedores flexibles tendrán una ori-
entación secundaria, perpendicular a la principal. Si la principal es en horizontal, la
secundaria será en vertical, y viceversa.
22
• Ítem: Cada uno de los hijos flexibles que tendrá el contenedor en su interior.
23
Existen dos propiedades principales para manipular la dirección y comportamiento de los
ı́tems a lo largo del eje principal del contenedor. Son las siguientes:
24
Mediante la propiedad flex-direction podemos modificar la dirección del eje principal
del contenedor para que se oriente en horizontal (por defecto) o en vertical. Además, también
podemos incluir el sufijo -reverse para indicar que coloque los ı́tems en orden inverso.
Por otro lado, existe otra propiedad llamada flex-wrap con la que podemos especificar el
comportamiento del contenedor respecto a evitar que se desborde (nowrap, valor por de-
fecto) o permitir que lo haga, en cuyo caso, estarı́amos hablando de un contenedor flexbox
multilinea.
En el caso en que hayamos puesto un width o height a los items, si usamos el valor nowrap
y la suma de las dimensiones de los items es superior a la del contenedor, entonces el width
o height puesto para los items se ignora.
Existe una propiedad de atajo (short-hand) llamada flex-flow, con la que podemos resumir los
valores de las propiedades flex-direction y flex-wrap, especificándolas en una sola propiedad
y ahorrándonos utilizar las propiedades concretas.
25
Ahora que tenemos un control básico del contenedor de estos ı́tems flexibles, necesitamos
conocer las propiedades existentes dentro de flexbox para disponer los ı́tems dependiendo de
nuestro objetivo. Vamos a echar un vistazo a 4 propiedades interesantes para ello, la primera
de ellas actua en el eje principal, mientras que el resto en el eje secundario:
De esta pequeña lista, hay que centrarse en primer lugar en la primera y la tercera propiedad,
que son las más importantes (las otras dos son casos particulares que explicaremos más ade-
lante):
26
La primera propiedad, justify-content, sirve para colocar los ı́tems de un contenedor me-
diante una disposición concreta a lo largo del eje principal:
27
SOBRE EL EJE SECUNDARIO
Una vez entendido este caso, debemos atender a la propiedad align-content, que es un
caso particular del anterior. Nos servirá cuando estemos tratando con un contenedor flex
multilinea, que es un contenedor en el que los ı́tems no caben en el ancho disponible, y por
lo tanto, el eje principal se divide en múltiples lı́neas (por ejemplo, usando flex-wrap: wrap).
De esta forma, align-content servirá para alinear cada una de las lı́neas del contenedor
multilinea. Los valores que puede tomar son los siguientes:
28
Con estos valores, vemos como cambiamos la disposición en vertical de los ı́tems que
están dentro de un contenedor multilinea.
29
La otra propiedad importante de este apartado es align-items, que se encarga de alinear
los ı́tems en el eje secundario del contenedor. Hay que tener cuidado de no confundir align-
content con align-items, puesto que el primero actúa sobre cada una de las lı́neas de un
contenedor multilinea (no tiene efecto sobre contenedores de una sola lı́nea), mientras que
align-items lo hace sobre la lı́nea actual. Los valores que puede tomar son los siguientes:
30
Por otro lado, la propiedad align-self actúa exactamente igual que align-items, sin em-
bargo es la primera propiedad de flexbox que vemos que se utiliza sobre un ı́tem hijo especı́fico
y no sobre el elemento contenedor. Salvo por este detalle, funciona exactamente igual que
align-items.
31
Si se especifica el valor auto a la propiedad align-self, el navegador le asigna el valor de
la propiedad align-items del contenedor padre, y en caso de no existir, el valor por defecto:
stretch.
PROPIEDADES DE HIJOS
A excepción de la propiedad align-self, todas las propiedades que hemos visto hasta ahora
se aplican sobre el elemento contenedor. Las siguientes propiedades, sin embargo, se aplican
sobre los ı́tems hijos:
• Propiedad flex-grow
La propiedad flex-grow, como su nombre lo indica, controla que tanto crecerá el flex-
item para rellenar el espacio disponible. Su valor solo puede ser un número entero (no
negativo).
32
En este caso el espacio disponible es de 100px (tamaño del contenedor menos la suma
del tamaño de los items) y este debe distribuirse entre los items de la siguiente forma:
100px/(1+2+1+1) = 20px -> Este es el valor de la unidad.
Luego esta unidad de crecimiento se multiplicará por el valor de flex-grow para de-
terminar cuanto crecerá cada item.
item1− > 20px * 1 = 20px, item2− > 20px * 2 = 40px, item3− > 20px * 1 =
20px e item4− > 20px * 1 = 20px.
Finalmente, el main size de cada item al dibujarse por el navegador será: item1 − >
120px, item2 − > 140px, item3 − > 120px e item4 − > 120px.
Hay que tener en cuenta que si los items tuvieran márgenes, el espacio disponible
serı́a menor (habrı́a que restarle el tamaño total de los márgenes). Por ejemplo, si
para el caso anterior todos los items tuvieran margin: 5px, el espacio disponible serı́a:
500px - (100px+100px+100px+100px) - (5px+5px+5px+5px+5px+5px+5px+5px) =
60px.
• Propiedad flex-shrink
Con la propiedad flex-shrink se controla cómo se encogerán los elementos. Los flex
items se encogerán para llenar el contenedor de acuerdo a su número flex-shrink,
cuando el tamaño por defecto de los flex items sea mayor al de su contenedor flex container.
Para calcular el tamaño final de un item que se ha encogido, se usan los mismos
principios que con flex-grow solo que en el sentido opuesto. Veamoslo con un ejemplo:
En este caso, el espacio disponible es negativo (–100px) ya que todos los items sumados
dan 600px y el contenedor tiene solo 500px.
33
Luego, los tamaños finales serán:
• Propiedad flex-basis
El tamaño definido por flex-basis es, como su nombre lo dice, el tamaño base. Es decir,
que podrá variar (crecer o encogerse), según los valores de flex-grow y flex-shrink que
veremos más adelante.
• Propiedad order
Dicha propiedad modifica y establece el orden de los ı́tems según una secuencia numérica.
Por defecto, todos los ı́tems flex tienen un order: 0 implı́cito, aunque no se especi-
fique. Si indicamos un order con un valor numérico, irá recolocando los ı́tems según su
número, colocando antes los ı́tems con número más pequeño (incluso valores negativos)
y después los ı́tems con números más altos.
34
11.2 Display: grid;
Sistema bidimensional que nos sirve para estructurar una página web.
• ı́tem: Cada uno de los hijos que contiene la cuadrı́cula (elemento contenedor).
Para activar la cuadrı́cula grid hay que utilizar sobre el elemento contenedor la propiedad
display y especificar el valor grid o inline-grid.
35
Este valor influye en como se comportará la cuadrı́cula con el contenido exterior. El primero
de ellos permite que la cuadrı́cula aparezca encima/debajo del contenido exterior (en bloque)
y el segundo de ellos permite que la cuadrı́cula aparezca a la izquierda/derecha (en lı́nea)
del contenido exterior (ojo, la cuadrı́cula entera, no cada uno de sus ı́tems):
Una vez elegido uno de estos dos valores, y establecida la propiedad display al elemento
contenedor, hay varias formas de configurar nuestra cuadrı́cula grid. Comencemos con las
propiedades que se aplican al elemento contenedor (padre).
Es posible crear cuadrı́culas con un tamaño explı́cito. Para ello, sólo tenemos que usar
las propiedades CSS grid-template-columns y grid-template-rows, que sirven para indicar las
dimensiones de cada celda de la cuadrı́cula, diferenciando entre columnas y filas.
36
Asumamos el siguiente código CSS:
Esto significa que tendremos una cuadricula con 2 columnas (la primera con 50px de ancho
y la segunda con 300px de ancho) y con 2 filas (la primera con 200px de alto y la segunda
con 75px de alto).
Este nuevo ejemplo, se crea una cuadrı́cula de 2x2, donde el tamaño de ancho de la cuadrı́cula
se divide en dos columnas (mismo tamaño de ancho para cada una), y el tamaño de alto de
la cuadrı́cula se divide en dos filas, donde la primera ocupará el doble (2 fr) que la segunda
(1 fr).
37
FILAS Y COLUMNAS REPETITIVAS
En caso de tener más ı́tems de lo que se indica en la propiedad, los ı́tems restantes se
incluirı́an sin formato. De tener menos, simplemente se ocuparı́an los ı́tems implicados.
38
Ejemplo:
Mediante los grids CSS es posible indicar el nombre y posición concreta de cada área de
una cuadrı́cula. Para ello utilizaremos la propiedad grid-template-areas, donde debemos es-
pecificar el orden de las áreas en la cuadrı́cula. Posteriormente, en cada ı́tem hijo, utilizamos
la propiedad grid-area para indicar el nombre del área del que se trata:
39
Aplicando este código, conseguirı́amos una cuadrı́cula donde:
40
HUECOS EN GRID
Por defecto, la cuadrı́cula tiene todas sus celdas pegadas a sus celdas contiguas. Aunque serı́a
posible darle un margin a las celdas dentro del contenedor, existe una forma más apropiada,
que evita los problemas clásicos de los modelos de caja: los huecos (gutters).
Para especificar los huecos (espacio entre celdas) podemos utilizar las propiedades column-
gap y/o row-gap. En ellas indicaremos el tamaño de dichos huecos:
Ejemplo:
41
ATAJO: GRID CON HUECOS
Existe una propiedad de atajo para las propiedades column-gap y row-gap, permitiéndonos
la posibilidad de no tener que indicarlas por separado.
POSICIÓN EN EL GRID
Existen una serie de propiedades que se pueden utilizar para colocar los ı́tems dentro de
la cuadrı́cula. Con ellas podemos distribuir los elementos de una forma muy sencilla y
cómoda. Dichas propiedades son justify-items y align-items (ya vista en el módulo CSS
flexbox).
Estas propiedades se aplican sobre el elemento contenedor padre, pero afectan a los ı́tems
hijos, por lo que actuan sobre la distribución de cada uno de los hijos. En el caso de que
queramos que uno de los ı́tems hijos tengan una distribución diferente al resto, aplicamos
la propiedad justify-self o align-self sobre el ı́tem hijo en cuestión, sobreescribiendo su dis-
tribución.
Estas propiedades funcionan exactamente igual que sus análogas justify-items o align-items,
sólo que en lugar de indicarse en el elemento padre contenedor, se hace sobre un elemento hijo.
Para más información del valor grid, ver los siguientes videos: Grid CSS.
42
o relleno (padding), este es entonces añadido al ancho y alto a alcanzar el tamaño de la
caja que es desplegada en pantalla. Esto significa que cuando se definen el ancho y alto, se
tiene que ajustar el valor definido para permitir cualquier borde o relleno que se pueda añadir.
• border-box le dice al navegador tomar en cuenta para cualquier valor que se especi-
fique de borde o de relleno para el ancho o alto de un elemento. Es decir, si se define
un elemento con un ancho de 100 pixeles. Esos 100 pixeles incluı́ran cualquier borde
o relleno que se añadan, y la caja de contenido se encogerá para absorber ese ancho
extra. Esto tı́picamente hace mucho más fácil dimensionar elementos.
Para resetear todas las cajas de un documento HTML y ası́ poner el valor border-box hay
que escribir arriba del documento CSS:
13 Centrado de cajas
Ver Cları́n.
Nuestro objetivo es centrar nuestra página web con respecto a la ventana del navegador.
43
14 Posicionamiento CSS
A grandes rasgos, y como aprendimos en temas anteriores, si tenemos varios elementos en
lı́nea (uno detrás de otro) aparecerán colocados de izquierda hacia derecha, mientras que
si son elementos en bloque se verán colocados desde arriba hacia abajo. Estos elementos
se pueden ir combinando y anidando (incluyendo unos dentro de otros), construyendo ası́
esquemas más complejos.
Hasta ahora, hemos estado trabajando sin saberlo en lo que se denomina posicionamiento
estático (static), donde todos los elementos aparecen con un orden natural según donde
estén colocados en el HTML. Este es el modo por defecto en que un navegador renderiza
una página.
Sin embargo, existen otros modos alternativos de posicionamiento, que podemos cambiar
mediante la propiedad position, que nos pueden interesar para modificar la posición en
donde aparecen los diferentes elementos y su contenido.
44
Si utilizamos un modo de posicionamiento diferente al estático (absolute, fixed, sticky o rel-
ative), podemos utilizar una serie de propiedades para modificar la posición de un elemento.
Estas propiedades son las siguientes:
Antes de pasar a explicar los tipos de posicionamiento, debemos tener claras las propiedades
top, bottom, left y right, que sirven para mover un elemento desde la orientación que su
propio nombre indica hasta su extremo contrario. Esto es, si utilizamos left e indicamos
20px, estaremos indicando mover desde la izquierda 20 pı́xeles hacia la derecha.
Las propiedades top y left van a tener preferencia por sobre bottom y right respectivamente.
45
14.2 Posicionamiento absoluto
Los elementos con este tipo de posicionamiento pierden sus dimensiones y su posición origi-
nal en el flujo del documento.
Este tipo de posicionamiento coloca los elementos utilizando como punto de origen el primer
ancestro con posicionamiento relativo. En caso de no encontrar dicho ancestro relativo, se
mueve respecto de la etiqueta <html>.
Notar que en el ejemplo de las imágenes de arriba el elemento ”Caja Absoluta” no posee un
ancestro con position: relative; y, por lo tanto, toma como punto de referencia para moverse
la etiqueta <html>.
46
mismo sitio posicionado.
Para que este comportamiento explicado arriba funcione, el elemento sticky debe ser: 1)
hijo directo del body o 2) su elemento contenedor debe tener dimensiones definidas y solo
será sticky dentro de las dimensiones de su contenedor padre.
Este comportamiento dado por este tipo de posicionamiento es muy habitual con los menús
superiores de las páginas o las cabeceras de secciones. Sin embargo, para que funcione para
tal fin hay que poner, por ejemplo, la etiqueta header como la primera etiqueta hija del body
con un top: 0; puesto que de esta forma se queda guardado el espacio que ocupa el header
(por la parte de position relative que posee el sticky) y no ”pisa” a ningún otro elemento del
documento.
47
Se recomienda probar el resultado!
14.5 Profundidad
Es interesante conocer también la existencia de la propiedad z-index, que establece el nivel
de profundidad en el que está un elemento sobre los demás. De esta forma, podemos hacer
que un elemento se coloque encima o debajo de otro.
Su funcionamiento es muy sencillo, sólo hay que indicar un número que representará el
nivel de profundidad del elemento. Los elementos un número más alto estarán por encima
de otros con un número más bajo, que permanecerán ocultos detrás de los primeros.
El valor por default de dicha propiedad es auto y acepta números positivos, negativos y
el cero.
48
Aclaraciones:
• Los niveles z-index, ası́ como las propiedades top, left, bottom y right no funcionan
con elementos que estén utilizando posicionamiento estático. Deben tener un tipo de
posicionamiento diferente a estático.
• Un elemento padre nunca podrá estar por encima de sus elementos hijos.
• Si tenemos elementos con un position diferente a static y z-index: auto (con el valor
por default), el que aparece primero o más hacia al frente es aquel que figura más a lo
último del documento HTML.
49