Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS PlatoBlockchain Data Intelligence. Κάθετη αναζήτηση. Ολα συμπεριλαμβάνονται.

Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS

Πρόσφατα ανακάλυψα τη χαρά της δημιουργίας παιχνιδιών μόνο για CSS. Είναι πάντα συναρπαστικό πώς η HTML και το CSS είναι ικανά να χειριστούν τη λογική ενός ολόκληρου διαδικτυακού παιχνιδιού, οπότε έπρεπε να το δοκιμάσω! Τέτοια παιχνίδια βασίζονται συνήθως στο ol' Checkbox Hack όπου συνδυάζουμε την επιλεγμένη/μη επιλεγμένη κατάσταση μιας εισαγωγής HTML με το :checked ψευδο-κλάση στο CSS. Μπορούμε να κάνουμε πολλά μαγικά με αυτόν τον συνδυασμό!

Στην πραγματικότητα, προκάλεσα τον εαυτό μου να φτιάξω ένα ολόκληρο παιχνίδι χωρίς Checkbox. Δεν ήμουν σίγουρος αν θα ήταν δυνατό, αλλά σίγουρα είναι, και θα σας δείξω πώς.

Εκτός από το παιχνίδι παζλ που θα μελετήσουμε σε αυτό το άρθρο, έχω φτιάξει μια συλλογή από καθαρά παιχνίδια CSS, τα περισσότερα από αυτά χωρίς το Checkbox Hack. (Είναι επίσης διαθέσιμα στο CodePen.)

Θέλετε να παίξουμε πριν ξεκινήσουμε;

Προσωπικά προτιμώ να παίζω το παιχνίδι σε λειτουργία πλήρους οθόνης, αλλά μπορείτε να το παίξετε παρακάτω ή άνοιξέ το εδώ.

Cool σωστά; Ξέρω ότι δεν είναι το καλύτερο παιχνίδι παζλ που είδες ποτέ, αλλά δεν είναι καθόλου κακό για κάτι που χρησιμοποιεί μόνο CSS και μερικές γραμμές HTML. Μπορείτε εύκολα να προσαρμόσετε το μέγεθος του πλέγματος, να αλλάξετε τον αριθμό των κελιών για να ελέγξετε το επίπεδο δυσκολίας και να χρησιμοποιήσετε όποια εικόνα θέλετε!

Θα ξαναφτιάξουμε αυτό το demo μαζί και, στη συνέχεια, θα βάλουμε λίγη επιπλέον λάμψη σε αυτό στο τέλος για μερικές κλωτσιές.

Η λειτουργία μεταφοράς και απόθεσης

Ενώ η δομή του παζλ είναι αρκετά απλή με το CSS Grid, η δυνατότητα μεταφοράς και απόθεσης κομματιών του παζλ είναι λίγο πιο δύσκολη. Έπρεπε να βασιστώ σε έναν συνδυασμό μεταβάσεων, εφέ αιώρησης και επιλογείς αδελφών για να το κάνω.

Εάν τοποθετήσετε το δείκτη του ποντικιού πάνω από το κενό πλαίσιο σε αυτήν την επίδειξη, η εικόνα μετακινείται μέσα σε αυτό και παραμένει εκεί ακόμα κι αν μετακινήσετε τον κέρσορα έξω από το πλαίσιο. Το κόλπο είναι να προσθέσετε μια μεγάλη διάρκεια μετάβασης και καθυστέρηση — τόσο μεγάλη που η εικόνα χρειάζεται πολύ χρόνο για να επιστρέψει στην αρχική της θέση.

img {
  transform: translate(200%);
  transition: 999s 999s; /* very slow move on mouseout */
}
.box:hover img {
  transform: translate(0);
  transition: 0s; /* instant move on hover */
}

Προσδιορίζοντας μόνο το transition-delay είναι αρκετό, αλλά η χρήση μεγάλων τιμών τόσο για την καθυστέρηση όσο και για τη διάρκεια μειώνει την πιθανότητα ο παίκτης να δει ποτέ την εικόνα να κινείται προς τα πίσω. Αν περιμένεις 999s + 999s — που είναι περίπου 30 λεπτά — τότε θα δείτε την εικόνα να κινείται. Αλλά δεν θα το κάνετε, σωστά; Θέλω να πω, κανείς δεν θα αργήσει τόσο πολύ μεταξύ των στροφών αν δεν φύγει από το παιχνίδι. Έτσι, θεωρώ ότι αυτό είναι ένα καλό κόλπο για εναλλαγή μεταξύ δύο καταστάσεων.

