5 puntos por GN⁺ 2024-02-14 | 3 comentarios | Compartir por WhatsApp
  • Centrar en CSS ya no es un solo truco, sino una cuestión de elegir entre Flow, Flexbox, Positioned layout, CSS Grid y text-align según si el elemento está dentro del flujo del documento, flotando o si hay varios elementos
  • Para centrar horizontalmente un solo elemento, el enfoque de Flow layout con max-width: fit-content para limitar el ancho y margin-inline: auto afecta menos a los elementos hermanos
  • Con Flexbox se puede centrar horizontal y verticalmente uno o varios hijos solo con justify-content: center y align-items: center, y aunque los hijos se desborden, el overflow ocurre de forma simétrica
  • Para UI flotante como modales o banners, la combinación correcta es position: fixed, inset: 0, límites de tamaño y margin: auto; CSS Grid destaca por su sintaxis corta y por superponer elementos
  • El texto en sí no se alinea con técnicas de layout, sino que necesita text-align: center; además, si se amplía el soporte de align-content en Flow layout, podría reducirse la necesidad de cambiar a Flexbox o Grid solo para alineación vertical simple

Centrado horizontal con auto margin en Flow layout

  • Una de las estrategias más antiguas es limitar el ancho del elemento y luego dejar ambos márgenes en auto
.element {
  max-width: fit-content;
  margin-left: auto;
  margin-right: auto;
}
  • En Flow layout, los elementos normalmente llenan el espacio horizontal, así que para centrarlos primero hay que limitar su ancho
  • fit-content hace que el elemento envuelva su contenido, de modo que el width quede determinado por el tamaño del contenido, como ocurre con height
  • Si se usa max-width en vez de width, solo se limita el tamaño máximo, así que cuando el contenedor se hace más angosto, el elemento también puede reducirse
  • Si solo está margin-left: auto, el espacio sobrante entra en el margen izquierdo; si ambos márgenes están en auto, el espacio restante se reparte por igual y el elemento queda centrado
.element {
  max-width: fit-content;
  margin-inline: auto;
}
  • margin-inline es la forma moderna de asignar el mismo valor a margin-left y margin-right, y tiene buen soporte de navegador
  • margin-inline forma parte de las propiedades lógicas (logical properties), así que no funciona según izquierda y derecha, sino según el eje inline de la dirección de escritura
    • Esto permite aplicar el margen al lado correcto tanto en idiomas que se escriben de izquierda a derecha como de derecha a izquierda
  • Este enfoque es útil cuando se quiere centrar solo un hijo —como una imagen entre párrafos de un blog— sin afectar a los elementos hermanos

Centrar uno o varios hijos con Flexbox

  • Flexbox es un modo de layout muy fuerte para distribuir varios ítems a lo largo del eje principal, y también se usa mucho para centrado
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}
  • Si se usan juntos justify-content: center y align-items: center, los hijos se pueden colocar en el centro horizontal y vertical
  • Aunque los hijos no quepan dentro del contenedor, la alineación se mantiene y, si se desbordan, el overflow ocurre de forma simétrica
  • También se pueden centrar varios hijos, y flex-direction controla la dirección en la que se apilan
.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  gap: 4px;
}
  • Es una opción base muy conveniente porque aplica bien tanto a uno como a varios hijos

Centrar UI flotante con Positioned layout

  • Los elementos que deben salir del flujo normal del documento y flotar por encima, como modales, prompts o banners, se pueden manejar con Positioned layout
