====== 5. CSS Avanzado ====== En este tema vamos a explicar principalmente el layout en CSS con //flexbox// y //grid//. ===== Flexbox ===== Flex se utiliza para colocar cosas de forma horizontal o vertical. * [[https://css-tricks.com/snippets/css/a-guide-to-flexbox/|A Complete Guide to Flexbox]] * {{css_flexbox_layout_cheatsheet.pdf|Flexbox Layout Cheatsheet. Otra gía rápida de flexbox}} * [[https://medium.com/@js_tut/the-complete-css-flex-box-tutorial-d17971950bdc|The Complete CSS Flex Box Tutorial]] * [[https://medium.com/@js_tut/flexbox-the-animated-tutorial-8075cbe4c1b2|Flexbox — The Animated Tutorial]] * [[https://stackoverflow.com/questions/32551291/in-css-flexbox-why-are-there-no-justify-items-and-justify-self-properties|In CSS Flexbox, why are there no “justify-items” and “justify-self” properties?]] * [[https://flexboxfroggy.com/#es|Flexbox Froggy - A game for learning CSS flexbox]] Vamos a explicar flex con el siguiente ejemplo:
Item1
Item2
Item3
Item4
Item5
.l-flex { display:flex; } .l-flex--direction-row { flex-direction:row } .l-flex--justify-content-center { justify-content:center } .l-flex__area--grow-2 { flex-grow:2 } Como vemos hay dos tipos de elementos, el contenedor y los items que hay centro. El contenedor siempre tendrá la siguiente línea ''display:flex;''. * Veamos otro ejemplo:
Item2
Item3
Item4
Item5
Ahora veremos algunas de las opciones que permite flex. ==== flex-direction ==== Para hacer que los item se muestren de forma vertical u horizontal. Sus valores son * ''flex-direction:row'' Los items se colocan en horizontal. Es decir en una única línea. {{:clase:daw:diw:1eval:flex-row.png|}} * ''flex-direction:column'' Los items que solocal en vertical. Es decir en una única línea. {{:clase:daw:diw:1eval:flex-colum.png|}} ==== flex-wrap ==== Para hacer que si no caben en una línea, se pasen a la línea siguiente. * ''flex-wrap:wrap'' Si se añade se pasa de línea en vez de mantenerse en la misma {{:clase:daw:diw:1eval:flex-wrap.png|}} ==== justify-content ==== Es como se distribuye el espacio sobrante en horizontal. Hacía la izquierda, derecha, ocupando todo el espacio, etc, etc. Alguno de sus posibles valores son: * ''justify-content:flex-start'' * ''justify-content:flex-end'' * ''justify-content:center'' * ''justify-content:space-between'' * ''justify-content:space-around'' * ''justify-content:space-evenly'' {{:clase:daw:diw:1eval:flex-justify-content.png|}} ==== align-content ==== Es como se distribuye el espacio sobrante en vertical. Hacía arriba, abajo, ocupando todo el espacio, etc, etc. Alguno de sus posibles valores son: * ''align-content:flex-start'' * ''align-content:flex-end'' * ''align-content:center'' * ''align-content:strech'' * ''align-content:space-between'' * ''align-content:space-around'' {{:clase:daw:diw:1eval:flex-align-content.png|}} ==== align-items ==== Si los elementos se justifican hacía arriba, abajo, ocupando todo el espacio, etc, etc. Alguno de sus posibles valores son: * ''align-items:flex-start'' * ''align-items:flex-end'' * ''align-items:center'' * ''align-items:stretch'' * ''align-items:baseline'' {{:clase:daw:diw:1eval:flex-align-items.png|}} ==== flex-grow ==== Permite que crezca el item si hay mas espacio. Por defecto el valor es ''0'' que significa que no crece, sino que se queda con el espacio que necesita para su contenido. * ''flex-grow:1'': Todos los items con este valor crecerán para ocupar más espacio pero todos los que tengan este valor tendrán el mismo tamaño entre ellos * ''flex-grow:2'': Como al anterior pero todos los que tengan este valor tendrán el mismo tamaño entre ellos pero el **doble** que los de ''flex-grow:1'' * ''flex-grow:3'': Como al anterior pero todos los que tengan este valor tendrán el mismo tamaño entre ellos pero el **triple** que los de ''flex-grow:2'' {{:clase:daw:diw:1eval:flex-grow.png|}} Se usa entro de los "hijos" En el siguiente ejemplo, ''AAAAA'' tendrá el espacio mínimo para que quepa el texto mientras que ''BBBBB'' y ''CCCCC'' se expandirán hasta ocupar todo el espacio disponible pero ''CCCCC'' ocupará el doble que ''BBBBB''
AAAAA
BBBBB
CCCCC
Si definimos ''flex-grow'', el item crecerá hasta tener un tamaño mayor o justo el den contenido, así que no tiene sentido usar ''flex-shrink:1'' ya que ya se podría hacer más pequeño ni usar ''flex-basis'' ya que no tendrá un tamaño fijo. ==== flex-shrink ==== Indica que un item puede reducir su tamaño en comparación con otros items cuando el contenedor es más pequeño que el tamaño total de los elementos. * ''flex-shrink:1'': Los items con este valor pueden reducir su tamaño para ajustarse al contenedor. * ''flex-shrink:0'': Los items con este valor no se reducirá, independientemente del tamaño del contenedor. Ejemplo: Si tienes tres elementos en un contenedor y uno tiene flex-shrink: 0, este no se reducirá, mientras que los otros dos se reducirán según sea necesario para encajar en el contenedor. Se usa entro de los "hijos" Solo tiene sentido usar ''flex-shrink:1'' si se indica ''flex-basis'' y si valor no es ''auto''. Ya que si ''flex-basis:auto'' el item ya tendré el tamaño mínimo del contenido así que no se podrá hacer más pequeño y por lo tanto no se necesita ''flex-shrink:1'' ==== flex-basis ==== Define el tamaño inicial de un item antes de que se aplique el crecimiento o la reducción. Es el tamaño en el que se basa el elemento antes de que el espacio adicional sea distribuido (con ''flex-grow'') o el espacio sea reducido (con ''flex-shrink''). El tamaño inicial se puede establecer en ''px'', ''%'', ''em'', etc. Por defecto el tamaño inicial es ''auto'' y significa que el tamaño es el del contenido. Se usa entro de los "hijos" Veamos ahora un ejemplo completo de las 3 propiedades: Ejemplo de Flexbox
AAAAAAAAAAAAAAA
BBBBBBBBBBBBBBB
CCCCCCCCCCCCCCC
La explicación es: * El ''item1'' empieza con un tamaño de ''300px'' (por ''flex-basis: 300px;'') pero se puede hacer más pequeño si es necesario (por ''flex-shrink: 1;'') * El ''item2'' empieza con un tamaño de ''300px'' (por ''flex-basis: 300px;'') pero **NO** se puede hacer más pequeño (por ''flex-shrink: 0;'') * El ''item3'' ocupará todo el espacio que haya libre (por ''flex-grow:1'') y eso incluye hacerlo más grande o pequeño ==== flex ==== Es poner en una misma linea ''flex-grow'', ''flex-shrink'' y ''flex-basis'' Se usa entro de los "hijos" Mas información en: * [[https://css-tricks.com/understanding-flex-grow-flex-shrink-and-flex-basis/|Understanding flex-grow, flex-shrink, and flex-basis]] * [[https://www.paradigmadigital.com/dev/diferencia-flex-basis-width/|Diferencia entre flex basis y width]] * [[https://ed.team/blog/guia-definitiva-de-flexbox-2-flex-basis-flex-frow-flex-shrink|Guia definitiva de Flexbox (2): Flex basis, flex-frow, flex-shrink]] * [[https://www.desarrollolibre.net/blog/css/las-propiedades-flex-grow-flex-shrink-y-flex-basis|Las propiedades flex-grow, flex-shrink y flex-basis]] ==== margin y auto ==== Una utilidad de flexbox es hacer menús pero a veces queremos mover algunos item hacia la derecha.El truco para hacerlo es usar ''margin-left: auto;'' En los siguientes páginas se indica como hacerlos.
Item1
Item2
Item3
Item4
Item5
En el ejemplo, los items 1 , 2 y 3 estarán pegados a la izquierda y los items 4 y 5 estarán pegados a la derecha. Mas información en: * [[https://medium.com/flexbox-and-grids/the-most-popular-navigation-bars-created-with-flexbox-6c0f59f55686|The Most Popular Navigation Bars created with Flexbox]] * [[https://github.com/ohansemmanuel/Understanding-Flexbox/blob/master/05.%20Auto%20margin%20alignment/auto_margin.md|Understanding Flexbox - auto-margin]] {{ :clase:daw:diw:1eval:flex-frog.png?direct&100 |}} Para aprender flexbox puede jugar a [[https://flexboxfroggy.com/#es|Flexbox Froggy - A game for learning CSS flexbox]] ===== Grid ===== Grid permite colocar cosas en dos dimensiones. Como si fuera una rejilla (un grid en inglés). * Guías completas de Grid: * [[https://css-tricks.com/getting-started-css-grid/|Getting Started with CSS Grid]] * [[https://css-tricks.com/snippets/css/complete-guide-grid|A Complete Guide to Grid]] * [[https://tympanus.net/codrops/css_reference/grid/|CSS Grid is a two-dimensional layout system created specifically to tackle grid-based user interfaces on the web.]] * [[https://www.codeinwp.com/blog/css-grid-tutorial-layout/|The Ultimate CSS Grid Tutorial for Beginners (With Interactive Examples)]] * {{css_grid_layout_cheatsheet.pdf|}} * Grid vs FlexBox: * [[https://www.youtube.com/watch?v=hs3piaN4b5I|Video:Flexbox vs. CSS Grid — Which is Better?]] * [[https://css-tricks.com/css-grid-replace-flexbox/|Does CSS Grid Replace Flexbox?]] * Mas información: * [[https://css-tricks.com/almanac/properties/j/justify-items/|justify-items]] * [[https://www.youtube.com/watch?v=0Gr1XSyxZy0|Los 9 grandes errores con CSS Grid]] * [[https://css-tricks.com/things-ive-learned-css-grid-layout/|Things I’ve Learned About CSS Grid Layout]] * [[https://www.webstoemp.com/blog/notes-on-using-css-grid-in-production/|Notes on using CSS Grid in production]]: Tiene de interesante el uso de "@movil" y el uso de bucles en SASS * [[https://gridbyexample.com/|Grid by Example]] .container { display:grid; grid-template-columns: 1fr 1fr 2fr; grid-template-rows: 1fr 2fr; } .item { border:1px solid red; }
Item1
Item2
Item3
Item4
Item5
Item6
==== grid-template-columns ==== Indica el tamaño de cada columna Las unidades pueden ser: * Tamaño fijo: Usar px * auto: Coje el menos tamaño posible * fr: Es una fracción del espacio libre después de quitar las columnas de tamaño fijo (Las 2 formas anteriores, px y auto) Ejemplos: * ''grid-template-columns: 1fr 1fr 2fr'' La última columna tendrá el doble de tamaño que las anteriores * ''grid-template-columns: 1fr 1fr 50px'' La segunda columna tendrá el mismo de tamaño que la primera. La última siempre 50px * ''grid-template-columns: 1fr 2fr 80px auto'' La última tendrá un tamaño mínimo posible, la tercera tendrá 80px, la segunda el doble que la primera. ==== repeat ==== Si hay muchas columnas y todas del mismo tamaño en vez de .container { grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; } se puede escribir: grid-template-columns: repeat(6, 1fr); \\ \\ o en vez de .container { grid-template-columns: 100px 100px 100px 100px 100px 100px ; } se puede escribir: grid-template-columns: repeat(6, 100px ); ==== auto-fit ==== Si el tamaño de las columnas es fijo se puede hacer lo siguiente para no especificar el número de columnas y que sea variable según el ancho de la ventana: .container { grid-template-columns: repeat(auto-fit, 100px ); } En ese caso ocupará todas las filas que sea necesario para poder poner ponerlo todo. Es una forma de hacer las cosas responsivas. \\ \\ Por último se puede usar la función ''minmax'' de CSS para hacerlo de la siguiente forma .container { grid-template-columns: repeat( auto-fit, minmax( 100px, 1fr ) ); } Que hará que cada columna ocupe como mínimo 100px y si hay mas espacio crecerá hasta ocupar todo. Pero se crearán tantas filas como sea necesario. Mas información en [[https://timwright.org/blog/2017/08/26/css-grid-layout/|repeat,auto-fit,minmax,1fr]] y en [[https://www.youtube.com/watch?v=mVQiNpqXov8|MinMax in CSS Grid — 3/3 Flexibility]] La función ''minmax'' es similar a las propiedades css de: * ''min-width'' * ''min-height'' * ''max-width'' * ''max-height'' ==== Ejemplo ==== Veamos ahora un ejemplo de la diferencia entre ''repeat(4,1fr)'' , ''repeat(auto-fit,100px)'' y ''repeat( auto-fit, minmax( 100px, 1fr ) )'' .container { display:grid; grid-template-columns: repeat(4,1fr); } .container2 { display:grid; grid-template-columns: repeat(auto-fit,100px); } .container3 { display:grid; grid-template-columns: repeat( auto-fit, minmax( 100px, 1fr ) ); } .container4 { display:grid; grid-template-columns: repeat( 4, minmax( 100px, 1fr ) ); } .item { border:1px solid red; } .item2 { border:1px solid green; } .item3 { border:1px solid blue; } .item4 { border:1px solid pink; }

repeat(4,1fr)

Item1
Item2
Item3
Item4
Item5
Item6
Item7
Item8

repeat(auto-fit,100px)

Item1
Item2
Item3
Item4
Item5
Item6
Item7
Item8

repeat( auto-fit, minmax( 100px, 1fr ) )

Item1
Item2
Item3
Item4
Item5
Item6
Item7
Item8

repeat( 4, minmax( 100px, 1fr ) )

Item1
Item2
Item3
Item4
Item5
Item6
Item7
Item8
==== grid-template-rows ==== Es lo mismo que ''grid-template-columns'' pero referido a las filas. ==== gap ==== Indica la separación entre cada una de las celdas del grid. .container { gap: 15px 10px; } {{:clase:daw:diw:1eval:grid-gap.png|}} La propiedad ''gap'' también funciona con **flex** ==== Bloque de Layout por columnas ==== Ejemplo de Layout con BEM por columnas. .l-columns { display: grid; grid-template-columns: repeat(1, 1fr); } .l-columns--2 { grid-template-columns: repeat(2, 1fr); } .l-columns--3 { grid-template-columns: repeat(3, 1fr); } .l-columns--4 { grid-template-columns: repeat(4, 1fr); }

Column A

Column B

Column C

Column D

Column E

Column F

==== span ==== Se puede hacer que un elemento ocupe más de una columna con ''grid-column: span x;'' siendo ''x'' el número de columnas que quieres que se expanda. .l-columns { display: grid; } .l-columns--4{ grid-template-columns: repeat(4, 1fr); } .l-columns__area { } .l-columns__area--span-2 { grid-column: span 2; }
* Mas información * [[https://webdesign.tutsplus.com/how-to-build-web-form-layouts-with-css-grid--cms-28776t|How to Build Web Form Layouts With CSS Grid]] * [[https://www.scale.at/blog/responsive-form-layout-css-grid|Tutorial: A Responsive Form Layout with CSS Grid]] ===== Reglas BEM de Layout ===== Para hacer una clase de Layout hay que seguir las siguientes reglas: * Siempre con dos elementos. * El ''div'' principal, al que llamaremos "padre" * Los ''div'' hijos que llamaremos "áreas" (Es para seguir la nomenclatura de grid) * El CSS solo debe tener cosas para modificar la posición (y a veces tamaño) de las Áreas pero no cambiar ni sus colores, fuentes, etc. * Puede ser optativo poner en las areas la clase del elemento si no tiene utilidad. * Las clases CSS de los elementos que son area se llamará ''&__area'' o ''&__area-YYYY''. .l-extremo { display:flex &__area-izquierda { margin-right: auto; } &__area-derecha { margin-left: auto; } } .l-columns { display: grid; grid-template-columns: repeat(1, 1fr); @for $i from 1 to 12 { &--#{$i} { grid-template-columns: repeat($i, 1fr); } } &__area { } }
Pulsar Izquierda
Pulsar Derecha
* En un área se podría poner un componente ya que sus propiedades CSS no van a //chocar//.
Pulsar Izquierda
Pulsar Derecha
Artículos en general sobre Layout * [[http://1linelayouts.glitch.me/|1-Line Layouts.10 Modern CSS layout and sizing techniques]] * [[https://moderncss.dev/|Modern CSS Solutions]] ===== Ejercicios ===== ==== Ejercicio 1 ==== Modifica la página del tema anterior para usar ahora lo nuevo de grid y flex cuando sea necesario.