Παρατηρήσατε ότι η τοποθέτηση του ποντικιού στην εικόνα ενεργοποιεί επίσης τις αλλαγές; Αυτό συμβαίνει επειδή η εικόνα είναι μέρος του στοιχείου του κουτιού, κάτι που δεν είναι καλό για εμάς. Μπορούμε να το διορθώσουμε προσθέτοντας pointer-events: none στην εικόνα, αλλά δεν θα μπορούμε να τη σύρουμε αργότερα.

Αυτό σημαίνει ότι πρέπει να εισάγουμε ένα άλλο στοιχείο μέσα στο .box:

Αυτό το επιπλέον div (χρησιμοποιούμε μια κατηγορία .a) θα πάρει την ίδια περιοχή με την εικόνα (χάρη στο CSS Grid και grid-area: 1 / 1) και θα είναι το στοιχείο που ενεργοποιεί το φαινόμενο αιώρησης. Και εκεί είναι που παίζει ο επιλογέας αδερφού:

.a {
  grid-area: 1 / 1;
}
img {
  grid-area: 1 / 1;
  transform: translate(200%);
  transition: 999s 999s;
}
.a:hover + img {
  transform: translate(0);
  transition: 0s;
}

Περνώντας πάνω στο .a Το στοιχείο μετακινεί την εικόνα και αφού καταλαμβάνει όλο το χώρο μέσα στο κουτί, είναι σαν να αιωρούμαστε πάνω από το κουτί! Η αιώρηση της εικόνας δεν είναι πλέον πρόβλημα!

Ας σύρουμε και αποθέτουμε την εικόνα μας μέσα στο πλαίσιο και ας δούμε το αποτέλεσμα:

Το είδες αυτό? Αρχικά πιάνετε την εικόνα και τη μεταφέρετε στο κουτί, τίποτα το φανταχτερό. Αλλά μόλις απελευθερώσετε την εικόνα, ενεργοποιείτε το εφέ αιώρησης που μετακινεί την εικόνα και, στη συνέχεια, προσομοιώνουμε μια δυνατότητα μεταφοράς και απόθεσης. Εάν αφήσετε το ποντίκι έξω από το κουτί, δεν θα συμβεί τίποτα.

Χμμ, η προσομοίωση σας δεν είναι τέλεια γιατί μπορούμε επίσης να τοποθετήσουμε το κουτί και να έχουμε το ίδιο αποτέλεσμα.

Είναι αλήθεια και θα το διορθώσουμε. Πρέπει να απενεργοποιήσουμε το εφέ αιώρησης και να το επιτρέψουμε μόνο εάν απελευθερώσουμε την εικόνα μέσα στο πλαίσιο. Θα παίξουμε με τη διάστασή μας .a στοιχείο για να συμβεί αυτό.

Τώρα, η τοποθέτηση του πλαισίου δεν κάνει τίποτα. Αλλά αν αρχίσετε να σέρνετε την εικόνα, το .a εμφανίζεται το στοιχείο και μόλις απελευθερωθεί μέσα στο πλαίσιο, μπορούμε να ενεργοποιήσουμε το εφέ αιώρησης και να μετακινήσουμε την εικόνα.

Ας αναλύσουμε τον κώδικα:

.a {
  width: 0%;
  transition: 0s .2s; /* add a small delay to make sure we catch the hover effect */
}
.box:active .a { /* on :active increase the width */
  width: 100%;
  transition: 0s; /* instant change */
}
img {
  transform: translate(200%);
  transition: 999s 999s;
}
.a:hover + img {
  transform: translate(0);
  transition: 0s;
}

Κάνοντας κλικ στην εικόνα ενεργοποιείται το :active ψευδο-τάξη που κάνει το .a στοιχείο πλήρους πλάτους (αρχικά ισούται με 0). Η ενεργή κατάσταση θα παραμείνει ενεργός μέχρι να απελευθερώσουμε την εικόνα. Αν απελευθερώσουμε την εικόνα μέσα στο κουτί, το .a στοιχείο επιστρέφει στο width: 0, αλλά θα ενεργοποιήσουμε το εφέ hover πριν συμβεί και η εικόνα θα πέσει μέσα στο κουτί! Εάν το αφήσετε έξω από το κουτί, δεν συμβαίνει τίποτα.

