imagenes - tablas en html5
¿Puedes hacer este diseño HTML sin usar tablas? (10)
Ok, tuve un problema de diseño simple hace una semana o dos. Es decir, las secciones de una página necesitaban un encabezado:
+---------------------------------------------------------+
| Title Button |
+---------------------------------------------------------+
Bastante simple. La cuestión es que el odio a la mesa parece haber tomado el control en el mundo de la Web, lo que me recordó cuando pregunté ¿Por qué utilizar listas de definiciones (DL, DD, DT) para formularios HTML en lugar de tablas? Ahora el tema general de tablas vs divs / CSS ha sido discutido previamente, por ejemplo:
Por lo tanto, esto no pretende ser una discusión general sobre CSS vs tablas para el diseño. Esta es simplemente la solución a un problema. Intenté varias soluciones a las anteriores utilizando CSS, que incluyen:
- Flota a la derecha para el botón o div que contiene el botón;
- Posición relativa para el botón; y
- Posición relativa + absoluta.
Ninguna de estas soluciones fue satisfactoria por diferentes razones. Por ejemplo, el posicionamiento relativo dio como resultado un problema de índice z donde mi menú desplegable apareció bajo el contenido.
Así que terminé volviendo a:
<style type="text/css">
.group-header { background-color: yellow; width: 100%; }
.group-header td { padding: 8px; }
.group-title { text-align: left; font-weight: bold; }
.group-buttons { text-align: right; }
</style>
<table class="group-header">
<tr>
<td class="group-title">Title</td>
<td class="group-buttons"><input type="button" name="Button"></td>
</tr>
</table>
Y funciona perfectamente. Es simple, tan retrocompatible como sea posible (eso funcionará probablemente incluso en IE5) y simplemente funciona. Sin problemas con el posicionamiento o las carrozas.
Entonces, ¿alguien puede hacer el equivalente sin tablas?
Los requisitos son:
- Compatible con versiones anteriores: a FF2 e IE6;
- Razonablemente consistente: en diferentes navegadores;
- Verticalmente centrado: el botón y el título son de diferentes alturas; y
- Flexible: permita un control razonablemente preciso sobre el posicionamiento (relleno y / o margen) y el estilo.
En una nota lateral, encontré un par de artículos interesantes hoy:
EDITAR: Permítanme explicar el tema del flotador. Este tipo de trabajo:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { float: left; padding: 8px; }
.group-buttons { float: right; padding: 8px; }
</style>
</head>
<body>
<div class="group-header">
<div class="group-title">This is my title</div>
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
<div class="group-content">
<p>And it works perfectly. It''s simple, as backward compatibile as it gets (that''ll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
Gracias a Ant P por el overflow: hidden
parte overflow: hidden
(aunque todavía no entiendo por qué). Aquí es donde aparece el problema. Digamos que quiero que el título y el botón se centren verticalmente. Esto es problemático porque los elementos son de diferente altura. Compare esto con:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-header td { vertical-align: middle; }
.group-title { padding: 8px; }
.group-buttons { text-align: right; }
</style>
</head>
<body>
<table class="group-header">
<tr>
<td class="group-title">This is my title</td>
<td class="group-buttons"><input type="button" value="Collapse"></td>
</tr>
</table>
<div class="group-content">
<p>And it works perfectly. It''s simple, as backward compatibile as it gets (that''ll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
que funciona a la perfección
Decidí usar Flex Box porque facilitaba las cosas.
Básicamente necesita ir al padre de los hijos que desea alinear y agregar display: box (prefijado por supuesto). para hacer que se sienten en los lados use justify-content . el espacio intermedio es lo correcto cuando tienes elementos que necesitan alinearse hasta el final, como en este caso (ver enlace) ...
entonces el problema de la alineación verical. porque hice el padre de los dos elementos que desea alinear un cuadro flexible, ahora es fácil usar los elementos alineados: centro. luego agregué los estilos que quería antes, eliminé el flotador del título y el botón en el encabezado y agregué un relleno.
.group-header, .group-content {
width: 500px;
margin: 0 auto;
}
.group-header{
border: 1px solid red;
background: yellow;
overflow: hidden;
display: -webkit-box;
display: -moz-box;
display: box;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
-o-justify-content: space-between;
justify-content: space-between;
webkit-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
-o-align-items: center;
align-items: center;
padding: 8px 0;
}
.group-content{
border: 1px solid black;
background: #DDD;
}
.group-title {
padding-left: 8px;
}
.group-buttons {
padding-right: 8px
}
En CSS puro, una respuesta de trabajo algún día será simplemente usar "display:table-cell"
. Desafortunadamente, eso no funciona en los navegadores de categoría A actuales, por lo que para todo eso, podrías usar una tabla si solo deseas obtener el mismo resultado de todos modos. Por lo menos, estarás seguro de que funciona lo suficientemente lejos en el pasado.
Honestamente, solo usa una tabla si es más fácil. No va a doler.
Si la semántica y la accesibilidad del elemento de la tabla realmente le importan, hay un borrador en proceso para hacer que su tabla no sea semántica:
http://www.w3.org/TR/wai-aria/#presentation
Creo que esto requiere una DTD especial más allá de XHTML 1.1, que simplemente agitaría todo el debate text/html
vs application/xml
, así que no vayamos allí.
Por lo tanto, a su problema de CSS no resuelto ...
Para alinear verticalmente dos elementos en su centro: se puede hacer de diferentes maneras, con algunos hackeos CSS obtusos.
Si puede encajar dentro de las siguientes limitaciones, entonces hay una manera relativamente simple:
- La altura de los dos elementos es fija.
- La altura del contenedor es fija.
- Los elementos serán lo suficientemente estrechos como para no superponerse (o se pueden establecer en un ancho fijo).
Entonces puedes usar posicionamiento absoluto con márgenes negativos:
.group-header { height: 50px; position: relative; }
.group-title, .group-buttons { position: absolute; top: 50%; }
# Assuming the height of .group-title is a known 34px
.group-title { left: 0; margin-top: -17px; }
# Assuming the height of .group-buttons is a known 38px
.group-buttons { right: 0; margin-top: -19px; }
Pero esto no tiene sentido en la mayoría de las situaciones ... Si ya conoce la altura de los elementos, puede usar flotadores y agregar suficiente margen para colocarlos según sea necesario.
Aquí hay otro método que usa la línea base de texto para alinear verticalmente las dos columnas como bloques en línea. El inconveniente aquí es que necesita establecer anchos fijos para que las columnas llenen el ancho desde el borde izquierdo. Como necesitamos mantener los elementos bloqueados en una línea de base de texto, no podemos usar simplemente flotante: a la derecha para la segunda columna. (En cambio, tenemos que hacer que la primera columna sea lo suficientemente ancha como para empujarla).
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; }
.valign { display: inline-block; vertical-align: middle; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { padding: 8px; width: 384px; }
.group-buttons { padding: 8px; width: 84px; text-align: right; }
</style>
<!--[if lt IE 8]>
<style type="text/css">
.valign { display: inline; margin-top: -2px; padding-top: 1px; }
</style>
<![endif]-->
</head>
<body>
<div class="group-header">
<div class="valign">
<div class="group-title">This is my title.</div>
</div><!-- avoid whitespace between these! --><div class="valign">
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
</div>
<div class="group-content">
<p>And it works perfectly, but mind the hacks.</p>
</div>
</body>
</html>
El HTML: agregamos .valign wrappers alrededor de cada columna. (Dales un nombre más "semántico" si te hace más feliz.) Debes mantenerlos sin espacios en blanco o los espacios de texto los separarán. (Sé que apesta, pero eso es lo que obtienes por ser "puro" con el marcado y separarlo de la capa de presentación ... ¡Ja!)
El CSS: usamos vertical-align:middle
para alinear los bloques con la línea base de texto del elemento group-header. Las diferentes alturas de cada bloque se mantendrán verticalmente centradas y empujarán la altura de su contenedor. El ancho de los elementos se debe calcular para que se ajuste al ancho. Aquí, son 400 y 100, menos su relleno horizontal.
Las correcciones de IE: Internet Explorer solo muestra bloque en línea para elementos nativos en línea (por ejemplo, span, no div). Pero, si le damos el div hasLayout y luego lo mostramos en línea, se comportará como en línea. El ajuste del margen consiste en fijar un espacio de 1px en la parte superior (intente agregar colores de fondo al título del grupo para ver).
Esta es una especie de pregunta capciosa: parece terriblemente simple hasta que llegas a
Digamos que quiero que el título y el botón estén centrados verticalmente.
Quiero dejar constancia de que sí, el centrado vertical es difícil en CSS. Cuando las personas publican, y parece interminable en SO, "¿puedes hacer X en CSS?" La respuesta casi siempre es "sí" y su apetito no parece justificado. En este caso, sí, esa cosa en particular es difícil.
Alguien debería simplemente editar toda la pregunta hasta "¿Es problemático el centrado vertical en CSS?".
Estoy de acuerdo en que uno solo debería usar tablas para datos tabulares, por la sencilla razón de que las tablas no se muestran hasta que se terminan de cargar (sin importar qué tan rápido sea, es más lento que el método CSS). Sin embargo, creo que esta es la solución más simple y elegante:
<html><head><title>stack header</title>
<style type="text/css">
#stackheader {
background-color: #666;
color: #FFF;
width: 410px;
height: 50px;
}
#title {
color: #FFF;
float: left;
padding: 15px 0 0 15px;
}
#button {
color: #FFF;
float: right;
padding: 15px 15px 0 0;
}
</style></head><body>
<div id="stackheader">
<div id="title">Title</div>
<div id="button">Button</div>
</div>
</body></html>
La función del botón y cualquier detalle adicional se pueden diseñar a partir de esta forma básica. Disculpas por las malas etiquetas.
Haz una doble flotación en un div y usa el clearfix. http://www.webtoolkit.info/css-clearfix.html ¿Tiene restricciones de relleno / margen?
<div class="clearfix">
<div style="float:left">Title</div>
<input type="button" value="Button" style="float:right" />
</div>
No tiene nada de malo utilizar las herramientas disponibles para hacer el trabajo de manera rápida y correcta.
En este caso, una mesa funcionó a la perfección.
Yo personalmente hubiera usado una mesa para esto.
Creo que las tablas anidadas deberían evitarse, las cosas pueden desordenarse.
Simplemente flote hacia la izquierda y hacia la derecha y configúrelo para borrar ambos y listo. Sin necesidad de tablas.
Editar: Sé que obtuve muchos votos positivos para esto y creí que tenía razón. Pero hay casos en los que simplemente necesitas tener tablas. Puedes intentar hacer todo con CSS y funcionará en los navegadores modernos, pero si deseas apoyar a los más antiguos ... No repetirlo, aquí la pila relacionada desborda el hilo y despotrica en mi blog .
Edit2: Como los navegadores más antiguos ya no son tan interesantes, estoy usando Twitter bootstrap para nuevos proyectos. Es ideal para la mayoría de las necesidades de diseño y lo hace con CSS.
Título flotante a la izquierda, botón flotante a la derecha y (esta es la parte que no supe hasta hace poco): crea el contenedor de ambos {overflow:hidden}
.
Eso debería evitar el problema del índice z, de todos modos. Si no funciona, y realmente necesita la compatibilidad con IE5, siga adelante y use la tabla.
Yo recomendaría no usar una tabla en esta instancia, porque eso no es datos tabulares; es puramente de presentación tener el botón ubicado en el extremo derecho. Esto es lo que haría para duplicar la estructura de su tabla (cambie a una H # diferente para que se adapte a su ubicación en la jerarquía de su sitio):
<style>
.group-header { background: yellow; zoom: 1; padding: 8px; }
.group-header:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
/* set width appropriately to allow room for button */
.group-header h3 { float: left; width: 300px; }
/* set line-height or margins to align with h3 baseline or middle */
.group-header input { float: right; }
</style>
<div class="group-header">
<h3>This is my title</h3>
<input type="button" value="Collapse"/>
</div>
Si desea alineación vertical verdadera en el medio (es decir, si el texto se ajusta, el botón aún está alineado a la mitad con respecto a ambas líneas de texto), entonces necesita hacer una tabla o trabajar algo con position: absolute
y márgenes. Puede agregar position: relative
a su menú desplegable (o más probablemente su elemento principal) para colocarlo en el mismo nivel de orden que los botones, lo que le permite ubicarlo encima de ellos con índice z, si se trata de eso .
Tenga en cuenta que no necesita width: 100%
en el div porque es un elemento de nivel de bloque, y zoom: 1
hace que el div se comporte como si tuviera un clearfix en IE (otros navegadores recogen el clearfix real). Tampoco necesita todas esas clases superfluas si está enfocando las cosas un poco más específicamente, aunque es posible que necesite un divisor div o un intervalo en el botón para facilitar el posicionamiento.
<div class="group-header">
<input type="button" name="Button" value="Button" style="float:right" />
<span>Title</span>
</div>