Ver Mensaje Individual
  #1 (permalink)  
Antiguo 16/06/2007, 07:53
Avatar de metacortex
metacortex
Viejo demente
 
Fecha de Ingreso: junio-2004
Ubicación: Caracas - Venezuela
Mensajes: 9.027
Antigüedad: 19 años, 10 meses
Puntos: 832
Tutorial: Esquinas redondeadas con puro CSS

Cómo hacer esquinas redondeadas sólo con CSS.

Hola panas. Hace poco estaba leyendo un libro sobre trucos CSS que por cierto se los recomiendo ampliamente (The CSS Anthology: 101 Essential Tips, Tricks & Hacks, por Rachel Andrew. Editorial SitePoint Pty. Ltd). Ahí se explicaba cómo hacer esquinas redondeadas, pero revisando el método que allí se utilizaba se me ocurrió uno más sencillo, utilizando una base similar a la descrita en dicho libro.

Como bien sabemos, es posible lograr el efecto de redondeado principalmente de 3 maneras: Con Javascript, muy bueno pero con los inconvenientes de la accesibilidad. Con el -moz-border-radius sería lo ideal, pero siendo parte de la futura recomendación CSS3, lamentablemente aún no es compatible con todo navegador. Y por último está el recurso de las imágenes, el cual viene siendo la opción más viable en el presente.

Con este procedimiento, el efecto que se obtiene es el mismo que el -moz-border-radius pero visible en todo navegador. Aparentemente el trabajo es tedioso, pero al final todo es cuestión de construir la primera esquina y de allí salen las demás. En el "experimento" trabajé con posicionamiento en lugar de márgenes y capas a lo largo (que era lo que decía el libro) y el resultado fue aún mejor, ya que -al igual que el moz-border- es posible hacer cambios de forma bastante sencilla, una vez el trabajo esté hecho. [ Ver ejemplo terminado ]

Para lo que sigue se utilizaron valores equivalentes a un -moz-border-radius con 16px.


1.- Lo primero que haremos será crear una capa con posicionamiento relativo que servirá de contenedor:

HTML:
Código:
<div id="contenedor"></div>
CSS:
Código:
#contenedor {
	width: 40%;
	position: relative;
	margin: 5ex auto;
	overflow: hidden;
}
Dentro de esta capa irá el cuadro con el borde principal. Podemos darle los estilos que deseemos sin temor alguno:

HTML:
Código:
<div id="contenedor">
	<div class="cuadro"></div>
</div>
CSS:
Código:
.cuadro {
	border: 1px solid #ccc;
	background: #fcfaf7;
	padding: 1em;
}
2.- Se preparan los estilos para las esquinas superior e Inferior. Como las mini-capas tendrán distintos anchos, los clasificamos en 1, 2 y 3px.

A las capas que conformarán las esquinas superiores les daremos un borde inferior y posicionamiento top: 0:
Código:
.sup-1px, .sup-2px, .sup-3px {
	border-bottom: solid #ccc;
	top: 0;
}
Hacemos exactamente lo contrario con la capa de las esquinas inferiores; les asignamos borde superior y posicionamiento bottom: 0:
Código:
.inf-1px, .inf-2px, .inf-3px {
	border-top: solid #ccc;
	bottom: 0;
}
Ahora el resto de los ajustes, los cuales abreviamos para no repetir estilos en cada clase:

Código:
.sup-1px, .sup-2px, .sup-3px,
.inf-1px, .inf-2px, .inf-3px {
	overflow: hidden;
	background: #fff;
	position: absolute;
}

.sup-1px, .inf-1px {
	width: 1px;
}

.sup-2px, .inf-2px {
	width: 2px;
}

.sup-3px, .inf-3px {
	width: 3px;
}
3.- Luego creamos los estilos que complementarán los datos necesarios para formar las mini-capas. La información es precisamente la que varía de un estilo en otro: posicionamiento horizontal, altura y ancho de borde.
Código:
.si-1 { height: 11px; left: 0; border-width: 0; }