Υπάρχει μια μικρή ιδιορρυθμία: κάνοντας κλικ στο κενό πλαίσιο μετακινείται επίσης η εικόνα και σπάει το χαρακτηριστικό μας. Επί του παρόντος, :active συνδέεται με το .box στοιχείο, οπότε κάνοντας κλικ σε αυτό ή σε οποιοδήποτε από τα παιδιά του θα το ενεργοποιήσετε. και κάνοντας αυτό, καταλήγουμε να δείχνουμε το .a στοιχείο και ενεργοποίηση του φαινομένου αιώρησης.

Μπορούμε να το διορθώσουμε παίζοντας με pointer-events. Μας επιτρέπει να απενεργοποιήσουμε οποιαδήποτε αλληλεπίδραση με το .box διατηρώντας παράλληλα τις αλληλεπιδράσεις με τα στοιχεία του παιδιού.

.box {
  pointer-events: none;
}
.box * {
  pointer-events: initial;
}

Τώρα Η δυνατότητα μεταφοράς και απόθεσης είναι τέλεια. Εκτός αν μπορείτε να βρείτε πώς να το χακάρετε, ο μόνος τρόπος για να μετακινήσετε την εικόνα είναι να τη σύρετε και να την αποθέσετε μέσα στο κουτί.

Χτίζοντας το πλέγμα του παζλ

Η συναρμολόγηση του παζλ θα είναι εύκολη σε σύγκριση με αυτό που μόλις κάναμε για τη δυνατότητα μεταφοράς και απόθεσης. Θα βασιστούμε σε κόλπα πλέγματος CSS και φόντου για να δημιουργήσουμε το παζλ.

Εδώ είναι το πλέγμα μας, γραμμένο σε Pug για ευκολία:

- let n = 4; /* number of columns/rows */
- let image = "https://picsum.photos/id/1015/800/800";

g(style=`--i:url(${image})`)
  - for(let i = 0; i < n*n; i++)
    z
      a
      b(draggable="true") 

Ο κώδικας μπορεί να φαίνεται περίεργος, αλλά μεταγλωττίζεται σε απλό HTML:

<g style="--i: url(https://picsum.photos/id/1015/800/800)">
 <z>
   <a></a>
   <b draggable="true"></b>
 </z>
 <z>
   <a></a>
   <b draggable="true"></b>
 </z>
 <z>
   <a></a>
   <b draggable="true"></b>
 </z>
  <!-- etc. -->
</g>

Βάζω στοίχημα ότι αναρωτιέστε τι συμβαίνει με αυτές τις ετικέτες. Κανένα από αυτά τα στοιχεία δεν έχει κάποιο ιδιαίτερο νόημα — απλώς βρίσκω ότι ο κώδικας είναι πολύ πιο εύκολο να γραφτεί χρησιμοποιώντας <z> από ένα σωρό <div class="z"> ή οτιδήποτε.

Έτσι τα έχω χαρτογραφήσει:

  • <g> είναι το πλέγμα μας που περιέχει N*N <z> στοιχεία.
  • <z> αντιπροσωπεύει τα στοιχεία του πλέγματος μας. Παίζει το ρόλο του .box στοιχείο που είδαμε στην προηγούμενη ενότητα.
  • <a> ενεργοποιεί το φαινόμενο αιώρησης.
  • <b> αντιπροσωπεύει ένα μέρος της εικόνας μας. Εφαρμόζουμε το draggable χαρακτηριστικό σε αυτό επειδή δεν μπορεί να συρθεί από προεπιλογή.

Εντάξει, ας καταχωρήσουμε το κοντέινερ πλέγματος μας <g>. Αυτό είναι σε Sass αντί για CSS:

$n : 4; /* number of columns/rows */

g {
  --s: 300px; /* size of the puzzle */

  display: grid;
  max-width: var(--s);
  border: 1px solid;
  margin: auto;
  grid-template-columns: repeat($n, 1fr);
}

Στην πραγματικότητα πρόκειται να κάνουμε το πλέγμα μας τα παιδιά μας — το <z> στοιχεία — πλέγματα επίσης και έχουν και τα δύο <a> και <b> στην ίδια περιοχή πλέγματος:

