Un ejercicio de golf CSS | Programar Plus

El golf de código es un tipo de programación en el que el objetivo es realizar una tarea utilizando la menor cantidad de bytes posible. CSSBattle es un campo de batalla de golf de código donde los jugadores completan para recrear imágenes de destino usando CSS y HTML.

Las reglas son bastante simples:

  • Sin recursos externos (lo siento, no <img src="https://css-tricks.com/a-css-golfing-exercise/the-solution.png">)
  • Su solución debe renderizarse correctamente en Chrome (solo para fines de puntuación)

Esta puede ser una salida bastante divertida del trabajo inicial del día a día. No hay necesidad de preocuparse por la mantenibilidad, la semántica, el rendimiento, la accesibilidad o cualquier otra cosa que no sea hacer una cosa realmente pequeña y aún así renderizar correctamente.

Una solución de golf en 12 intentos

Este tipo de pensamiento es una desviación bastante dramática de cómo la mayoría de nosotros estamos escribiendo código de front-end para sitios de producción (¡espero!), Así que he estado publicando todas mis soluciones en GitHub en un esfuerzo por compartir algunos conocimientos y aprender de los demás. Como efecto secundario afortunado, también significa que hay un historial bastante detallado de mis envíos.

Aquí hay una cuenta de principio a fin de mis intentos del séptimo objetivo de CSSBattle, que se ve así:

CSSBattle Target # 7 – Sendero frondoso

El método de “centrar la cosa maldita”

Un primer enfoque razonable es simplemente pegar un elemento en el medio de la página, colocar una sombra de cuadro y un radio de borde en él, y llamarlo hecho. Si escribiéramos esto “de verdad”, podría verse así:

<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        background: #0B2429;
        margin: 0;
      }

      .leaf {
        width: 150px;
        height: 150px;
        border-radius: 67% 0;
        background: #F3AC3C;
        margin: 75px 0 75px 175px;
        box-shadow:
          -50px 0 #998235, 
          -100px 0 #1A4341
      }
    </style>
  </head>
  <body>
    <div class="leaf"/>
  </body>
</html>

¡Pero eso es 423 bytes! Eso no sirve para CSS golf, así que veamos qué podemos eliminar.

Intento 1: 144 bytes

<p style="margin:75 167;height:150;width:150;border-radius:67%0;box-shadow:-50px 0#998235,-100px 0#1A4341,0 0 0 5in #0B2429;background:#F3AC3C">

Aquí hay una versión para jugar al golf. Definitivamente hay algo raro aquí, no. <!DOCTYPE>, No <html>, No <body>, nada de nada. El navegador no los necesita (y, de hecho, los inserta por nosotros), por lo que ahorramos muchos bytes al omitirlos. Estamos usando <p> en vez de <div> ya que es más corto, y no cerramos la etiqueta en absoluto, ya que no es necesario para que las cosas se procesen.

El CSS en sí no es muy diferente, aparte del hecho de que hemos utilizado una enorme sombra de cuadro en lugar de un fondo en el elemento del cuerpo (“background”Es largo, por lo que evitarlo puede ser beneficioso). También está incluido en el elemento, ya que <style></style> la etiqueta cuesta bytes adicionales.

Puede que hayas notado que usamos 5in para la extensión en nuestra última sombra de caja. Jugar con unidades extrañas es una gran parte del golf CSS. En este caso, solo necesitamos la sombra para cubrir el lienzo de 400 × 300 y ‘5in‘(480px) es más corto que cualquier valor de píxel.

Intento 2: 141 bytes

<p style=margin:75+167;height:150;width:150;border-radius:67%0;box-shadow:-50px+0#998235,-100px+0#1A4341,0+0+0+5in#0B2429;background:#F3AC3C>

Esto introduce un truco de golf bastante importante: reemplazar los espacios con signos más nos permite eliminar las comillas alrededor de los atributos, ahorrando un par de bytes. No estoy totalmente seguro de por qué funciona esto. Alguien sugirió que puede estar relacionado con esta parte de la especificación HTML. Si tiene una mejor respuesta, ¡hágamelo saber!

