CSS3 box-sizing: margen-cuadro; Por qué no?

139

¿Por qué no tenemos box-sizing: margin-box;? Por lo general, cuando ponemos box-sizing: border-box;en nuestras hojas de estilo realmente nos referimos a lo primero.


Ejemplo:

Digamos que tengo un diseño de página de 2 columnas. Ambas columnas tienen un ancho del 50%, pero se ven un poco feas porque no hay canalón (espacio en el medio); A continuación se muestra el CSS:

.col2 {
    width: 50%;
    float: left;
}


Para aplicar una canaleta, puede pensar que podríamos establecer un margen derecho en la primera de las 2 columnas; algo como esto:

.col2:first-child {
    margin-right: 24px;
}

Pero esto haría que la segunda columna se ajuste a una nueva línea, porque lo siguiente es cierto:

50% + 50% + 24px > 100%

box-sizing: margin-box;resolvería este problema al incluir el margen en el ancho calculado del elemento. Me parece muy útil si no más útil que box-sizing: border-box;.

Diseñador web
fuente
30
"¿Por qué no tenemos box-sizing: margin-box;?" Porque si bien los márgenes horizontales no colapsan, tal propuesta interferiría seriamente con el colapso del margen vertical. De todos modos, si desea proponer algo para la estandarización, Stack Overflow no es el lugar correcto. Prueba las listas de correo.
BoltClock
16
En ciertas situaciones, puede evitar esto usando border: xxx solid transparent;, ya que el borde está incluido en border-box. Sin embargo, esto romperá algunas otras cosas, como box-shadow.
Nathan Osman
28
¿Estamos cerrando todas las preguntas sobre estándares como "no constructivas" ahora? Es una pregunta justa, e incluso tiene una respuesta directa: no la tenemos box-sizing: margin-boxporque no funcionaría con el colapso del margen.
thomasrutter
@thomasrutter: No había una razón mejor redactada cuando lo cerré, que fue hace más de un año. De todos modos, "no constructivo" se ha ido ahora (lo que significa que no, en realidad ya no cerramos nada como no constructivo), y como todo "tengo una idea, así es como funciona, ¡hagamos de esto un estándar!" la cosa se ha eliminado desde que se cerró por última vez, ahora en realidad suena como un práctico "¿por qué X no funciona?" pregunta. Todavía es una pregunta increíblemente especulativa (mi razonamiento anterior no es más que una suposición educada), pero no voy a comentar más sobre eso.
BoltClock
¿por qué no tener un centro de la envoltura / div si desea espaciar: codepen.io/chriscoyier/pen/eGcLw
Ashley

Respuestas:

55

¿No podrías usar width: calc(50% - 24px);para tus cols? Luego establece tus márgenes.