z {
  aspect-ratio: 1;
  display: grid;
  outline: 1px dashed;
}
a {
  grid-area: 1/1;
}
b {
  grid-area: 1/1;
}

Όπως μπορείτε να δείτε, τίποτα το φανταχτερό — δημιουργήσαμε ένα πλέγμα με συγκεκριμένο μέγεθος. Το υπόλοιπο CSS που χρειαζόμαστε είναι για τη δυνατότητα μεταφοράς και απόθεσης, η οποία απαιτεί να τοποθετούμε τυχαία τα κομμάτια γύρω από τον πίνακα. Θα απευθυνθώ στη Sass για αυτό, και πάλι για την ευκολία να μπορώ να περάσω και να διαμορφώσω όλα τα κομμάτια του παζλ με μια λειτουργία:

b {
  background: var(--i) 0/var(--s) var(--s);
}

@for $i from 1 to ($n * $n + 1) {
  $r: (random(180));
  $x: (($i - 1)%$n);
  $y: floor(($i - 0.001) / $n);
  z:nth-of-type(#{$i}) b{
    background-position: ($x / ($n - 1)) * 100% ($y / ($n - 1)) * 100%;
    transform: 
      translate((($n - 1) / 2 - $x) * 100%, (($n - 1)/2 - $y) * 100%) 
      rotate($r * 1deg) 
      translate((random(100)*1% + ($n - 1) * 100%)) 
      rotate((random(20) - 10 - $r) * 1deg)
   }
}

Ίσως έχετε παρατηρήσει ότι χρησιμοποιώ το Sass random() λειτουργία. Έτσι παίρνουμε τις τυχαιοποιημένες θέσεις για τα κομμάτια του παζλ. Να θυμάστε ότι θα το κάνουμε απενεργοποίηση αυτή τη θέση όταν αιωρείται πάνω από το <a> στοιχείο μετά από μεταφορά και απόθεση το αντίστοιχο <b> στοιχείο μέσα στο κελί του πλέγματος.

z a:hover ~ b {
  transform: translate(0);
  transition: 0s;
}

Στον ίδιο βρόχο, ορίζω επίσης τη διαμόρφωση φόντου για κάθε κομμάτι του παζλ. Όλα θα μοιράζονται λογικά την ίδια εικόνα με το φόντο και το μέγεθός του θα πρέπει να είναι ίσο με το μέγεθος ολόκληρου του πλέγματος (που ορίζεται με το --s μεταβλητός). Χρησιμοποιώντας το ίδιο background-image και μερικά μαθηματικά, ενημερώνουμε το background-position να δείχνει μόνο ένα κομμάτι της εικόνας.

Αυτό είναι! Το παιχνίδι παζλ μας μόνο για CSS έχει τελειώσει τεχνικά!

Αλλά μπορούμε πάντα να τα καταφέρουμε καλύτερα, σωστά; σου έδειξα πώς να φτιάξετε ένα πλέγμα από σχήματα κομματιών παζλ σε άλλο άρθρο. Ας πάρουμε την ίδια ιδέα και ας την εφαρμόσουμε εδώ, σωστά;

Σχήματα κομματιών παζλ

Εδώ είναι το νέο μας παιχνίδι παζλ. Ίδια λειτουργικότητα αλλά με πιο ρεαλιστικά σχήματα!

Αυτή είναι μια απεικόνιση των σχημάτων στο πλέγμα:

Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS

Αν κοιτάξετε προσεκτικά, θα παρατηρήσετε ότι έχουμε εννέα διαφορετικά σχήματα παζλ: το τέσσερις γωνίες, τη τέσσερις άκρες, να ένα για όλα τα άλλα.

Το πλέγμα των κομματιών του παζλ που έφτιαξα στο άλλο άρθρο στο οποίο αναφέρθηκα είναι λίγο πιο απλό:

Μπορούμε να χρησιμοποιήσουμε την ίδια τεχνική που συνδυάζει μάσκες CSS και ντεγκραντέ για να δημιουργήσουμε τα διαφορετικά σχήματα. Σε περίπτωση που δεν είστε εξοικειωμένοι με mask και κλίσεις, συνιστώ ανεπιφύλακτα να ελέγξετε αυτή η απλοποιημένη περίπτωση για να κατανοήσετε καλύτερα την τεχνική πριν προχωρήσετε στο επόμενο μέρος.

