ทำไม HTML ถึงคิดว่า“ chucknorris” เป็นสี


7486

ทำไมสตริงสุ่มบางตัวจึงสร้างสีเมื่อป้อนเป็นสีพื้นหลังใน HTML ตัวอย่างเช่น:

<body bgcolor="chucknorris"> test </body>

... สร้างเอกสารที่มีพื้นหลังสีแดงในเบราว์เซอร์และแพลตฟอร์มทั้งหมด

ที่น่าสนใจในขณะที่chucknorriสร้างพื้นหลังสีแดงเช่นกันchucknorrสร้างพื้นหลังสีเหลือง

เกิดอะไรขึ้นที่นี่?


154
ขณะที่ทราบด้าน: bgcolorไม่ได้ใช้ ใช้ backgroundCSS
John Dvorak

47
ทำไมคุณเคยต้องการที่จะเพิ่มสีพื้นหลังที่เรียกว่าchucknorris? สีที่คาดหวังคืออะไร?
masterFly

106
@masterFly: ฉันไม่รู้ว่าทำไมความคิดเห็นของฉันภายใต้คำตอบที่ยอมรับถูกลบเพราะ "ไม่สร้างสรรค์" เพราะตอบคำถามของคุณได้ค่อนข้างดี: ผู้คนทดลองกับสิ่งเหล่านี้ตลอดเวลา ฉันอายุแค่ 10 ขวบเมื่อฉันค้นพบสิ่งนี้และสิ่งที่ฉันทำในเวลานั้นก็เกิดความยุ่งเหยิงและดูว่าเกิดอะไรขึ้น คุณไม่จำเป็นต้องมีเหตุผลเชิงปฏิบัติในการทำบางสิ่งบางอย่างโดยเฉพาะอย่างยิ่งสิ่งที่ไม่สำคัญเช่นนี้
BoltClock

49
และ<body bgcolor="stevensegal">การทดสอบ </body> เป็นสีเขียว
Chris

4
@BenDaggers โปรดอ่านประวัติการแก้ไขก่อนทำการแก้ไขอีกครั้ง CSSแท็กที่ไม่เกี่ยวข้องและได้ถูกลบออกไปเป็นครั้งที่สอง
การแข่งขัน Lightness ใน Orbit

คำตอบ:


6878

มันเป็นสิ่งที่หลงเหลือมาจากสมัย Netscape

ตัวเลขที่หายไปจะถือเป็น 0 [... ] ตัวเลขที่ไม่ถูกต้องนั้นถูกตีความเพียงแค่ 0 เช่นค่า # F0F0F0, F0F0F0, F0F0F, #FxFxFx และ FxFxFx เหมือนกันทั้งหมด

มันมาจากการโพสต์ในบล็อกพูดจาโผงผางเล็กน้อยเกี่ยวกับการแยกวิเคราะห์สีของ Microsoft Internet Explorerซึ่งครอบคลุมในรายละเอียดที่ดีรวมถึงความยาวที่แตกต่างกันของค่าสี ฯลฯ

หากเราใช้กฎนี้ในการโพสต์บล็อกเราจะได้รับสิ่งต่อไปนี้:

  1. แทนที่อักขระเลขฐานสิบหกที่ไม่ใช่ค่าทั้งหมดด้วย 0

    chucknorris becomes c00c0000000
  2. ใช้จำนวนตัวอักษรทั้งหมดหารด้วย 3 (11 -> 12)

    c00c 0000 0000
  3. แบ่งออกเป็นสามกลุ่มเท่า ๆ กันโดยแต่ละองค์ประกอบจะเป็นตัวแทนขององค์ประกอบสีที่สอดคล้องกันของสี RGB:

    RGB (c00c, 0000, 0000)
  4. ตัดอาร์กิวเมนต์แต่ละตัวจากด้านขวาลงไปที่อักขระสองตัว

ซึ่งให้ผลลัพธ์ดังต่อไปนี้:

RGB (c0, 00, 00) = #C00000 or RGB(192, 0, 0)

นี่คือตัวอย่างที่แสดงให้เห็นถึงbgcolorคุณสมบัติในการดำเนินการเพื่อสร้างแถบสี "น่าอัศจรรย์" นี้:

<table>
  <tr>
    <td bgcolor="chucknorris" cellpadding="8" width="100" align="center">chuck norris</td>
    <td bgcolor="mrt"         cellpadding="8" width="100" align="center" style="color:#ffffff">Mr T</td>
    <td bgcolor="ninjaturtle" cellpadding="8" width="100" align="center" style="color:#ffffff">ninjaturtle</td>
  </tr>
  <tr>
    <td bgcolor="sick"  cellpadding="8" width="100" align="center">sick</td>
    <td bgcolor="crap"  cellpadding="8" width="100" align="center">crap</td>
    <td bgcolor="grass" cellpadding="8" width="100" align="center">grass</td>
  </tr>
</table>

สิ่งนี้จะตอบอีกส่วนหนึ่งของคำถาม ทำไมจึงbgcolor="chucknorr"ผลิตสีเหลือง ถ้าเราใช้กฎสตริงคือ:

c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]

ซึ่งให้สีทองสีเหลืองอ่อน เมื่อสตริงเริ่มต้นด้วยอักขระ 9 ตัวเราจะเก็บค่า C ตัวที่สองในเวลานี้เพื่อให้ค่าสีสุดท้าย

ฉันพบสิ่งนี้ครั้งแรกเมื่อมีคนชี้ให้เห็นว่าคุณสามารถทำได้color="crap"และมันก็ออกมาสีน้ำตาล


174
โปรดทราบว่าแม้จะมีสิ่งที่โพสต์บล็อกกล่าวว่าเมื่อคุณได้รับการจัดการสาย 3 ถ่านคุณซ้ำตัวละครแต่ละตัวมากกว่า prepending 0. คือ0F6จะกลายเป็นไม่ได้#00FF66 #000F06
Aaron Dufour

634
@usr: HTML ถูกสร้างขึ้นโดยไม่สนใจอินพุตที่มีรูปแบบผิดพลาด)
Lily Ballard

59
คุณยังสามารถใช้สตริงแบบสุ่มของฉันเพื่อแปลงสี cssเพื่อให้ได้สีสำหรับสตริงที่ระบุ มันขึ้นอยู่กับ5 ขั้นตอนในการคำนวณสีสตริงโดยเจเรมี Goodell
TimPietrusky

15
โอกาสที่ซ่อนอยู่สำหรับความหมาย? คุณสามารถสร้างหน้าแสดงข้อผิดพลาดได้ด้วย: <body bgcolor=error><h1 style=text-align:center>Error: Not Found<h1></span>คุณสามารถเพิ่ม div ที่มีพื้นหลัง anothe หรืออะไรทำนองนั้นดังนั้นมันจึงไม่ใช่สิ่งที่น่าตกใจ
ธีรอท

32
@Theraot bgcolor="success"เป็นสีเขียวที่ดีเช่นกัน ที่น่าสนใจหนึ่งสามารถแทนที่สีเหล่านี้โดยใช้ CSS แอตทริบิวต์ / ตัวเลือกค่า (เช่นtd[bgcolor="chucknorris"] {...})
daiscog

970

ฉันขอโทษที่จะไม่เห็นด้วย แต่ตามกฎสำหรับการแยกค่าสีเดิมโพสต์โดย@Yuhong Bao , chucknorrisไม่ถือเอาไป#CC0000แต่จะ#C00000เป็นสีที่คล้ายกันมาก แต่แตกต่างกันเล็กน้อยของสีแดง ฉันใช้ส่วนเสริมของFirefox ColorZillaเพื่อตรวจสอบสิ่งนี้

กฎของรัฐ:

  • ทำให้สตริงมีความยาวที่เป็นทวีคูณของ 3 โดยการเพิ่ม 0: chucknorris0
  • แยกสตริงออกเป็น 3 สายยาวเท่ากัน: chuc knor ris0
  • ตัดปลายแต่ละสตริงเป็น 2 อักขระ: ch kn ri
  • เก็บค่า hex และเพิ่ม 0 ในกรณีที่จำเป็น: C0 00 00

ฉันสามารถใช้กฎเหล่านี้เพื่อตีความสตริงต่อไปนี้อย่างถูกต้อง:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

UPDATE: ผู้ตอบแบบดั้งเดิมที่กล่าวว่ามีสี#CC0000ตั้งแต่แก้ไขคำตอบของพวกเขาเพื่อรวมการแก้ไข