.element {
  position: fixed;
  inset: 0px;
  width: 12rem;
  height: 5rem;
  max-width: 100vw;
  max-height: 100dvh;
  margin: auto;
}
  • position: fixed fija el elemento al viewport, y inset: 0px establece top, left, right y bottom en 0px
  • Si solo se usa inset: 0px, el elemento intentará ocupar todo el viewport, así que hay que limitar su tamaño con width, height, max-width y max-height
  • Esta combinación crea deliberadamente una condición imposible
    • El elemento no puede estar a 0px tanto del lado izquierdo como del derecho y al mismo tiempo tener un ancho de 12rem
    • El motor de renderizado de CSS prioriza la restricción de width y resuelve la tensión pegándolo a un lado según la dirección del idioma
  • Si además se agrega margin: auto, cambia la forma en que el navegador resuelve esa tensión y el elemento queda centrado horizontal y verticalmente
  • Las cuatro condiciones necesarias son position: fixed, inset: 0px, ancho y alto limitados, y margin: auto
  • Centrado en un solo eje, como un banner inferior

    .element {
      position: fixed;
      left: 0px;
      right: 0px;
      bottom: 8px;
      width: 12rem;
      max-width: calc(
        100vw - 8px * 2
      );
      margin-inline: auto;
    }
    
    • Si se omite top: 0px, desaparece la condición imposible en el eje vertical y el elemento queda fijo abajo
    • calc(100vw - 8px * 2) limita el ancho máximo para dejar un margen de seguridad en ambos lados del viewport
    • margin-inline: auto expresa con más precisión la intención de centrar en el eje horizontal
  • Elementos cuyo tamaño no se conoce

    .element {
      position: fixed;
      inset: 0;
      width: fit-content;
      height: fit-content;
      margin: auto;
    }
    
    • Si no se conoce de antemano el tamaño del elemento, se puede hacer que envuelva su contenido con width: fit-content y height: fit-content
    • Se puede agregar una restricción como max-width: 60vw, pero no es obligatorio, y el elemento quedará contenido dentro del viewport
  • Un centro intencionalmente desplazado

    • Si se ajusta un valor de inset en un solo lado, como bottom: 48px, el elemento se moverá solo la mitad de ese valor
    • Con bottom: 48px, el elemento sube 24px
    • Esto pasa porque el elemento queda colgado en el centro de una caja virtual entre los límites superior e inferior
    • Si se usa transform: translateY(-48px), se puede mover el elemento exactamente 48px hacia arriba
    • El enfoque con offset en bottom permite dejar libre la propiedad transform para animaciones o efectos de entrada posteriores

Centrar con sintaxis corta en CSS Grid y superponer elementos

  • En CSS Grid, el código más corto para centrar es la combinación display: grid con place-content: center
.container {
  display: grid;
  place-content: center;
}
  • place-content es la forma abreviada de justify-content y align-content, y aplica el mismo valor a filas y columnas

  • Con esta configuración se crea una celda de Grid 1×1 en el centro del contenedor padre

  • Diferencia frente a Flexbox

    • Aunque se vea parecido a Flexbox, CSS Grid usa un algoritmo de layout completamente distinto
    • La diferencia se hace visible si al hijo se le da width: 50% y height: 50%
    • En Flexbox, los porcentajes se calculan con base en el padre .container
    • En CSS Grid, los porcentajes se calculan con base en la celda Grid
    • Si no se definen grid-template-columns o grid-template-rows, los tracks del Grid calculan su tamaño a partir del contenido, y por eso el elemento puede terminar siendo más pequeño de lo esperado
    • En esos casos se puede agregar más CSS para ajustar Grid, pero para un centrado simple Flexbox puede ser más sencillo
  • Superponer varios elementos en la misma posición

    .container {
      display: grid;
      place-content: center;
    }
    
    .element {
      grid-row: 1;
      grid-column: 1;
    }
    
    • CSS Grid permite colocar varios hijos en la misma celda
    • Si a todos los .element se les asigna grid-row: 1 y grid-column: 1, compartirán el mismo espacio de Grid y quedarán superpuestos unos sobre otros
    • Puede funcionar incluso si los hijos tienen tamaños distintos
    .container {
      display: grid;
      place-content: center;
      place-items: center;
    }
    
    .element {
      grid-row: 1;
      grid-column: 1;
    }
    
    • Para superponer en el centro hijos de distinto tamaño, hace falta agregar place-items: center
    • place-items es la abreviatura de justify-items y align-items, y controla la alineación de las imágenes dentro de la celda Grid
    • Sin esta propiedad, aunque la celda Grid en sí esté centrada, las imágenes dentro de la celda se apilarán en la esquina superior izquierda
    • Para profundizar en CSS Grid, se puede consultar An Interactive Guide to CSS Grid

El texto se alinea aparte con text-align

  • El texto debe tratarse por separado en CSS, y las técnicas de layout como Flexbox no alinean caracteres individuales
  • Si se centra un párrafo con Flexbox, el bloque del párrafo queda centrado, pero los caracteres dentro del párrafo siguen alineados a la izquierda
  • Para centrar el texto en sí, hay que usar text-align: center
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

