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 |
+---------------------------------------------------------+
Cosas bastante simples. La cosa es que el odio a las tablas parece haberse apoderado del mundo web, lo cual recordé cuando pregunté ¿Por qué usar etiquetas de listas de definiciones (DL, DD, DT) para formularios HTML en lugar de tablas? Ahora, el tema general de tablas vs divs / CSS se ha 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. Probé varias soluciones a lo anterior usando CSS, que incluyen:
- Flota a la derecha para el botón o un 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 resultó en un problema de índice Z donde mi menú desplegable apareció debajo del 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, compatible con versiones anteriores (que probablemente funcionará incluso en IE5) y simplemente funciona. No se pierda el posicionamiento o los flotadores
Entonces, ¿alguien puede hacer el equivalente sin tablas?
Los requisitos son:
- Compatible con versiones anteriores: a FF2 e IE6;
- Razonablemente consistente: en diferentes navegadores;
- Centrado verticalmente: el botón y el título tienen diferentes alturas; y
- Flexible: permite un control razonablemente preciso sobre el posicionamiento (relleno y / o margen) y el estilo.
En una nota al margen, me encontré con un par de artículos interesantes hoy:
EDITAR: Permítanme ampliar el tema de la flotación. Este tipo de obras:
<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
papel (aunque todavía no entiendo por qué). Aquí es donde entra el problema. Digamos que quiero que el título y el botón estén centrados verticalmente. Esto es problemático porque los elementos tienen 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 perfectamente.
Respuestas:
No hay nada de malo en utilizar las herramientas que están disponibles para hacer el trabajo de forma rápida y correcta.
En este caso una mesa funcionó a la perfección.
Personalmente, habría utilizado una mesa para esto.
Creo que las tablas anidadas deben evitarse, las cosas pueden complicarse.
fuente
Simplemente flote hacia la izquierda y hacia la derecha y configure para borrar ambos y listo. Sin necesidad de mesas.
Editar: Sé que obtuve muchos votos a favor por esto, y creí que tenía razón. Pero hay casos en los que simplemente necesita tener tablas. Puede intentar hacer todo con CSS y funcionará en los navegadores modernos, pero si desea admitir los más antiguos ... No para repetirme, aquí el hilo de desbordamiento de pila relacionado y despotricar en mi blog .
Edición 2: Dado que 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 utiliza CSS.
fuente
Esta es una especie de pregunta capciosa: parece terriblemente simple hasta que llegas a
Quiero dejar constancia de que sí, el centrado vertical es difícil en CSS. Cuando la gente publica, y parece interminable en SO, "¿puedes hacer X en CSS?", La respuesta casi siempre es "sí" y su quejido parece injustificado. 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?".
fuente
Flota el título a la izquierda, el botón flotante a la derecha y (aquí está la parte que nunca supe hasta hace poco): haz el contenedor de ambos
{overflow:hidden}
.Eso debería evitar el problema del índice z, de todos modos. Si no funciona y realmente necesita el soporte IE5, siga adelante y use la tabla.
fuente
overflow:hidden
.En CSS puro, un día una respuesta funcional será simplemente usar
"display:table-cell"
. Desafortunadamente, eso no funciona en los navegadores actuales de grado A, por lo que, para todo eso, también puede usar una tabla si solo desea lograr el mismo resultado de todos modos. Al menos estarás seguro de que funciona lo suficiente en el pasado.Honestamente, solo use una mesa si es más fácil. No dolerá.
Si la semántica y la accesibilidad del elemento de la tabla realmente le importan, hay un borrador de trabajo para hacer que su tabla no sea semántica:
http://www.w3.org/TR/wai-aria/#presentation
Creo que esto requiere un DTD especial más allá de XHTML 1.1, lo que agitaría todo el debate
text/html
frente a élapplication/xml
, así que no vayamos allí.Entonces, a su problema de CSS no resuelto ...
Para alinear verticalmente dos elementos en su centro: se puede hacer de diferentes maneras, con algún truco CSS obtuso.
Si puede ajustarse a las siguientes limitaciones, existe una forma relativamente sencilla:
Entonces puedes usar el posicionamiento absoluto con márgenes negativos:
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 utiliza la línea base de texto para alinear verticalmente las dos columnas como bloques en línea. El inconveniente aquí es que debe establecer anchos fijos para que las columnas completen el ancho desde el borde izquierdo. Debido a que necesitamos mantener los elementos bloqueados en una línea de base de texto, no podemos simplemente usar float: right para la segunda columna. (En cambio, tenemos que hacer que la primera columna sea lo suficientemente ancha para empujarla).
El HTML: Agregamos envoltorios .valign alrededor de cada columna. (Déles un nombre más "semántico" si le hace más feliz.) Estos deben mantenerse sin espacios en blanco entre ellos o, de lo contrario, 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 del texto del elemento de encabezado de grupo. Las diferentes alturas de cada bloque permanecerán centradas verticalmente y empujarán hacia afuera la altura de su contenedor. Los anchos de los elementos deben calcularse para ajustarse al ancho. Aquí, son 400 y 100, menos su relleno horizontal.Las correcciones de IE: Internet Explorer solo muestra el bloque en línea para los elementos en línea de forma nativa (por ejemplo, span, no div). Pero, si le damos el div hasLayout y luego lo mostramos en línea, se comportará como un bloque en línea. El ajuste del margen es para arreglar un espacio de 1px en la parte superior (intente agregar colores de fondo al título .group para ver).
fuente
Recomendaría no usar una tabla en este caso, porque no son datos tabulares; es puramente presentativo tener el botón ubicado en el extremo derecho. Esto es lo que haría para duplicar la estructura de su tabla (cambiar a un H # diferente para adaptarse a dónde se encuentra en la jerarquía de su sitio):
Si desea una verdadera alineación vertical en el medio (es decir, si el texto envuelve, el botón todavía está alineado en el medio con respecto a ambas líneas de texto), entonces necesita hacer una tabla o trabajar algo con
position: absolute
márgenes. Puede agregarposition: relative
a su menú desplegable (o más probablemente a su padre) para colocarlo en el mismo nivel de orden que los botones, lo que le permite subirlo por encima de ellos con el índice z, si se trata de eso.Tenga en cuenta que no necesita
width: 100%
en el div porque es un elemento a nivel de bloque yzoom: 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 extrañas si está apuntando a cosas un poco más específicamente, aunque es posible que necesite un div contenedor o span en el botón para facilitar el posicionamiento.fuente
zoom: 1
in.group-header
, que activa hasLayout y hace que IE 6 se comporte de la misma forma que si tuviera el elemento: after activo.Haz un doble flotador en un div y usa clearfix. http://www.webtoolkit.info/css-clearfix.html ¿Tiene alguna restricción de margen / relleno?
fuente
fuente
Elegí usar Flexbox porque facilitó mucho las cosas.
Básicamente, debe ir al padre de los niños que desea alinear y agregar
display:box
(con prefijo, por supuesto). Para hacer que se sienten a los lados, use justify-content . El espacio entre medio es lo correcto cuando tienes elementos que deben alinearse hasta el final, como en este caso (ver enlace) ...Luego, el problema de la alineación vertical. Como hice el padre de los dos elementos, desea alinear un Flexbox. Ahora es fácil de usar
align-items: center
.Luego agregué los estilos que deseaba antes, eliminé el flotador del título y el botón en el encabezado y agregué un relleno:
Ver demostración
fuente
Estoy de acuerdo en que realmente solo se deben usar tablas para datos tabulares, por la sencilla razón de que las tablas no se muestran hasta que se terminan de cargar (no importa 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:
La función del botón y cualquier detalle adicional se pueden diseñar desde esta forma básica. Disculpas por las malas etiquetas.
fuente