Este intento también limpia un par de errores de espacios en blanco del último intento.

Intento 3: 126 bytes

<body bgcolor=F3AC3C style=margin:75+75+75+175;border-radius:67%+0;box-shadow:-50px+0#998235,-100px+0#1A4341,0+0+0+5in#0B2429>

Usando un <body> etiqueta en lugar de una <p> significa que:

  • Ya no gastamos bytes configurando la altura o el ancho en un párrafo
  • Tenemos acceso a bgcolor

bgcolor es un atributo obsoleto que aparece a menudo en las soluciones de golf CSS. Solo funciona con algunas etiquetas (<body> incluido) y hace dos grandes cosas:

  • Nos evita gastar bytes en “background:
  • Nos ahorra un byte al permitirnos omitir # en colores hexadecimales. Además, si un color termina en uno o dos ceros, podemos eliminarlos y aún se renderizará correctamente. Por ejemplo, FFFF00 es lo mismo que FFFF.

¡Hay una regresión de golf en esta iteración! ¿Puedes distinguirlo?

El método de “borde”

En este punto, había pasado bastantes horas jugando con este objetivo y me estaba quedando bastante atascado. Afortunadamente, CSSBattle tiene una comunidad amigable en Spectrum que está más que dispuesta a echar una mano.

En el momento, Praveen ocupé el puesto n. ° 1 con dos bytes menos de los que había logrado, así que pedí ayuda. Sugirió aprovechar tanto el <body> y <html> elementos para colocar todo mientras se utilizan bordes en lugar de un color de fondo.

Intento 4:126 bytes