El futuro de Flow layout: align-content

  • En Flow layout, el centrado horizontal ya es posible con auto margin, pero hasta ahora para el centrado vertical hacían falta otros modos de layout como Flexbox o Grid
  • A inicios de 2024, los vendors de navegadores estaban implementando align-content en Flow layout
  • Este nuevo comportamiento controla la alineación del contenido en la dirección block y, en ese momento, solo podía usarse detrás de una flag en Chrome Canary y en Safari Technical Preview
  • El demo de ejemplo no reproduce un comportamiento real de Flow layout, sino que lo recrea con Flexbox después de verificar cómo funciona en Chrome Canary y Safari TP
  • Esta función no crea una UI nueva, pero sí puede reducir la necesidad de cambiar a otro modo de layout solo para un centrado simple

Criterios de elección según el caso

  • Para centrar horizontalmente un solo elemento sin afectar a sus hermanos, usa la estrategia de auto margin en Flow layout
  • Para UI flotante como modales o banners, colócalos al centro con Positioned layout y auto margin
  • Si quieres superponer varios elementos en el mismo lugar y centrarlos, CSS Grid es adecuado
  • Para centrar texto, usa text-align, y puede combinarse con otros métodos de centrado
  • En la mayoría de los demás casos, Flexbox es la opción más versátil
    • Puede manejar uno o varios hijos
    • Permite centrado horizontal y vertical
    • Sirve tanto si los hijos están dentro del contenedor como si se desbordan

3 comentarios

 
v08zbv8fvlkjasdflkj 2024-02-15

Ahora que lo pienso, de repente también me molesta que en GeekNews los artículos no estén centrados ;_; jaja

 
joyfui 2024-02-14