86
ฉันคิดออกฉันได้ตีความคำแนะนำในการแยกวิเคราะห์บางอย่างผิดพลาด: "adamlevine" = "ada00e000e" = "ada00e000e00" = "ada0 0e00 0e00" = "โฆษณา 0e 0e" - สมบูรณ์แบบ !!
Jeremy Goodell

17
ในกรณีที่คุณสนใจฉันโพสต์อัลกอริทึม 5 ขั้นตอนเป็น UPDATE สำหรับคำถามที่คล้ายกันที่ฉันโพสต์วันนี้: stackoverflow.com/questions/12939234/ …
Jeremy Goodell

18
@TimPietrusky สร้างเครื่องมือสาธิตสุดเหลือเชื่อสำหรับชื่อสีแบบสุ่ม เพียงไปที่นี่: randomstringtocsscolor.comและคลิกในกล่องและพิมพ์ "chucknorris"
Jeremy Goodell

4
adamlevineทำงานตามjsfiddle.net/LdyZ8/2959แต่ตัวอักษรจะถูกบล็อกada00e000eซึ่งจะถูกใส่เข้าไปada00e000e00แต่ลดลงไปเป็นค่า HEX 6 หลักทั่วไป[ad]a0[0e]00[0e]00ซึ่งทำให้ ad0e0e ซึ่งปรากฏใน jsfiddle ด้านบน
Martin

4
มันจะดีกว่าถ้าคำตอบนี้มีสถานะปัจจุบันเท่านั้น - ประวัติของคำตอบนี้และคำตอบอื่น ๆ อยู่ในบทสรุปการแก้ไขและ / หรือความคิดเห็น
Peter Mortensen

397

เบราว์เซอร์ส่วนใหญ่จะไม่สนใจค่าที่ไม่ใช่เลขฐานสิบหกในสตริงสีของคุณโดยแทนที่ตัวเลขที่ไม่ใช่ฐานสิบหกด้วยศูนย์

ChuCknorrisc00c0000000แปลว่า ณ จุดนี้เบราว์เซอร์จะแบ่งสายออกเป็นสามส่วนเท่ากันแสดงให้เห็นสีแดง , สีเขียวและสีฟ้าc00c 0000 0000ค่า: บิตพิเศษในแต่ละส่วนจะถูกละเว้นซึ่งทำให้ผลลัพธ์สุดท้าย#c00000ซึ่งเป็นสีแดง

หมายเหตุสิ่งนี้ใช้ไม่ได้กับการแยกวิเคราะห์สี CSS ซึ่งเป็นไปตามมาตรฐาน CSS

<p><font color='chucknorris'>Redish</font></p>
<p><font color='#c00000'>Same as above</font></p>
<p><span style="color: chucknorris">Black</span></p>


7
แม้ว่าฉันจะยังสงสัยอยู่ว่าทำไม OP ถึงพูดว่า "ใน CSS" และไม่ใช่ "ใน HTML" - บางทีพวกเขากำลังใช้เบราว์เซอร์ที่เก่ามากหรือเพิ่งเข้าใจผิด?
Mike Christensen

7
ดังนั้นเขาจึงมีแนวโน้มที่จะใช้bgcolorแอตทริบิวต์ที่เลิกใช้แล้ว
animuson

12
ตัวละครที่ไม่ถูกต้องจะไม่ถูกข้ามพวกเขาจะถือว่าเป็น 0
รักษา mods ของคุณได้ดี

5
(ในขณะที่คำตอบนี้อาจจะตาย) คำแนะนำ: ใช้สีพื้นหลังแทนเพื่อแสดงสี สีข้อความอยู่เหนือพื้นที่สัมพัทธ์ขนาดเล็กมันยากที่จะเห็นความแตกต่างหรือความคล้ายคลึงกัน
Zoe

304

เบราว์เซอร์พยายามแปลงchucknorrisเป็นรหัสสีฐานสิบหกเนื่องจากไม่ใช่ค่าที่ถูกต้อง

  1. ในchucknorrisทุกอย่างยกเว้นcไม่ใช่ค่าเลขฐานสิบหกที่ถูกต้อง
  2. c00c00000000ดังนั้นจึงได้รับการแปลง
  3. ซึ่งกลายเป็น# c00000เฉดสีแดง