<style>*{border-radius:67%+0;border:75px solid#F3AC3C;margin:0 50;box-shadow:-50px 0#998235,-100px 0#1A4341,0 0 0 5in#0B2429

Esta es una desviación bastante grande de nuestra última estrategia. Nuestra etiqueta corporal se ha ido y estamos usando <style>*{ para apuntar al <html> y <body> etiquetas que el navegador inserta por nosotros. La combinación de margin y border empuja nuestra forma exactamente donde debe estar, y el box-shadow sobre <body> cubre todo el exceso de cosas que verías al peinar <html>.

Esto fue difícil de asimilar para mí, pero Praveen hizo un diagrama que explica las cosas bastante bien. Aquí hay una versión bonita:

Márgenes y fronteras en <html> y <body>

a y b son el margen y el borde en <html>, y c es el margen en <body>. El margen derecho en <body> no hace nada ya que no hay espacio para empujar el <body> a la izquierda y ya tiene ancho cero.

Una vez aplicadas nuestras sombras de caja, b está cubierto y todo lo que queda es nuestra imagen de destino.

Sin embargo, todavía faltan algunas optimizaciones. Dorus van den Oord fue capaz de reducir el método de borde a 121 bytes, ofreciendo este consejo críptico:

pequeña pista para llegar a ese 121: ¿Qué pasaría si pudieras mover un elemento en un cuarto de…?

Intentos 5 y 6: 122 bytes

<style>*{border-radius:67%+0;border:75px solid#F3AC3C;margin:0 50;box-shadow:-53q 0#998235,-25vw 0#1A4341,0 0 0 5in#0B2429

Resulta que todo lo que necesitábamos era una unidad de la que casi nadie había oído hablar (q) (y el humilde vw). Tener que escribir “px”Rara vez es correcto en CSS golf, por lo que es algo a lo que hay que estar atento. Aquí, podemos reemplazar 100px con 25vw y 50px con 53q.

A q, o un cuarto de milímetro, es exactamente eso: 1/4 de milímetro, o poco menos de un píxel. El q La unidad es un elemento básico de CSS golf como uno de dos valores (el otro es %) que requieren solo un byte para expresarse. He combinado mi quinto y sexto intento aquí, ya que ambos fueron solo ajustes de unidad. ¡Sin embargo, todavía estamos a un byte de 121!

Intento 7: 121 bytes

<style>*{border-radius:67%0;border:75px solid#F3AC3C;margin:0 50;box-shadow:-53q 0#998235,-25vw 0#1A4341,0 0 0 5in#0B2429

Finalmente arreglamos esa regresión del tercer intento, gracias a una solicitud de extracción de Praveen. Un porcentaje no necesita un espacio entre él y los valores subsiguientes, por lo que podemos guardar un byte en nuestro border-radius. Este es un gran ejemplo de cómo compartir código puede ayudar a todos los involucrados. Había estado atascado en esto durante bastante tiempo.

El método del “margen funky”

¡Sin embargo, las fronteras no son el único enfoque! Ingresar Rasmus Fløemargen funky:

Obtuve 123 caracteres en el n. ° 7 usando box-shadow y un funky margin:75 400 75-150 🙂

Intento 8: 120 bytes

<body bgcolor=0B2429 style=border-radius:67%0;margin:75+400+75-150;box-shadow:86mm+0#F3AC3C,73mm+0#998235,75vh+0#1A4341>

Así es como funciona esto, como lo explica Rasmus:

el margen derecho positivo lo empuja fuera del lienzo hacia la izquierda, y el margen izquierdo negativo estira el elemento al ancho deseado 🙂

Aquí se extrae:

El método de “margen funky” de Rasmus Fløe

El margen derecho (b) empuja el <body> elemento completamente hacia la izquierda, contrayéndolo a un ancho cero. El margen izquierdo negativo (a) luego lo estira de nuevo a 150px de ancho (el ancho de la forma de la hoja), y luego nuestra sombra de caja (c) está lo suficientemente desplazado para estar a la vista. Esto es increíble porque ya no tenemos que lidiar con las sombras de los cuadros negativos para que todo se adapte correctamente a las capas.

También volvemos a bgcolor y aprovechar una bonita peculiaridad de los colores de fondo: porque <html> no tiene su propio color de fondo, hereda uno de <body>.

Intentos 9 y 10: 118 bytes

<body bgcolor=0B2429 style=border-radius:67%0;margin:75+340+75-90;box-shadow:7cm+0#F3AC3C,57mm+0#998235,55vh+0#1A4341>

Con un poco más de disputa de unidades, podemos ahorrarnos dos bytes más (apoyo a Dorus, que fue el primero en descubrir esta optimización). Ajustar los márgenes ahorra un dígito (150 se convierte en 90) y, como un bono dulce, podemos convertir 86mm a 70mm, que se convierte en 7cm. Nuevamente he combinado dos intentos aquí que fueron arreglos de unidades menores. (Me avergüenza decir que inicialmente me perdí mmcm conversión.)

Intento 11: 117 bytes

<body bgcolor=0B2429 style=border-radius:67%0;margin:75+85%75-90;box-shadow:7cm+0#F3AC3C,57mm+0#998235,55vh+0#1A4341>

Romain Deltour fue el primero en encontrar esta solución de 117 bytes. Cambiando 340 a 85% significa que podemos omitir un espacio después de uno de nuestros valores (como hicimos con border-radius), guardando otro byte.

Intento 12: 115 bytes

<body bgcolor=0B2429 style=border-radius:67%0;margin:75+85%75-90;box-shadow:7cm+0#F3AC3C,57mm+0#998235,55vh+0#7fd2>

Dos semanas completas después de la solución de 117 bytes de Romain, Viacheslav Popov pudo componer alfa a 115 bytes a través de códigos hexadecimales de 4 dígitos.

Realmente me encanta esto porque, no solo es muy inteligente, sino que mucha gente (incluido yo mismo) pensó que el objetivo ya se había optimizado por completo. La persistencia de Viacheslav provocó una nueva ronda de discusión y agregó otro CSS-Trick ™ a nuestro arsenal para futuros objetivos.

Intento 13:

Esto me parece muy cerca de lo óptimo, pero eso ciertamente no significa que no se pueda superar, ¿por qué no intentarlo? Existe una técnica anterior para comenzar, muchas personas dispuestas a ayudar e incluso algunas herramientas. Feliz golf ⛳️

(Visited 8 times, 1 visits today)