ฉันสร้างเกมไขปริศนา CSS ได้อย่างไร PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

ฉันสร้างเกมปริศนา CSS บริสุทธิ์ได้อย่างไร

ฉันเพิ่งค้นพบความสุขในการสร้างเกมที่ใช้ CSS เท่านั้น เป็นเรื่องที่น่าสนใจเสมอที่ HTML และ CSS สามารถจัดการกับตรรกะของเกมออนไลน์ทั้งหมดได้ ดังนั้นฉันจึงต้องลอง! เกมดังกล่าวมักจะใช้ Checkbox Hack แบบเก่า ซึ่งเรารวมสถานะที่ตรวจสอบแล้ว/ไม่ได้เลือกของอินพุต HTML เข้ากับ :checked คลาสหลอกใน CSS เราสร้างเวทย์มนตร์ได้มากมายด้วยชุดค่าผสมนั้น!

อันที่จริง ฉันท้าทายตัวเองให้สร้างเกมทั้งเกมโดยไม่มีช่องทำเครื่องหมาย ฉันไม่แน่ใจว่ามันจะเป็นไปได้หรือไม่ แต่มันแน่นอน และฉันจะแสดงให้คุณเห็นว่า

นอกจากเกมไขปริศนาเราจะเรียนในบทความนี้แล้ว คอลเลกชันของเกม CSS ล้วนๆส่วนใหญ่ไม่มี Checkbox Hack (นอกจากนี้ยังมี บน CodePen.)

ต้องการที่จะเล่นก่อนที่เราจะเริ่ม?

โดยส่วนตัวฉันชอบเล่นเกมในโหมดเต็มหน้าจอ แต่คุณสามารถเล่นได้ที่ด้านล่างหรือ เปิดตรงนี้.

เย็นใช่มั้ย? ฉันรู้ มันไม่ใช่เกมไขปริศนาที่ดีที่สุดที่คุณเคยเห็น™ แต่ก็ไม่ได้แย่สำหรับบางอย่างที่ใช้ CSS และ HTML เพียงไม่กี่บรรทัดเท่านั้น คุณสามารถปรับขนาดของตาราง เปลี่ยนจำนวนเซลล์เพื่อควบคุมระดับความยาก และใช้รูปภาพอะไรก็ได้ที่คุณต้องการ!

เราจะทำการรีเมคเดโมนั้นใหม่ด้วยกัน จากนั้นจึงเพิ่มประกายพิเศษเล็กน้อยในตอนท้ายเพื่อการเตะ

ฟังก์ชันลากและวาง

แม้ว่าโครงสร้างของตัวต่อจะค่อนข้างตรงไปตรงมากับ 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แต่เราจะเรียกใช้เอฟเฟกต์โฮเวอร์ก่อนที่มันจะเกิดขึ้น และรูปภาพจะอยู่ในกล่อง! ถ้าปล่อยนอกกรอบก็ไม่มีอะไรเกิดขึ้น

มีมุมแหลมเล็กน้อย: การคลิกที่ช่องว่างจะเป็นการย้ายรูปภาพและทำให้คุณลักษณะของเราหยุดชะงัก ปัจจุบัน, :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);
}

เรากำลังจะสร้างลูกกริดของเราจริงๆ — the <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 บริสุทธิ์ได้อย่างไร

หากคุณสังเกตดีๆ คุณจะสังเกตเห็นว่าเรามีรูปทรงตัวต่อที่แตกต่างกันเก้าแบบ: the สี่มุมที่ สี่ขอบและ หนึ่งสำหรับทุกสิ่งทุกอย่าง.

ตารางของชิ้นส่วนจิ๊กซอว์ที่ฉันทำในบทความอื่นที่ฉันอ้างถึงนั้นตรงไปตรงมากว่าเล็กน้อย:

เราสามารถใช้เทคนิคเดียวกับที่รวมมาสก์ 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 ค้นหาแนวตั้ง AI.
ฉันสร้างเกมปริศนา 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 ค้นหาแนวตั้ง AI.
ฉันสร้างเกมปริศนา 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 ค้นหาแนวตั้ง AI.
ฉันสร้างเกมปริศนา CSS บริสุทธิ์ได้อย่างไร

สาธิตขั้นสุดท้าย

นี่คือการสาธิตแบบเต็มอีกครั้ง หากคุณเปรียบเทียบกับเวอร์ชันแรก คุณจะเห็นโครงสร้างโค้ดเดียวกันในการสร้างกริดและคุณลักษณะการลากแล้ววาง รวมทั้งโค้ดสำหรับสร้างรูปร่าง

การปรับปรุงที่เป็นไปได้

บทความจบลงที่นี่ แต่เราสามารถปรับปรุงปริศนาของเราต่อไปด้วยคุณสมบัติเพิ่มเติม! แล้วตัวจับเวลาล่ะ? หรืออาจแสดงความยินดีเมื่อผู้เล่นไขปริศนาเสร็จ

ฉันอาจจะพิจารณาคุณสมบัติทั้งหมดเหล่านี้ในเวอร์ชันต่อๆ ไป ดังนั้น จับตาดู repo GitHub ของฉัน.

ตัดขึ้น

และ CSS ไม่ใช่ภาษาโปรแกรมพวกเขาพูด ฮา!

ฉันไม่ได้พยายามที่จะจุดประกาย #HotDrama บางอย่างด้วยสิ่งนั้น ฉันพูดอย่างนั้นเพราะเราทำเรื่องตรรกะที่ยุ่งยากจริงๆ และครอบคลุมคุณสมบัติและเทคนิค CSS มากมายไปพร้อมกัน เราเล่นกับ CSS Grid, ทรานซิชัน, มาสก์, การไล่ระดับสี, ตัวเลือก และคุณสมบัติพื้นหลัง ไม่ต้องพูดถึงเทคนิค Sass สองสามอย่างที่เราใช้เพื่อทำให้โค้ดของเราปรับเปลี่ยนได้ง่าย

เป้าหมายไม่ใช่เพื่อสร้างเกม แต่เพื่อสำรวจ CSS และค้นพบคุณสมบัติและลูกเล่นใหม่ที่คุณสามารถใช้ในโปรเจ็กต์อื่นได้ การสร้างเกมออนไลน์ใน CSS เป็นความท้าทายที่ผลักดันให้คุณสำรวจคุณสมบัติ CSS อย่างละเอียดและเรียนรู้วิธีใช้งาน นอกจากนี้ยังเป็นเรื่องสนุกมากมายที่เราได้เล่นอะไรเมื่อพูดและทำเสร็จแล้ว

ไม่ว่า CSS จะเป็นภาษาการเขียนโปรแกรมหรือไม่ก็ตาม ไม่ได้เปลี่ยนความจริงที่ว่าเราเรียนรู้อยู่เสมอโดยการสร้างและสร้างสรรค์สิ่งใหม่ๆ

ประทับเวลา:

เพิ่มเติมจาก เคล็ดลับ CSS