Evitando JavaScript usando selectores CSS

La semana pasada nos encontrábamos con un escenario muy simple, donde básicamente teníamos una imagen de perfil y era necesario mostrar posibles acciones sobre la misma cuando el usuario pasaba el ratón por encima. Si bien no es nada del otro mundo, esta situación puede poner al desarrollador en duda sobre cómo realizar esta tarea, e incluso al diseñador/maquetador de la plataforma. Después de mantener una conversación al respecto, las dos opciones posibles eran claras: Hacer uso de JavaScript para controlar el evento hover o bien utilizar CSS con el mismo fin. En este post veremos cómo es posible utilizar CSS, sin perjudicar el rendimento de nuestro sitio.

Utilizando JavaScript

<!DOCTYPE html>
<html>
<head>
	<style>
	#profile{
		min-height: 200px;
		width: 150px;
		background-color:DarkTurquoise;
	}
	#profile input{
		display: none;
	}
	</style>
</head>
<body>
	<div id="profile">
		<input type="button" value="Change image"/>
	</div>
	<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
	<script>
	$(function(){
		$("#profile").hover(function(){
			$(":input",$(this)).show();
		},
		function() {
			$(":input",$(this)).hide();
		});
	});
	</script>
</body>
</html>

Si bien el código es bastante sencillo, al implementar esta funcionalidad con JavaScript nos enfrentamos a lo siguiente (podéis comprobar su funcionamiento en este enlace):

  1. Haremos uso de una librería de terceros que nos facilite el trabajo, como por ejemplo JQuery.
  2. Si además hacemos buen uso de la separación de capas en nuestro front-end, tendremos otro archivo donde ubicaremos el script.
  3. Un tercer recurso dedicado a los estilos CSS.

Si vemos este ejemplo desde la perspectiva del rendimiento, estamos obligando a nuestra aplicación a solicitar diferentes recursos para llevar a cabo una simple acción, fácilmente alcanzable con CSS. Aunque este supuesto es muy sencillo ¿qué ocurriría si cada vez que implementamos una nueva funcionalidad pensamos de esta manera?

Utilizando selectores CSS

<!DOCTYPE html>
<html>
<head>
	<title>CSS Selector ></title>
	<style>
	#profile{
		min-height: 200px;
		width: 150px;
		background-color:DarkTurquoise;
	}
	#profile input[type="button"]{
		display: none;
	}
	#profile:hover > input[type="button"]{
		display: block;
	}
	</style>
</head>
<body>
	<div id="profile">
		<input type="button" value="Change image"/>
	</div>
</body>
</html>

En el ejemplo anterior, estamos haciendo uso de CSS para lograr el mismo cometido: utilizamos el selector :hover, seguido de > input[type=»button»]. Con ello le estamos diciendo que cuando el div con id profile esté en su estado hover (el ratón está posicionado encima) y dentro del mismo se encuentre un input del tipo button este último debe mostrarse. Si tuviéramos varias acciones (buttons) dentro de este div con el mismo estilo estaríamos cubiertos 🙂
Como podemos ver, no hay ningún script involucrado y el resultado es exactamente el mismo, evitando recursos adicionales. Podéis ver el resultado de este ejemplo aquí.

Selectores >, + y ~

Al margen del ejemplo, me gustaría mostrar este conjunto de selectores y cuál es su significado:

<!DOCTYPE html>
<html>
<head>
	<title>CSS Selector >, + and ~</title>
	<style>
		div#main p{
			font-weight: bold;
		}
		div#main > p{
			border: 1px solid black;
		}
		div + p{
			text-transform: uppercase;
		}
		div ~ p{
			background-color: red ;
		}
	</style>
</head>
<body>
	<div id="main">
		<p>Paragraph #1</p>
		<p>Paragraph #2</p>
		<div>
			<p>Child Paragraph</p>
		</div>
		<p>Paragraph #3</p>
		<p>Paragraph #4</p>
		<div>
			<p>Child Paragraph #1</p>
			<p>Child Paragraph #2</p>
		</div>
		<p>Paragraph #5</p>
		<p>Paragraph #6</p>
	</div>
</body>
</html>

Para poder entenderlo, en el código anterior se aplica un estilo para cada uno de los selectores:

  • div#main p: Todos aquellos párrafos dentro del div con id main quedarán en negrita.
  • div#main > p: Todos aquellos que sean hijos directos de main tendrán un borde negro de un píxel de grosor.
  • div + p: Aquella p que esté inmediatamente después de una etiqueta div tendrá su contenido en mayúsculas.
  • div ~ p:Todas aquellas p que estén después de un div, aunque no directamente después, tendrán un fondo de color rojo.

Para ver el resultado podéis comprobar el siguiente enlace.

Espero que sea de utilidad.

¡Saludos!