Flexible
fuente
55
Es altamente dependiente del navegador. Probablemente alrededor de 2020, el ie15 lo admitirá y también se le permitirá usar eso en su trabajo :-(
peterh - Reinstale Monica el
1
¿No parece funcionar tan bien en Firefox? (o algo más que he hecho no es)
Laurengineer
@ Morgan Feeney: Sí, pero el tamaño de la caja no tiene un valor llamado margen-caja (que es el punto central de esta pregunta). Incluso si tal valor se introdujera ahora, ¿cómo propones parcharlo / rellenarlo / calzarlo en los navegadores existentes?
BoltClock
Sí, pero ... respondiendo específicamente a una respuesta que sugiere calc () como solución alternativa.
Morgan Feeney
No estoy seguro de si esto se aplica al ejemplo específico, pero una de las principales negativas al uso de calc () en nuestro escenario (como en FF 53.0.3) es que su comportamiento no es análogo al de ancho: X%; Por lo que podemos ver, "calc" se realiza en el momento de la representación inicial en un Xpx estático. Esto significa que, a diferencia del ancho: X%, la columna calculada no cambia de tamaño automáticamente con el cambio de tamaño del contenedor.
Pancho
16

Creo que podríamos tener un box-sizing: margin-box. El modelo de caja css muestra exactamente cuáles son las posiciones de los márgenes de los marcos.

Existen problemas menores, por ejemplo, los cuadros de margen pueden superponerse, pero no son difíciles de resolver.

Creo que la situación es la misma, como podemos ver con el overflow-x&overflow-y combinaciones , con los divs posicionados absolutos en las celdas de la tabla, con la combinación de min | max-width | height con el tamaño de la caja, y así sucesivamente.

Hay características, características realmente simples, que los desarrolladores del navegador simplemente no desarrollan.

En mi humilde opinión, box-sizing: margin-boxfueron una característica muy útil. Otra característica útil fueron lasbox-sizing: padding-box , existe al menos en el estándar, pero no se implementó en ninguno de los principales navegadores. ¡Ni siquiera en el cromo más nuevo!


Nota: Comentario de @Oriol: Firefox implementó box-sizing: padding-box. Pero otros no, y fue eliminado de la especificación. Firefox lo eliminará en la versión 50. Triste.

peterh - Restablece a Monica
fuente
2
Firefox lo implementó box-sizing: padding-box. Pero otros no, y fue eliminado de la especificación. Firefox lo eliminará en la versión 50. Triste.
Oriol
6

El chico en la parte superior pregunta si desea agregar margen al ancho total, incluidos el relleno y el borde. La cuestión es que el margen se aplica fuera del cuadro y el relleno y el borde no, cuando se usa border-box.

He tratado de lograr la border-marginidea. Lo que he encontrado es que si usa el margen puede agregar una clase de .lastal último elemento (con margen, luego aplicar un margen de cero o usar :last-child/:last-of-type). O agregue márgenes iguales en todos los sentidos (similar a la versión de relleno anterior).

Ver ejemplos aquí: http://codepen.io/mofeenster/pen/Anidc

border-boxcalcula el ancho del elemento + su relleno + su borde como el ancho total. Entonces, si tienes 2 divs que tienen un 50% de ancho, serán adyacentes. Si les agrega 8pxrelleno, entonces tendrá una canaleta de 16px. Combine eso con un elemento de envoltura, que también tiene relleno 8px, tendrá una cuadrícula muy bien distribuida con canales iguales por todos lados.

Vea este ejemplo aquí: http://codepen.io/mofeenster/pen/vGgje

Este último es mi método favorito.

Morgan Feeney
fuente
4

Estoy seguro de que todo esto es obvio, pero lo escribiré de todos modos porque ... bueno, necesito el ejercicio. ¿El siguiente resultado no sería tan eficiente como box-sizing: margin-box;:

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizingse utiliza para controlar desde qué punto el relleno y el borde se evalúan según el tamaño general del elemento. Entonces, aunque no es kosher incluir pxmárgenes con un %ancho (como suele ser siempre el caso), es más fácil calcular cuál debería ser la cantidad de porcentaje relativo porque no tiene que incorporar relleno y bordes al ancho definido.

Plummer
fuente
9
El caso de uso para algo así como el cuadro de margen es permitir mezclar anchos de porcentaje con márgenes de píxeles. Si desea dos cuadros de 50% con un margen de 1px entre ellos, esto no se puede lograr con un margen de porcentaje de 1% de similar: algunos tamaños de pantalla pequeños redondearán 1% a 0 píxeles y de repente no tendrá margen. Lo que realmente necesitamos es más compatibilidad con el navegador para calc () como muestra @Slouch, o el modelo flexbox.
1
Si ese es el cuidado, el contenedor principal sería inferior a 100 px, y espero que algunos elementos de diseño se replanteen en ese momento. Hay algunas otras cosas que podría hacer con elementos anidados y similares, pero, sí, tener cálculos variables sería bastante tonto. Si te gustan cosas como sass o menos, creo que hacen muchas de estas cosas. He jugado con ellos, pero todavía no soy un Jedi.
Plummer
2
Lo que estás sugiriendo es una solución alternativa. No es una forma ideal de escribir CSS cuando trabajas con diseños complejos. Estás asumiendo que el diseñador o autor quiere usar porcentajes en su diseño. Además, independientemente de este problema, incluso si usa la función calc () para calcular el espaciado usando márgenes de píxeles, todavía limita al diseñador porque debe predeterminar qué es el canal, en lugar de permitir que se sobrescriba usando CSS.
limitlessloop
No entiendo tu punto. El problema en cuestión era que incluir px y% causa saltos de línea porque el margen no se incluye en el cálculo del tamaño. Un margen no está incluido en el tamaño de un elemento, es el espacio que desea que aparezca alrededor de un elemento. Además, ¿cómo margin-boxmanejaría los cálculos de márgenes multidimensionales? @mediapuntos de interrupción max-widthy min-widthfuncionan bien. Supongo que margin-boxpodría reducir un poco la hinchazón, pero también obtengo razones por las que puede considerarse redundante.
Plummer
¿Por qué nadie menciona que este VALOR de porcentaje de margen es el porcentaje de ancho por alguna razón ... no importa la altura o el ancho? Se utiliza el ancho del padre. Lo cual es extraño por decir lo menos ... por lo que el código anterior no debería funcionar y no funciona. a menos que iguale la altura y el ancho.
Muhammad Umer
4

Esto se debe a que el atributo de tamaño de caja se refiere al tamaño de un elemento después de calcular los valores específicos de dimensión dados (relleno, bordes). "box-sizing: border-box" establece la altura / anchura de un elemento y tiene en cuenta el relleno y el ancho del borde. El alcance del margen de un elemento es mayor que el elemento en sí mismo, lo que significa que modifica el flujo de la página y sus elementos circundantes, por lo tanto, altera directamente la forma en que el elemento se ajusta dentro de su elemento primario en relación con sus elementos hermanos. En última instancia, un valor de atributo "cuadro de margen" causaría problemas importantes y es esencialmente lo mismo que establecer los elementos alto / ancho directamente.

Ryan
fuente
1
Mis disculpas, pero no entiendo cómo incluir el relleno, el borde y el margen en el cálculo espacial a través de "margen-cuadro" diferiría conceptualmente de incluir el relleno y el borde a través de "borde-cuadro". ¿Seguramente es solo una variación sobre el mismo tema?
Pancho
1

En Codrops hay un par de buenos artículos sobre el tema del efecto de los márgenes y las filas forzadas a desbordarse. Sugieren usar la unidad rem o em con un CSS normalizador estableciendo el tamaño de fuente al 100% para todos los navegadores, luego, cuando se configuran anchos y márgenes, es fácil realizar un seguimiento del efecto en el ancho de la fila simplemente haciendo una nota en los comentarios para El ancho total. Una conversión de 16px a 1 em es la forma de calcular el total de ventanas objetivo con total.

Trabajando así para la etapa de desarrollo al menos y luego, si desea plantillas 'receptivas', puede convertir anchos a%, incluidos los anchos de margen.

La otra forma, a menudo más simple, que sugieren manejar las canaletas es usar el pseudo después y el content: ''; de cada una de sus columnas que creo que funciona muy bien. Si establece una clase div que es la última columna definida, como final, puede seleccionar esa clase para que no tenga el pseudo después o una más amplia; el que mejor se adapte a su diseño.

La ventaja adicional de usar este método de pseudoelemento es que también le proporciona un objetivo para las sombras que pueden dar un efecto más 3D y una mayor profundidad a la imagen plana en el monitor de los lectores. En este momento estoy experimentando con este efecto ampliando los efectos que se usan en los botones, 'ajustando' los gradientes y el índice z.

Weedy101
fuente
1

Las dimensiones de los elementos no reemplazados a nivel de bloque en flujo normal deben satisfacer

margen-izquierda + borde-izquierda-ancho + relleno-izquierda + ancho + relleno-derecha + borde-derecha-ancho + margen-derecha = ancho del bloque contenedor

Cuando están demasiado restringidos, los navegadores deben ajustar el margen izquierdo o derecho. Creo que eso significa que el ancho del cuadro de margen debe ser igual al ancho del bloque contenedor (es decir, 100%).

Para su caso, los bordes transparentes box-sizing: border-boxpueden funcionar como márgenes .

sam
fuente
1

Quizás establezca el borde en 0% de opacidad usando RGBA y use el borde como margen.

usuario3236407
fuente
Suena como un truco, pero haría el trabajo.
Morgan Feeney
Esto puede resultar útil si no desea utilizar envoltorios para lograr el trabajo.
limitlessloop
... a menos que realmente necesites un borde
FrancescoMM
@FrancescoMM: un poco "ruidoso", pero podría hacer un cuadro con un borde transparente de "ancho de margen" (y sin margen, por supuesto) y dentro de ese lugar un cuadro con un borde visible del ancho que desea mostrar (de nuevo sin margen)
Pancho
1
Simplemente no puedo seguir este tipo de pensamiento. ¿Hay algo más natural que decir que quiero dos cajas 1pxseparadas, cada una ocupando 50%espacio disponible? Eso es exactamente lo margin-boxque haría. O olvide el cuadro de margen y piense en el espacio disponible. No el 50% del contenedor principal, sino el 50% de lo que queda. No "calc", no "5% margin", no tal desastre ...
maaartinus
0

Hay una situación interesante cuando se utiliza el tamaño de la caja dentro del contenido del cuerpo

sin contenido no hay cuadro de borde no da ningún valor en el margen izquierdo-derecho% recuento de estos algoritmos de recuento de dos cuadros

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

Las versiones de Firefox anteriores a la 57 también admitían el valor del cuadro de relleno para el tamaño del cuadro, aunque este valor se eliminó de la especificación y las versiones posteriores del navegador.

Por lo tanto, el margen no está planeado ...

Dmytro Yurchenko
fuente