Yo uso mucho place-items: center;, pero veo que hay varios métodos más.

 
GN⁺ 2024-02-14
Opiniones en Hacker News
  • Como otros comentarios están comentando sobre los comentarios en sí, me sumo: creo que el meme de centrar en CSS en general se refiere a “cómo poner un elemento justo en el centro de otro”
    Desde el punto de vista de implementación, es cierto que centrar puede ser difícil y tener varios significados, pero para la generación de GeoCities o AngelFire era difícil de aceptar, porque con HTML en los 90 ya se podía poner hello sin problemas en medio de una caja amarilla de 600x600
    Era frustrante que la nueva herramienta que supuestamente era mejor no pudiera hacer una tarea estándar que ya hacíamos, y por eso se siguieron usando layouts con tablas hasta fines de los 2000. Me gusta CSS, pero quizá esto sea una especie de síndrome de Estocolmo
    Me sorprendió que valign funcione en Chromium aunque no esté presente, y no sé si es un cambio reciente

    • Tal como se dijo: poner hello en medio de una caja amarilla de 600x600 fue posible desde la primera versión de CSS. Por ejemplo, el atributo HTML valign corresponde a la propiedad CSS vertical-align de las cajas inline, inline-block y table-cell
      Pero, por experiencia, buena parte de la gente que habla con nostalgia de usar solo tablas o se queja de que CSS es limitado y confuso en realidad no hizo mucho esfuerzo por aprender cómo funciona CSS. Al menos el autor es consciente de eso
    • También funciona en Firefox sin el atributo "valign". Aun así, cuando se usan tablas sin layout fijo, siempre he visto diferencias sutiles entre los 3 navegadores principales, así que en general no dependería del comportamiento de layout automático
  • Buen artículo, y la reacción acá es bastante sorprendente para una audiencia nominalmente técnica. El layout y formato automáticos de páginas son realmente difíciles; de hecho, dan para temas de tesis doctoral[1]
    No es realista esperar abstraer esa complejidad con una expresión simple como “hazlo como yo quiero”
    Si miran el sitio web de Gwern Branwen[2], roza lo artístico, pero la clave es decidir primero la forma deseada y restringir el texto para que pueda expresarse dentro de ese estilo
    Vengo observando el layout de páginas web desde que en 1995 me sumé a una startup del “primer sitio web de golf”[3], y gracias a Zen Garden y a la lista de correo/sitio web A List Apart[4] entendí lo difícil que es lograr contenido web que se vea bien en distintos entornos de salida
    Llevar contenido semántico a una pantalla, papel o un plano finito es, en esencia, un mapeo o proyección desde el espacio original hacia un conjunto de reglas del espacio de destino, y esas reglas incluyen restricciones físicas, restricciones del software del navegador y comportamientos propios de cada navegador
    Por eso CSS parece un desastre para alguien que quiere “crear una página web desde cero”, pero en realidad se trata más de tener demasiadas opciones que de restricciones que impidan hacer cosas
    [1] https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=thes...
    [2] https://gwern.net/
    [3] Se llamaba Golfweb, y al parecer terminó formando parte de CBS Sports
    [4] https://www.alistapart.com

    • Aunque mi carrera en layout web empezó en 1998, unos 3 años después, en toda mi experiencia relacionada todavía no he visto nada tan excelente como el material de Every Layout[1]. Muy recomendable
      [1] https://every-layout.dev/rudiments/boxes/
    • El problema de CSS es casi por completo complejidad autoinfligida. Es cierto que el layout es difícil, pero me pregunto por qué apuntaron al modelo actual y lo hicieron todavía más difícil
      En particular, hay una meta sisífica de buscar un gran modelo único que sirva para todas las páginas y recalcular el layout automático en cada página. Si a eso se suma la meta de cubrir todos los tamaños de ventana, no entiendo por qué pensaron que eso era posible
    • No podía dejar de poner este enlace para quienes quieran ver más arte con CSS
      https://css-art.com/the-girl-with-a-p-e-a-r-l-css-earring/
      No sé cuántos div centrados contiene
    • En los últimos días intenté encajar layouts basados en flujo y paginación en un sistema de layout basado en Flexbox, y confirmé que el layout y el formato son definitivamente difíciles
      Especialmente en tablas con texto y objetos de distintos tamaños en cada columna, decidir cuándo y cómo pasar elementos a la página siguiente es un trabajo complicado de elegir buenas heurísticas
    • No sé cómo distinguir si esto es un problema autoimpuesto o un problema de investigación inherentemente difícil. Antes de entrar al desarrollo web nunca pensé que “el layout es difícil”, y ya existían ventanas desplazables y redimensionables
      En custom appkit, controles GTK y un toolkit basado en Lua que no publicamos, centrar contenido o hacer salto de línea y alineación de elementos no era nada especial; me pregunto qué es lo que se está pasando por alto en la web
      Eso de que “solo hay abundancia de opciones” suena parecido al TMTOWTDI enterrado hace tiempo
  • Excelente artículo, y los elementos interactivos son especialmente buenos. Lo que más me ayudó hace unos años a entender el posicionamiento y centrado en CSS fue leer sobre el modelo de caja
    Entender el modelo de caja ayuda a razonar sobre el flujo dentro del DOM, y las propiedades CSS display y position también son fundamentales para aprender posicionamiento. La documentación de MDN está bien hecha
    https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_...
    https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layou...

  • “Cómo centrar algo” es una pregunta clásica de CSS, y el hecho mismo de que no sea tan obvio como para verlo frente a tus ojos dice mucho. CSS se parece más a una mezcla turbia de todo, una colección tipo fregadero diseñada simultáneamente por varios comités, no por uno solo
    Hace mucho se abandonó la idea de lanzamientos reales, y el estado actual de CSS se parece más a una recopilación de estados de módulos individuales que cambian continuamente. No es una forma de desarrollar software y, de hecho, tampoco es una buena forma de construir nada

    • Estoy de acuerdo y en desacuerdo. Los grandes grupos humanos se mueven así: lento y de forma caótica, como intentar arrear gatos
      Tampoco está claro hacia dónde van colectivamente la web y sus tecnologías, así que inevitablemente aparecen muchos experimentos fallidos e inconsistencias. Es un alcance mucho más amplio que el de un proyecto de ingeniería bien planificado con objetivos y camino claros
    • Creo que la pregunta sobre centrar aparece tan seguido porque, para quien está aprendiendo, es una de las primeras preguntas más naturales
      Quien aprende a hacer que una página web se vea como quiere suele empezar con tamaño de texto, color, color de fondo y alineación; salvo la alineación, lo demás corresponde casi 1:1 con las formas anteriores a CSS
      Antes de CSS, si querías poner contenido en el centro, simplemente lo metías en una etiqueta, sin importar si era texto o un objeto HTML como un div, una tabla o un botón. Mucha gente esperaba que CSS también funcionara como antes, sin distinguir entre objetos inline y de bloque, pero como CSS no encajaba con ese prejuicio, surgió esta pregunta
  • Este artículo me parece excelente, y en especial la forma de interacción es muy buena. También existe una herramienta que desde hace mucho casi siempre daba el resultado deseado
    http://howtocenterincss.com

  • A CSS le tomó décadas ofrecer una solución tan útil como una tabla con contenido centrado, y mientras tanto se criticaba usar tablas para el layout

  • Como mucha gente aquí, creo que CSS es un desastre total. El problema central es que las directivas de estilo se sobrescriben entre sí constantemente, o fallan en silencio sin producir ningún efecto

  • Me gustó que uno de los ejemplos tuviera un aviso de cookies brutalmente honesto
    “Valoramos tus datos personales. Para mejorar tu experiencia de navegación, usamos cookies que venden esos datos a anunciantes. Eso es muy valioso”

  • Es interesante lo que se puede aprender de la historia de usar tablas para layout. Las tablas tienen bordes, padding y un layout basado en celdas organizadas en columnas; si lo extendemos, alrededor de la tabla y de las celdas también se necesitan espacios, es decir, márgenes
    Las tablas son un elemento establecido desde hace mucho en el layout y, de hecho, contenían la sabiduría de que todos los elementos deberían comportarse hasta cierto punto como celdas de tabla
    Los elementos deben seguir el modelo de caja, algo bastante obvio para quien trabaja con tipografía, pero que también deban organizarse en columnas es menos evidente y se convierte en la base de Grid layout y Bootstrap
    Al encontrarse con un problema de layout, resolverlo con tablas y luego darse cuenta de que se necesita una función nueva que tenga algunas propiedades de las tablas, pero no todas, es una evolución natural
    CSS descubrió esto, pero curiosamente algunos sistemas, como los procesadores de texto, no lograron unificar los elementos bajo el modelo de caja

  • Las quejas de “¿por qué sigue siendo tan difícil?” me parecen bastante erradas. Como dice el artículo, Flexbox resuelve de forma intuitiva todos los casos simples de centrado
    Si no se resuelve con Flexbox, entonces no se trata simplemente de centrar, sino de hacer algo más complejo, y no es razonable esperar que la implementación sea súper simple

    • Desde la perspectiva de alguien que lleva mucho tiempo en esto, antes de Flexbox era difícil, y también lo fue durante la época en que Flexbox no tenía soporte al 100%, porque había que seguir monitoreando el uso de navegadores para decidir si se podía usar
      Ahora hay tantos métodos que la complejidad abruma. Es más común arreglar código viejo que crear algo nuevo, y hay que evaluar por qué el CSS fue escrito de cierta manera, qué casos límite podrían romperse, si se puede corregir, y qué solución elegir entre varias cuando no es algo simple
      Incluso hojeando el artículo no resulta intuitivo. En Flexbox, la configuración horizontal es justify-content y la vertical es align-items, pero hay tantas propiedades de CSS, y sus nombres son tan arbitrarios, que ya no las recuerdo bien
      Al final, la diferencia está entre construir soluciones complejas con bloques de construcción simples, intuitivos y confiables, o construir soluciones complejas con bloques de construcción complicados, que se solapan parcialmente y que hay que buscar constantemente
      Go o Python están más cerca de lo primero, y CSS más cerca de lo segundo
    • Flexbox es lo que siempre quise que fuera CSS; durante mucho tiempo no lo fue, hasta que un día lo fue, y se volvió posible abandonar el soporte para navegadores sin Flexbox. Casi se siente como la forma final de CSS
      Había una razón por la que a la gente le gustaba el sistema de grillas de Bootstrap, y Flexbox hace todo eso y más directamente dentro del navegador. Es difícil exagerar cuánto me gusta
    • En algún momento, en ciertos casos, era moderadamente difícil, pero desde hace unos 10 años ya es un problema resuelto. Todavía hay gente que habla de centrar un div en CSS como si estuviera a medio camino entre la alquimia y la ciencia espacial
      Eso muestra que no siguen los cambios de CSS tanto como otras partes del desarrollo web, pero aun así se sienten cómodos haciendo afirmaciones así
    • Además, Flexbox ha tenido soporte amplio por más de 10 años. El hilo de comentarios aquí es bastante fascinante
    • Totalmente cierto. Cuando uno se pelea con Flexbox, ayuda dar un paso atrás y resolverlo paso a paso
      Ir de afuera hacia adentro, del elemento padre al elemento hijo, lo vuelve mucho más fácil. Requiere algo de técnica, pero básicamente se acerca más al álgebra elástica