ดูเหมือนว่าจะมีปัญหากับInternet ExplorerและOpera (12) เป็นหลักเนื่องจาก Chrome (31) และ Firefox (26) ไม่สนใจสิ่งนี้

ป.ล. ตัวเลขในวงเล็บเป็นเบราว์เซอร์เวอร์ชันที่ฉันทดสอบ

.

เมื่อทราบไฟแช็ก

Chuck Norris ไม่สอดคล้องกับมาตรฐานเว็บ มาตรฐานเว็บสอดคล้องกับเขา # BADA55


296

เหตุผลก็คือเบราว์เซอร์ไม่สามารถเข้าใจได้และลองแปลมันเป็นสิ่งที่เข้าใจได้และในกรณีนี้ให้เป็นค่าเลขฐานสิบหก! ...

chucknorrisเริ่มต้นด้วยcอักขระที่รู้จักเป็นเลขฐานสิบหกและแปลงอักขระที่ไม่รู้จักทั้งหมดให้เป็น0!

ดังนั้นchucknorrisในรูปแบบเลขฐานสิบหกจะกลายเป็น: c00c00000000ตัวละครอื่น ๆ ทั้งหมดกลายเป็น0และcยังคงอยู่ที่พวกเขาอยู่ ...

ตอนนี้พวกมันถูกหารด้วย 3 สำหรับRGB(แดง, เขียว, น้ำเงิน) ... R: c00c, G: 0000, B:0000...

แต่เรารู้ว่าเลขฐานสิบหกที่ถูกต้องสำหรับ RGB คือเพียง 2 ตัวอักษรหมายถึง R: c0, G: 00, B:00

ดังนั้นผลลัพธ์ที่แท้จริงคือ:

bgcolor="#c00000";

ฉันยังเพิ่มขั้นตอนในภาพเพื่อเป็นข้อมูลอ้างอิงสำหรับคุณ:

ทำไม HTML ถึงคิดว่า "chucknorris" เป็นสี


23
นี่เป็นคำอธิบายที่น่ารักมาก: D: D: D
Dominik Bucher

2
คำอธิบายที่ชาญฉลาดและเรียบง่ายมากและตรงไปตรงมามากที่ฉันเคยเจอ
Saurin Vala

1
คำตอบที่สร้างสรรค์มาก :)
ahmednawazbutt

222

ข้อมูลจำเพาะ WHATWG HTML มีอัลกอริทึมที่แน่นอนสำหรับการแยกวิเคราะห์ค่าสีดั้งเดิม: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

รหัส Netscape Classic ที่ใช้สำหรับการแยกสตริงสีเป็นโอเพ่นซอร์ส: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

ตัวอย่างเช่นสังเกตว่าอักขระแต่ละตัวถูกวิเคราะห์เป็นตัวเลขฐานสิบหกจากนั้นจะถูกเปลี่ยนเป็นจำนวนเต็ม 32 บิตโดยไม่ตรวจสอบว่ามีการล้นโดยไม่ต้องตรวจสอบล้นเฉพาะเลขฐานสิบหกแปดตัวเท่านั้นที่พอดีกับจำนวนเต็ม 32 บิตซึ่งเป็นเหตุผลที่พิจารณาเฉพาะอักขระ 8 ตัวสุดท้าย หลังจากแยกเลขฐานสิบหกเป็นจำนวนเต็ม 32 บิตพวกเขาจะถูกตัดทอนเป็นจำนวนเต็ม 8 บิตโดยแบ่งพวกเขาด้วย 16 จนกว่าพวกเขาจะพอดีกับ 8 บิตซึ่งเป็นเหตุผลที่ศูนย์นำจะถูกละเว้น

อัปเดต: รหัสนี้ไม่ตรงกับที่ระบุไว้ในข้อมูลจำเพาะ แต่ความแตกต่างเพียงอย่างเดียวคือมีโค้ดไม่กี่บรรทัด ฉันคิดว่ามันเป็นบรรทัดเหล่านี้ที่เพิ่มเข้ามา (ใน Netscape 4):

if (bytes_per_val > 4)
{
      bytes_per_val = 4;
}

ขอบคุณคุณแสดงให้ฉันเห็นว่าซอร์สโค้ดเก่าของ Netscape นั้นคืออะไร ... ทำไมจึงยากที่จะหา
kb1000