.si-2 { height: 8px; left: 1px; border-width: 3px; }

.si-3 { height: 6px; left: 2px; border-width: 2px; }

.si-4 { height: 4px; left: 3px; border-width: 2px; }

.si-5 { height: 3px; left: 4px; border-width: 2px; }

.si-6 { height: 3px; left: 5px; border-width: 1px; }

.si-7 { height: 2px; left: 6px; border-width: 1px; }

.si-8 { height: 1px; left: 8px; border-width: 1px; }
Recordemos que más arriba les asignamos bordes a las capas, por lo cual se suma 1px a su altura total, es decir, si le asignamos valor de 10px en realidad mide 11 (10px + 1px de borde).

Combinamos entonces las clases .sup-[X]px y .si-[Nº] resultando algo así:
Código:
<div id="contenedor">
	<div class="cuadro">
	<!-- Comienza Esquina Izquierda -->
		<div class="sup-1px si-1"></div>
		<div class="sup-1px si-2"></div>
		<div class="sup-1px si-3"></div>
		<div class="sup-1px si-4"></div>
		<div class="sup-1px si-5"></div>
		<div class="sup-1px si-6"></div>
		<div class="sup-2px si-7"></div>
		<div class="sup-3px si-8"></div>
	</div>
</div>
Ya tenemos nuestra esquina izquierda. Ahora todo es cuestión de cambiarles las posiciones Left > Right para construir las demás (y por supuesto también cambiamos los nombres de los selectores por los que correspondan).

A las capas de las esquinas inferiores les asignaremos la clase .inf-[X]px, junto con las clases inferiores. [Ver CSS terminado ].

5.- Como siempre el aguafiestas de IE sale al baile con sus remedos de estándares y le arreglamos el bug que tiene con los píxeles de la derecha y abajo [ Ver CSS de IE ].

Para más detalles podemos ver el código fuente del ejemplo. Alguna información de estilos (si-x, sd-x, ii-x, id-x) presenta redundancia, pero no quise comprimirlo más, ya que como está se puede leer y comprender con más facilidad. Sin embargo, la carga en bytes no supera los 4.8kb entre HTML y CSS.

Beneficios de este método

Antes de los beneficios abordemos el punto en contra: 32 capas por cuadro no es precisamente algo del gusto de muchos. Quizás exista una forma más abreviada de hacer el trabajito. Particularmente estuve dándole vueltas al asunto y ese fue el menor número que pude conseguir (al principio lo había logrado con 16 capas por esquina = 64).

No obstante, los pro que le veo a esta técnica son varios. Podemos usar las mismas clases para múltiples cuadros y al mismo tiempo asignarles fácilmente colores y bordes distintos sin necesidad de tocar los bloques (si-x, sd-x, ii-x, id-x), a menos que deseemos distintos radios de curvatura. Podemos además insertar fondos (tipo cabezal), quedando éstos "embebidos" automáticamente por las curvas, ya que las mini-capas poseen, a su vez, fondos propios y tapan sus esquinas. Con el método del mencionado libro -al contrario- no era posible utilizar ese espacio superior e inferior, ya que las capas estaban dispuestas a lo largo y obstaculizaban el flujo del contenido.

Igualmente podemos disponer de todo el espacio del cuadro, ya que el posicionamiento absoluto no compromete la parte interna y los fondos de las mini-capas apuntan hacia afuera, no hacia adentro.

Es posible además agregar un fondo degradado a la "parte exterior" de las esquinas de arriba, en caso de que el fondo de la página tenga esa característica, si el márgen del contenedor tiene medidas absolutas y si el fondo es un repeat-y.

Finalmente también podemos enumerar entre los beneficios el hecho de haber resuelto con sólo CSS algo que usualmente depende de otros recursos =P.

Saludos.

Última edición por metacortex; 19/03/2008 a las 14:35 Razón: Modificar datos