Αρχικά, πρέπει να χρησιμοποιήσουμε συγκεκριμένους επιλογείς για να στοχεύσουμε κάθε ομάδα στοιχείων που μοιράζεται το ίδιο σχήμα. Έχουμε εννέα ομάδες, επομένως θα χρησιμοποιήσουμε οκτώ επιλογείς, συν έναν προεπιλεγμένο επιλογέα που τους επιλέγει όλους.

z  /* 0 */

z:first-child  /* 1 */

z:nth-child(-n + 4):not(:first-child) /* 2 */

z:nth-child(5) /* 3 */

z:nth-child(5n + 1):not(:first-child):not(:nth-last-child(5)) /* 4 */

z:nth-last-child(5)  /* 5 */

z:nth-child(5n):not(:nth-child(5)):not(:last-child) /* 6 */

z:last-child /* 7 */

z:nth-last-child(-n + 4):not(:last-child) /* 8 */

Ακολουθεί ένα σχήμα που δείχνει πώς αυτό χαρτογραφείται στο πλέγμα μας:

Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS PlatoBlockchain Data Intelligence. Κάθετη αναζήτηση. Ολα συμπεριλαμβάνονται.
Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS

Τώρα ας ασχοληθούμε με τα σχήματα. Ας εστιάσουμε στην εκμάθηση μόνο ενός ή δύο από τα σχήματα, επειδή όλα χρησιμοποιούν την ίδια τεχνική — και με αυτόν τον τρόπο, έχετε κάποια εργασία για να συνεχίσετε να μαθαίνετε!

Για τα κομμάτια του παζλ στο κέντρο του πλέγματος, 0:

mask: 
  radial-gradient(var(--r) at calc(50% - var(--r) / 2) 0, #0000 98%, #000) var(--r)  
    0 / 100% var(--r) no-repeat,
  radial-gradient(var(--r) at calc(100% - var(--r)) calc(50% - var(--r) / 2), #0000 98%, #000) 
    var(--r) 50% / 100% calc(100% - 2 * var(--r)) no-repeat,
  radial-gradient(var(--r) at var(--r) calc(50% - var(--r) / 2), #000 98%, #0000),
  radial-gradient(var(--r) at calc(50% + var(--r) / 2) calc(100% - var(--r)), #000 98%, #0000);

Ο κώδικας μπορεί να φαίνεται περίπλοκος, αλλά ας εστιάσουμε σε μια κλίση κάθε φορά για να δούμε τι συμβαίνει:

Δύο διαβαθμίσεις δημιουργούν δύο κύκλους (σημειώνονται με πράσινο και μωβ στην επίδειξη) και δύο άλλες διαβαθμίσεις δημιουργούν τις υποδοχές με τις οποίες συνδέονται τα άλλα κομμάτια (αυτή που σημειώνεται με μπλε γεμίζει το μεγαλύτερο μέρος του σχήματος ενώ αυτή που σημειώνεται με κόκκινο γεμίζει το επάνω τμήμα). Μια μεταβλητή CSS, --r, ορίζει την ακτίνα των κυκλικών σχημάτων.

Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS PlatoBlockchain Data Intelligence. Κάθετη αναζήτηση. Ολα συμπεριλαμβάνονται.
Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS

Το σχήμα των κομματιών του παζλ στο κέντρο (σημειωμένο 0 στην εικόνα) είναι το πιο δύσκολο να κατασκευαστεί καθώς χρησιμοποιεί τέσσερις κλίσεις και τέσσερις καμπυλότητες. Όλα τα άλλα κομμάτια ταχυδακτυλουργούν λιγότερες κλίσεις.

Για παράδειγμα, τα κομμάτια του παζλ κατά μήκος της επάνω άκρης του παζλ (σημειωμένα 2 στην εικόνα) χρησιμοποιεί τρεις διαβαθμίσεις αντί για τέσσερις:

mask: 
  radial-gradient(var(--r) at calc(100% - var(--r)) calc(50% + var(--r) / 2), #0000 98%, #000) var(--r) calc(-1 * var(--r)) no-repeat,
  radial-gradient(var(--r) at var(--r) calc(50% - var(--r) / 2), #000 98%, #0000),
  radial-gradient(var(--r) at calc(50% + var(--r) / 2) calc(100% - var(--r)), #000 98%, #0000);

Αφαιρέσαμε την πρώτη (πάνω) κλίση και προσαρμόσαμε τις τιμές της δεύτερης διαβάθμισης ώστε να καλύπτει τον χώρο που μένει πίσω. Δεν θα παρατηρήσετε μεγάλη διαφορά στον κώδικα αν συγκρίνετε τα δύο παραδείγματα. Θα πρέπει να σημειωθεί ότι μπορούμε να βρούμε διαφορετικές διαμορφώσεις φόντου για να δημιουργήσουμε το ίδιο σχήμα. Αν ξεκινήσετε να παίζετε με ντεγκραντέ, σίγουρα θα καταλήξετε σε κάτι διαφορετικό από αυτό που έκανα εγώ. Μπορείτε ακόμη να γράψετε κάτι πιο συνοπτικό — αν ναι, μοιραστείτε το στα σχόλια!

Εκτός από τη δημιουργία των σχημάτων, θα διαπιστώσετε επίσης ότι αυξάνω το πλάτος ή/και το ύψος των στοιχείων όπως παρακάτω:

height: calc(100% + var(--r));
width: calc(100% + var(--r));

Τα κομμάτια του παζλ πρέπει να ξεχειλίσουν το κελί του πλέγματος τους για να συνδεθούν.

Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS PlatoBlockchain Data Intelligence. Κάθετη αναζήτηση. Ολα συμπεριλαμβάνονται.
Πώς έφτιαξα ένα καθαρό παιχνίδι παζλ CSS

Τελικό demo

Εδώ είναι πάλι το πλήρες demo. Εάν το συγκρίνετε με την πρώτη έκδοση, θα δείτε την ίδια δομή κώδικα για τη δημιουργία του πλέγματος και της δυνατότητας μεταφοράς και απόθεσης, συν τον κώδικα για τη δημιουργία των σχημάτων.

Πιθανές βελτιώσεις

Το άρθρο τελειώνει εδώ, αλλά θα μπορούσαμε να συνεχίσουμε να βελτιώνουμε το παζλ μας με ακόμα περισσότερες δυνατότητες! Τι θα λέγατε για ένα χρονόμετρο; Ή ίσως κάποιου είδους συγχαρητήρια όταν ο παίκτης τελειώσει το παζλ;

Μπορεί να εξετάσω όλα αυτά τα χαρακτηριστικά σε μια μελλοντική έκδοση, έτσι να παρακολουθείτε το αποθετήριο GitHub μου.

Ολοκληρώνοντας

Και Η CSS δεν είναι γλώσσα προγραμματισμού, λένε. Χα!

Δεν προσπαθώ να πυροδοτήσω κάποιο #HotDrama με αυτό. Το λέω γιατί κάναμε μερικά πολύ δύσκολα λογικά πράγματα και καλύψαμε πολλές ιδιότητες και τεχνικές CSS στην πορεία. Παίξαμε με το Πλέγμα CSS, τις μεταβάσεις, τη κάλυψη, τις διαβαθμίσεις, τους επιλογείς και τις ιδιότητες φόντου. Για να μην αναφέρουμε τα λίγα κόλπα Sass που χρησιμοποιήσαμε για να κάνουμε τον κώδικά μας εύκολο στην προσαρμογή.

Ο στόχος δεν ήταν να φτιάξετε το παιχνίδι, αλλά να εξερευνήσετε το CSS και να ανακαλύψετε νέες ιδιότητες και κόλπα που μπορείτε να χρησιμοποιήσετε σε άλλα έργα. Η δημιουργία ενός διαδικτυακού παιχνιδιού σε CSS είναι μια πρόκληση που σας ωθεί να εξερευνήσετε τις λειτουργίες CSS με μεγάλη λεπτομέρεια και να μάθετε πώς να τις χρησιμοποιείτε. Επιπλέον, είναι απλά πολύ διασκεδαστικό να παίζουμε με κάτι όταν όλα λέγονται και γίνονται.

Είτε η CSS είναι γλώσσα προγραμματισμού είτε όχι, δεν αλλάζει το γεγονός ότι πάντα μαθαίνουμε δημιουργώντας και δημιουργώντας καινοτόμα πράγματα.

Σφραγίδα ώρας:

Περισσότερα από Κόλπα CSS