202

ตอบ:

  • เบราว์เซอร์จะพยายามแปลงchucknorrisให้เป็นค่าเลขฐานสิบหก
  • ตั้งแต่ cเป็นอักขระฐานสิบหกที่ใช้ได้เฉพาะในchucknorrisค่าจึงเปลี่ยนเป็น: c00c00000000( 0 สำหรับค่าทั้งหมดที่ไม่ถูกต้อง )
  • เบราว์เซอร์จะแบ่งผลลัพธ์ออกเป็น 3 กลุ่ม: Red = c00cgroupds: Green = 0000, Blue = 0000,
  • เนื่องจากค่าเลขฐานสิบหกที่ถูกต้องสำหรับพื้นหลัง html มีเพียง 2 หลักสำหรับแต่ละประเภทสี ( r , g , b ) ตัวเลข 2 หลักสุดท้ายจะถูกตัดออกจากแต่ละกลุ่มทำให้เหลือค่า rgb c00000ซึ่งเป็นสีอิฐแดง - แดง

22

chucknorrisเริ่มต้นด้วยcและเบราว์เซอร์อ่านมันเป็นค่าเลขฐานสิบหก

เนื่องจาก A, B, C, D, E และ F เป็นอักขระที่เป็นเลขฐานสิบหกตัวอักษรในเลขฐานสิบหก

เบราว์เซอร์แปลง chucknorrisเป็นค่าเลขฐานสิบหก, C00C00000000.

จากนั้นC00C00000000ค่าเลขฐานสิบหกจะถูกแปลงเป็นรูปแบบRGB (หารด้วย 3):

C00C00000000 => R:C00C, G:0000, B:0000

เบราว์เซอร์ต้องการเพียงตัวเลขสองหลักเพื่อระบุสี:

R:C00C, G:0000, B:0000=> R:C0, G:00, B:00=>C00000

ในที่สุดก็แสดง bgcolor = C00000ในเว็บเบราว์เซอร์

นี่คือตัวอย่างที่แสดงให้เห็น:

<table>
  <tr>
    <td bgcolor="chucknorris" cellpadding="10" width="150" align="center">chucknorris</td>
    <td bgcolor="c00c00000000" cellpadding="10" width="150" align="center">c00c00000000</td>
    <td bgcolor="c00000" cellpadding="10" width="150" align="center">c00000</td>
  </tr>
</table>


15

กฎสำหรับการแยกสีลักษณะมรดกเกี่ยวข้องกับขั้นตอนเพิ่มเติมนอกเหนือจากที่ระบุในคำตอบที่มีอยู่ ส่วนประกอบที่ถูกตัดส่วนที่ 2 หลักอธิบายไว้ดังนี้:

  1. ยกเลิกอักขระทั้งหมดยกเว้น 8 ตัวสุดท้าย
  2. ทิ้งศูนย์นำหน้าทีละตัวตราบใดที่องค์ประกอบทั้งหมดมีศูนย์นำหน้า
  3. ยกเลิกอักขระทั้งหมดยกเว้น 2 ตัวแรก

ตัวอย่างบางส่วน:

oooFoooFoooF
000F 000F 000F                <- replace, pad and chunk
0F 0F 0F                      <- leading zeros truncated
0F 0F 0F                      <- truncated to 2 characters from right

oooFooFFoFFF
000F 00FF 0FFF                <- replace, pad and chunk
00F 0FF FFF                   <- leading zeros truncated
00 0F FF                      <- truncated to 2 characters from right

ABCooooooABCooooooABCoooooo
ABC000000 ABC000000 ABC000000 <- replace, pad and chunk
BC000000 BC000000 BC000000    <- truncated to 8 characters from left
BC BC BC                      <- truncated to 2 characters from right

AoCooooooAoCooooooAoCoooooo
A0C000000 A0C000000 A0C000000 <- replace, pad and chunk
0C000000 0C000000 0C000000    <- truncated to 8 characters from left
C000000 C000000 C000000       <- leading zeros truncated
C0 C0 C0                      <- truncated to 2 characters from right

ด้านล่างเป็นการใช้อัลกอริทึมบางส่วน ไม่ได้จัดการข้อผิดพลาดหรือกรณีที่ผู้ใช้ป้อนสีที่ถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.