Code-Golfing ist eine Art des Programmierens, bei der das Ziel darin besteht, eine Aufgabe mit möglichst wenigen Bytes zu erledigen. CSSBattle ist ein Code-Golfing-Schlachtfeld, auf dem Spieler darum kämpfen, Zielbilder mit CSS und HTML nachzubilden.
Die Regeln sind ziemlich einfach
- Keine externen Ressourcen (tut mir leid, kein
<img src="die-loesung.png">) - Ihre Lösung muss in Chrome korrekt gerendert werden (nur zu Bewertungszwecken)
Dies kann eine ziemlich unterhaltsame Abwechslung von der täglichen Front-End-Arbeit sein. Es besteht keine Notwendigkeit, sich um Wartbarkeit, Semantik, Leistung, Zugänglichkeit oder irgendetwas anderes zu kümmern, außer darum, eine Sache wirklich, wirklich klein zu machen und sie immer noch korrekt rendern zu lassen.
Eine Golf-Lösung in 12 Versuchen
Diese Art des Denkens weicht stark davon ab, wie die meisten von uns Front-End-Code für Produktionsseiten schreiben (hoffe ich!), daher poste ich alle meine Lösungen auf GitHub, um sowohl Wissen zu teilen als auch von anderen zu lernen. Als glücklicher Nebeneffekt bedeutet dies auch, dass es eine ziemlich detaillierte Geschichte meiner Einreichungen gibt.
Hier ist eine Schritt-für-Schritt-Anleitung meiner Versuche für das 7. Ziel von CSSBattle, das so aussieht
Die „zentrier das verdammte Ding“-Methode
Ein vernünftiger erster Ansatz ist, einfach ein Element in die Mitte der Seite zu stecken, ihm einen `box-shadow` und einen `border-radius` zu verpassen und es als erledigt zu betrachten. Wenn wir dies "in echt" schreiben würden, könnte es so aussehen
<!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>
Aber das sind 423 Bytes! Das reicht nicht für CSS-Golf, also sehen wir mal, was wir entfernen können.
Versuch 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">
Hier ist eine gegolfte Version. Hier passiert definitiv einiges Seltsames – kein <!DOCTYPE>, kein <html>, kein <body>, nichts davon. Der Browser braucht sie nicht (und fügt sie sogar für uns ein), also sparen wir viele Bytes, indem wir sie weglassen. Wir verwenden <p> anstelle von <div>, da es kürzer ist, und wir schließen das Tag überhaupt nicht, da es zum Rendern nicht erforderlich ist.
Das CSS selbst ist nicht viel anders, abgesehen von der Tatsache, dass wir einen riesigen `box-shadow` anstelle eines Hintergrunds auf dem `body`-Element verwendet haben ("background" ist lang, daher kann es von Vorteil sein, es zu vermeiden). Es ist auch im `inline`-Stil im Element, da ein <style></style>-Tag zusätzliche Bytes kostet.
Sie haben vielleicht bemerkt, dass wir `5in` für die Ausdehnung in unserem letzten `box-shadow` verwendet haben. Das Spielen mit seltsamen Einheiten ist ein *riesiger* Teil des CSS-Golfings. In diesem Fall müssen wir nur den Schatten über das 400×300 Pixel große Canvas legen, und '5in' (480px) ist kürzer als jeder Pixelwert.
Versuch 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>
Dies führt einen ziemlich wichtigen Golf-Trick ein: das Ersetzen von Leerzeichen durch Pluszeichen ermöglicht es uns, die Anführungszeichen um Attribute zu entfernen, was ein paar Bytes spart. Ich bin mir nicht ganz sicher, warum das funktioniert. Jemand schlug vor, dass es mit diesem Teil der HTML-Spezifikation zusammenhängen könnte. Wenn Sie eine bessere Antwort haben, lassen Sie es mich bitte wissen!
Dieser Versuch behebt auch ein paar Whitespace-Fehler aus dem letzten Versuch.
Versuch 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>
Die Verwendung eines <body>-Tags anstelle eines <p> bedeutet, dass
- Wir geben keine Bytes mehr für die Einstellung von Höhe oder Breite eines Absatzes aus
- Wir erhalten Zugriff auf
bgcolor
bgcolor ist ein veraltetes Attribut, das im CSS-Golf häufig vorkommt. Es funktioniert nur bei wenigen Tags (einschließlich <body>) und leistet zwei großartige Dinge:
- Es erspart uns das Ausgeben von Bytes für "
background:" - Es spart uns ein Byte, indem es uns erlaubt,
#in Hex-Farben wegzulassen. Zusätzlich, wenn eine Farbe auf eins oder zwei Nullen endet, können wir sie entfernen und sie wird trotzdem korrekt gerendert. Zum Beispiel istFFFF00dasselbe wieFFFF.
In dieser Iteration gibt es eine Golf-Regression! Können Sie sie erkennen?
Die "Border"-Methode
Zu diesem Zeitpunkt hatte ich schon einige Stunden damit verbracht, an diesem Ziel herumzubasteln und steckte ziemlich fest. Glücklicherweise hat CSSBattle eine freundliche Community auf Spectrum, die mehr als bereit ist, zu helfen.
Zu dieser Zeit hatte Praveen den Spitzenplatz mit zwei Bytes weniger als ich erreicht, also bat ich um Hilfe. Er schlug vor, sowohl die <body>- als auch die <html>-Elemente zu nutzen, um alles zu positionieren, während `borders` anstelle einer Hintergrundfarbe verwendet werden.
Versuch 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
Dies ist eine ziemlich drastische Abkehr von unserer letzten Strategie. Unser `body`-Tag ist weg und wir verwenden <style>*{, um die von uns eingefügten <html>- und <body>-Tags anzusprechen. Die Kombination aus margin und border verschiebt unsere Form genau dorthin, wo sie sein muss, und der box-shadow auf <body> deckt all das überflüssige Zeug ab, das man beim Styling von <html> sehen würde.
Das war für mich schwer zu verstehen, aber Praveen hat eine Grafik erstellt, die die Dinge ziemlich gut erklärt. Hier ist eine verschönerte Version
<html> und <body>a und b sind der Margin und Border von <html>, und c ist der Margin von <body>. Der rechte Margin von <body> hat keine Auswirkung, da kein Platz ist, um <body> nach links zu verschieben, und es bereits eine Breite von Null hat.
Sobald unsere `box-shadow` angewendet sind, wird b überdeckt und alles, was übrig bleibt, ist unser Zielbild.
Es fehlen jedoch noch einige Optimierungen. Dorus van den Oord konnte die Border-Methode auf schlanke 121 Bytes reduzieren und gab diesen kryptischen Ratschlag:
kleiner Hinweis, um auf diese 121 zu kommen: Was wäre, wenn Sie ein Element um ein Viertel eines ... verschieben könnten?
Versuche 5 und 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
Es stellt sich heraus, dass wir nur eine Einheit brauchen, von der kaum jemand je gehört hat (q) (und das bescheidene vw). "px" schreiben zu müssen, ist im CSS-Golf selten richtig, daher ist es etwas, worauf man achten sollte. Hier können wir 100px durch 25vw und 50px durch 53q ersetzen.
Ein q, oder Viertelmillimeter, ist genau das – 1/4 Millimeter, oder knapp unter einem Pixel. Die q-Einheit ist ein Grundpfeiler des CSS-Golfs, da sie zusammen mit einer weiteren Einheit (%) nur ein Byte zum Ausdrücken benötigt. Ich habe meine 5. und 6. Versuche hier zusammengefasst, da beide nur Einheitenanpassungen waren. Wir sind aber immer noch ein Byte von 121 entfernt!
Versuch 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
Wir haben die Regression aus dem dritten Versuch *endlich* behoben, dank eines Pull-Requests von Praveen. Ein Prozentzeichen benötigt keinen Leerraum zwischen sich und nachfolgenden Werten, so dass wir ein Byte bei unserem border-radius sparen können. Dies ist ein großartiges Beispiel dafür, wie das Teilen von Code allen Beteiligten helfen kann. Ich hing hier ziemlich lange fest.
Die "funky margin"-Methode
Aber Borders sind nicht der einzige Ansatz! Treten Sie ein in den funky Margin von Rasmus Fløe
Ich habe 123 Zeichen für #7 erreicht, indem ich
box-shadowund einen funkymargin:75 400 75-150verwendet habe :)
Versuch 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>
So funktioniert das, wie Rasmus es erklärt:
Ein positiver rechter Margin schiebt es vom Canvas nach links — und ein negativer linker Margin dehnt das Element auf die gewünschte Breite aus :)
Hier ist es gezeichnet
Der rechte Margin (b) schiebt das <body>-Element ganz nach links und kollabiert es auf eine Breite von Null. Der negative linke Margin (a) dehnt es dann auf 150px Breite zurück (die Breite der Blattform), und dann ist unser `box-shadow` (c) weit genug versetzt, um sichtbar zu sein. Das ist *großartig*, weil wir keine negativen `box-shadow` mehr verwenden müssen, um alles korrekt übereinander zu legen.
Wir verwenden auch wieder bgcolor und können uns einen schönen Eigenheit von Hintergrundfarben zunutze machen: Da <html> keine eigene Hintergrundfarbe hat, erbt es diese von <body>.
Versuche 9 und 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>
Mit ein wenig mehr Einheiten-Wrangling können wir uns zwei weitere Bytes sparen (Props an Dorus, der diese Optimierung als Erster entdeckt hat). Durch Anpassen der Margins sparen wir eine Ziffer (150 wird zu 90) und als schöner Bonus können wir 86mm in 70mm umwandeln, was zu 7cm wird. Ich habe hier wieder zwei Versuche kombiniert, die kleinere Einheitenkorrekturen waren. (Ich bin peinlich berührt zu sagen, dass ich die mm-cm-Umwandlung anfangs übersehen habe.)
Versuch 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 war der Erste, der diese 117-Byte-Lösung fand. Die Änderung von 340 in 85% ermöglicht es uns, ein Leerzeichen nach einem unserer Werte wegzulassen (genau wie bei border-radius), was ein weiteres Byte spart.
Versuch 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>
Zwei volle Wochen nach Romans 117-Byte-Lösung konnte Viacheslav Popov sich mit Alpha-Compositing durch 4-stellige Hex-Codes auf 115 Bytes hocharbeiten.
Das gefällt mir wirklich gut, denn – nicht nur ist es verdammt clever – sondern viele Leute (mich eingeschlossen) dachten, das Ziel sei bereits vollständig optimiert. Viacheslavs Beharrlichkeit löste sowohl eine neue Diskussionsrunde aus als auch fügte unserem Arsenal für zukünftige Ziele einen weiteren CSS-Trick™ hinzu.
Versuch 13: <115 Bytes?
Das scheint mir verdammt nah am Optimum zu sein, aber das bedeutet sicher nicht, dass es nicht übertroffen werden kann – warum nicht versuchen? Es gibt Vorarbeit für den Einstieg, viele Leute, die bereit sind zu helfen, und sogar einige Werkzeuge. Viel Spaß beim Golfen ⛳️
Danke für den Artikel, aber dieser Code wird vom Validator validator.w3.org nicht unterstützt.
Dieser Kommentar wird nicht vom zweiten Absatz des Artikels unterstützt