การวาง div ในสมอถูกต้องหรือไม่?


530

ฉันได้ยินมาว่าการวางองค์ประกอบบล็อกไว้ในองค์ประกอบอินไลน์เป็นบาป HTML:

<a href="http://www.mydomain.com"><div>
What we have here is a problem. 
You see, an anchor element is an inline element,
and the div element is a block level element.
</div></a>

แต่ถ้าคุณใส่สมอเรือนอกdisplay:blockในสไตล์ชีตล่ะ? มันยังคงผิดหรือเปล่า? ข้อมูลจำเพาะ HTML 4.01 สำหรับองค์ประกอบระดับบล็อกและอินไลน์ดูเหมือนจะเป็นเช่นนั้น:

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

ไม่มีใครมีเคล็ดลับเพิ่มเติมเกี่ยวกับปัญหานี้หรือไม่?


3
ดูเพิ่มเติม: stackoverflow.com/questions/1091739/html-div-in-link-problem
DisgruntledGoat

@DisgruntledGoat - ขอบคุณสำหรับการเชื่อมโยง - หวังว่าฉันไม่เคยเห็นว่าไม่ช้าก็เร็ว :-)
ทอม

องค์ประกอบจุดยึดและ \ หรือลิงก์คือตัวควบคุมอัตโนมัติของเบราว์เซอร์ ดังนั้นจึงมีการแสดงผลและพฤติกรรมที่เบราว์เซอร์กำหนดไว้ล่วงหน้า ในการห่อองค์ประกอบ html ธรรมดาของแท้: div ภายในช่วงอย่างไรก็ตามเป็นบาป เหตุผลที่อยู่เบื้องหลังความจริงที่ว่าแท็กไม่ได้เพิ่มพฤติกรรมระดับใด ๆ เป็นความต้องการในการทำเครื่องหมายส่วนของข้อความโดยไม่รบกวนกระแสเอกสารไม่ได้เพราะพวกเขามีความหมายที่จะเป็นองค์ประกอบแบบอินไลน์ จาก POV นั้น A คือแท็กที่ไม่ทำอะไรเลย การดำรงอยู่ของมันอยู่นอกเหนือปัญหาและไม่ใช่ความบาป แต่อาจนำไปสู่รหัสความอัปลักษณ์และ \ หรือความกำกวม
Bekim Bacaj

ทุกคนที่ตรวจสอบที่นี่ในอนาคตโปรดทราบว่าในขณะที่แท็กจุดยึดสามารถมีองค์ประกอบระดับบล็อกอยู่ใน HTML5 พวกเขาไม่สามารถมีองค์ประกอบระดับบล็อกที่มีแท็กจุดยึดอื่น ๆ ! เพราะโดยทั่วไปแท็กสมอไม่สามารถมีแท็กสมออื่น ๆ คุณสามารถอ่านเพิ่มเติมได้ที่นี่: stackoverflow.com/questions/13052598/…
aderchox

คำตอบ:


748

ขึ้นอยู่กับรุ่นของ HTML ที่คุณใช้:

  • HTML 5ระบุว่า<a>องค์ประกอบ "อาจล้อมรอบทั้งย่อหน้ารายการตารางและอื่น ๆ แม้แต่ส่วนทั้งหมดตราบใดที่ไม่มีเนื้อหาแบบโต้ตอบภายใน (เช่นปุ่มหรือลิงก์อื่น ๆ )"

  • HTML 4.01ระบุว่า<a>องค์ประกอบอาจมีองค์ประกอบแบบอินไลน์เท่านั้น <div>เป็นบล็อกองค์ประกอบ<a>ดังนั้นจึงอาจไม่ปรากฏภายใน

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

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


4
มี DTD สำหรับ 4.01 ที่w3.org/TR/REC-html40/sgml/dtd.html A สามารถมี% inline%; % inline% เป็นกลุ่มของสิ่งต่าง ๆ (คุณสามารถติดตามลิงก์ได้) แต่ DIV ไม่ได้อยู่ในหมู่พวกเขา ดังนั้น A ที่มี DIV ภายในจะไม่สามารถใช้งานกับ XML ได้ ฉันคิดว่า DTD แสดงความตั้งใจของคณะกรรมการค่อนข้างดีดังนั้นฉันจะพูดว่า: ไม่มี
Carl Smotricz

2
@Ewan: ลิงก์แรกในคำตอบของฉันคือไปยังส่วนที่เกี่ยวข้องของ HTML 4.01
NickFitz

62
ฉันกำลังจะทิ้งความเป็นไปได้ที่จะทำสิ่งนี้ในโครงการจนกว่าฉันจะอ่านบรรทัดสุดท้ายเกี่ยวกับ HTML5 นั่นเป็นสิ่งที่ดีที่จะรู้ขอบคุณ
Elaine Marley

16
เครือข่ายนักพัฒนา Mozilla ( developer.mozilla.org/en-US/docs/Web/HTML/Element/a ) สะท้อนให้เห็นถึงความจริงที่ว่า HTML5 <a> องค์ประกอบตอนนี้รองรับองค์ประกอบเนื้อหาการไหลเช่น <div>, <ul> หรือ <table> .
AxeEffect

12
ภายใต้ HTML5 เป็นองค์ประกอบเป็น classed เป็นโปร่งใสซึ่งหมายความว่ามันสามารถมีการไหลเวียนขององค์ประกอบ (อ่านdefault = บล็อก ) เฉพาะในกรณีที่แม่ขององค์ประกอบสามารถมีการไหลเวียนขององค์ประกอบ มิฉะนั้นอนุญาตให้ใช้ถ้อยคำได้เฉพาะองค์ประกอบ (read default = inline ) ดังนั้นถ้าaอยู่ในรูปแบบหรือdivมันสามารถมีdivได้ แต่ใน a pจะไม่สามารถทำได้ ดูw3.org/TR/html-markup/terminology.html
Patanjali

81

ไม่มันจะไม่ตรวจสอบ แต่ใช่โดยทั่วไปจะทำงานในเบราว์เซอร์ที่ทันสมัย ที่ถูกกล่าวว่าใช้ช่วงในสมอของคุณและตั้งdisplay: blockไว้เช่นกันที่จะทำงานได้ทุกที่และจะตรวจสอบ!


7
หากคุณตั้งไว้display: blockไม่ใช่ในทางเทคนิคกลายเป็นองค์ประกอบบล็อกหรือไม่
WhyNotHugo

20
@hugo ในทางเทคนิคแล้วมันสำคัญไหม?
Andy Chase

5
HTML 4.01 ระบุว่าaองค์ประกอบอาจมีองค์ประกอบแบบอินไลน์เท่านั้น หากคุณสร้างspanองค์ประกอบเป็นองค์ประกอบบล็อกมันก็ไม่ควรอยู่ภายในสมอ
WhyNotHugo

22
@Hugo: ดูเหมือนว่าข้อ จำกัด ใน HTML4 นั้นมีความหมายไม่ใช่เป็นการนำเสนอ ความหมาย a <div>คือระดับบล็อกและ a <span>เป็นแบบอินไลน์แม้ว่าเอกสารประกอบ CSS ของเอกสารจะกำหนดเป็นอย่างอื่น
Roy Tinker

เพิ่ม style = "display: block;" ในแท็ก span และมันทำงานเหมือนมีเสน่ห์ เพิ่งเล่นกับการขยายเพื่อให้ได้ผลลัพธ์ตามที่ฉันต้องการ
Harif87

31

เอกสาร W3C ไม่ได้ใช้แนวคิดเช่นผิดและบาปแต่มันก็ไม่ใช้คนที่เป็นเหมือนให้หมายถึง , อาจจะเหมาะสมและท้อแท้

ที่จริงแล้วในย่อหน้าที่สองของส่วนที่ 4นั้น 4.01 ระบุรายละเอียดของคำดังต่อไปนี้

คำสำคัญ "ต้อง", "ต้องไม่", "ต้อง", "จะ", "ไม่ควร", "ไม่ควร", "ไม่ควร", "แนะนำ", "อาจ" และ "ตัวเลือก" ในเอกสารนี้ ที่จะตีความตามที่อธิบายไว้ใน [RFC2119] อย่างไรก็ตามเพื่อความสะดวกในการอ่านคำเหล่านี้จะไม่ปรากฏในตัวอักษรตัวพิมพ์ใหญ่ทั้งหมดในข้อกำหนดนี้

โดยที่ในใจฉันเชื่อว่าคำแถลงที่ชัดเจนอยู่ใน7.5.3 องค์ประกอบระดับบล็อกและอินไลน์ซึ่งมันบอกว่า

โดยทั่วไปองค์ประกอบแบบอินไลน์อาจมีเพียงข้อมูลและองค์ประกอบแบบอินไลน์อื่น ๆ

เงื่อนไข "โดยทั่วไป" ปรากฏขึ้นเพื่อแนะนำความกำกวมพอที่จะกล่าวได้ว่า HTML 4.01 อนุญาตให้องค์ประกอบแบบอินไลน์มีองค์ประกอบบล็อก

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

DTD ดูเหมือนจะให้อภัยน้อยลงที่นี่ แต่ข้อความของ DTDเลื่อนไปที่ข้อมูลจำเพาะ:

ข้อมูลจำเพาะ HTML 4.01 รวมถึงข้อ จำกัด ทางไวยากรณ์เพิ่มเติมที่ไม่สามารถแสดงใน DTD ได้

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


2
คุณมีฉันจนกว่าคุณจะพูดถึงประเภทของ
Robert Harvey

ไม่ใช่ doctype, doctype.com
Ewan Todd

คุณอาจถูกต้อง - ฉันควรใช้ doctype.com Opps - ฉันจะพยายามจดจำในครั้งต่อไป PHP -> SO, HTML -> doctype.com
Tom

2
สิ่งที่ฉันใช้คือไม่มีตัวเลือก "โหวตให้ปิดเหมือนเป็นของ doctype.com" (ไม่ควรมี)
Robert Harvey

7
ฉันเห็นด้วยกับ Rob - Stack Overflow สำหรับการเขียนโปรแกรม HTML / CSS เป็นการเขียนโปรแกรมในมุมมองของฉัน
DisgruntledGoat

13

ด้วยข้อกำหนด HTML5 ... ตอนนี้คุณสามารถวางองค์ประกอบระดับบล็อกไว้ในองค์ประกอบอินไลน์ได้ ดังนั้นตอนนี้จึงเหมาะสมอย่างยิ่งที่จะใส่ 'div' หรือ 'h1' ไว้ในองค์ประกอบ 'a'


1
เฉพาะภายในไหล (default = บล็อก ) องค์ประกอบหรือโปร่งใสองค์ประกอบ (เช่น) กับพ่อแม่ที่ช่วยให้การไหลเวียนขององค์ประกอบ ยกตัวอย่างเช่นPไม่อนุญาตให้มีการไหลขององค์ประกอบ (เช่นdiv ) แต่ถ้อยคำองค์ประกอบ (default = อินไลน์ ) ดังนั้นภายในPไม่สามารถมีdiv อย่างไรก็ตามaภายใน a divสามารถมีp s, div s หรือองค์ประกอบการไหลอื่น ๆ
Patanjali

4

คุณไม่สามารถใส่<div>ข้างใน<a>- มันไม่ถูกต้อง (X) HTML

แม้ว่าคุณจะมีสไตล์เป็นจอแสดงผล: บล็อกคุณยังคงไม่สามารถใส่องค์ประกอบระดับบล็อกไว้ในนั้นได้: (X) HTML ยังคงต้องปฏิบัติตาม (X) HTML DTD (ไม่ว่าคุณจะใช้รูปแบบใดก็ตาม) ไม่ว่า CSS จะเป็นอย่างไร เปลี่ยนแปลงสิ่งต่าง ๆ

เบราว์เซอร์อาจแสดงผลตามที่คุณต้องการ แต่มันไม่ถูกต้อง


4

มี DTD สำหรับ HTML 4 ในhttp://www.w3.org/TR/REC-html40/sgml/dtd.html DTD นี้เป็นรูปแบบของเครื่องที่สามารถประมวลผลได้โดยมีข้อ จำกัด ว่า DTD ควบคุม XML และ HTML 4 โดยเฉพาะอย่างยิ่งรสชาติ "ชั่วคราว" อนุญาตให้มีสิ่งต่าง ๆ มากมายที่ไม่ใช่ XML "ถูกกฎหมาย" ถึงกระนั้นฉันคิดว่ามันใกล้เคียงกับการกำหนดจุดประสงค์ของตัวระบุ

<!ELEMENT A - - (%inline;)* -(A)       -- anchor -->

<!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">

<!ENTITY % fontstyle "TT | I | B | BIG | SMALL">

<!ENTITY % phrase "EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >

<!ENTITY % special "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">

<!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">

ฉันจะตีความแท็กที่ระบุไว้ในลำดับชั้นนี้เป็นจำนวนแท็กทั้งหมดที่ได้รับอนุญาต

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

ในทางกลับกันฉันคิดว่ามันน่าสนใจที่การรวมของspecialดูเหมือนว่าจะอนุญาตให้มีAองค์ประกอบการทำรัง อาจมีถ้อยคำที่คาดเดายากในสเป็คที่ไม่อนุญาตสิ่งนี้แม้ว่าจะถูกต้องตามหลักไวยากรณ์ของ XML แต่ฉันจะไม่ดำเนินการต่อไปเนื่องจากไม่ใช่หัวข้อของคำถาม


คุณรู้ไหมว่า- - หมายถึง ฉันพยายามหาคำอธิบาย แต่หาไม่พบ
Ewan Todd

4

องค์ประกอบระดับบล็อกเช่น<div>สามารถห่อด้วย<a>แท็กใน HTML5 แม้ว่า<div>จะถือเป็นภาชนะ / เสื้อคลุมสำหรับเนื้อหาการไหลและ<a>'s มีการพิจารณาเนื้อหาไหลตามMDN อาจเป็นการดีกว่าที่จะสร้างองค์ประกอบอินไลน์ที่ทำหน้าที่เป็นองค์ประกอบระดับบล็อก


1
ในฐานะที่เป็นองค์ประกอบโปร่งใสเท่านั้นถ้าองค์ประกอบหลักของช่วยให้การไหล (ค่าเริ่มต้นเป็นบล็อก ) องค์ประกอบ
Patanjali

2

หากคุณต้องการหลีกเลี่ยงปัญหาความหมายของการวาง div ภายในแท็ก anchor เพียงวางแท็ก anchor ในระดับเดียวกับ divs ห่อมันทั้งหมดด้วยคอนเทนเนอร์ที่มีตำแหน่ง: สัมพัทธ์ทำให้ตำแหน่งแท็ก anchor ของคุณ: สัมบูรณ์และขยายเป็น เติมภาชนะ นอกจากนี้หากยังไม่ได้อยู่ในส่วนท้ายของการไหลของเนื้อหาให้แน่ใจว่าคุณทิ้งดัชนี z ไว้ที่นั่นเพื่อวางไว้เหนือเนื้อหา

ตามที่แนะนำฉันได้เพิ่มรหัสมาร์กอัป:

<div class="div__container>
  <div class="div__one>
  </div>
  <div class="div__two">
  </div>
  <a href="#"></a>
</div>

และ CSS:

.div__container {
  position: relative; 
}
.div__container a {
  position: absolute;
  top: 0;
  bottom: 0;      
  left: 0;
  right: 0;
  z-index: 999;
}

1
ในขณะที่คำตอบของคุณอาจถูกต้องมันจะช่วยถ้าคุณแสดงด้วยมาร์กอัป
datashaman

1

หากคุณกำลังจะไปสู่ความพยายามในการสร้าง<a>บล็อกทำไมไม่ใส่<a>ใน div เป็นองค์ประกอบบล็อกมันจะให้ผลเหมือนกัน


36
เพราะฉันอาจต้องการให้สมอใส่หลาย divs
Tom

1

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


1

มันผิด. ใช้ช่วง


4
Rofl นั่นก็เหมือนกับการใช้ div ฉันคิดว่าฉันเคยเห็นสิ่งนี้ทำ (กับ divs) ใน blip.tv แต่เป็นคนอื่นพูดถึงมันผิดตาม spec block = block ถ้า div หรือ span หรืออะไรก็ตามที่เหมือนกัน!
James Mitch

0

ฉันคิดว่าส่วนใหญ่เวลาที่ผู้คนถามคำถามนี้พวกเขาได้สร้างเว็บไซต์ที่มี div เท่านั้นและตอนนี้ div หนึ่งต้องการลิงก์

ฉันเห็นใครบางคนใช้ภาพว่างเปล่าแบบโปร่งใส PNG ภายในสมอแท็กเพื่อสร้างลิงก์ภายใน div และภาพมีขนาดเท่ากันกับ div

น่าเศร้าที่จริงแล้ว ... แต่มันใช้งานได้ ...


0

คุณสามารถทำได้โดยการเพิ่ม ":: ก่อน" องค์ประกอบ Pseudo

เคล็ดลับ CSS บริสุทธิ์)

a:before{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  pointer-events: auto;
  content: "";
  background-color: rgba(0,0,0,0);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="card" style="width: 18rem;">
  <img src="https://via.placeholder.com/250" class="card-img-top" alt="...">
  <div class="card-body">
    <h5 class="card-title">Card with stretched link</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
    <a href="#" class="btn btn-primary stretched-link">Go somewhere</a>
  </div>
</div>


-9

เช่นเดียวกับ FYI

หากเป้าหมายของคุณคือทำให้ div ของคุณสามารถคลิกได้คุณสามารถใช้ jQuery / Java Script

กำหนด div ของคุณเช่น:

<div class="clickableDiv" style="cursor:pointer">
  This is my div. Try clicking it!
</div>

jQuery ของคุณจะถูกนำไปใช้เช่น:

 <script type="text/javascript">

    $(document).ready(function () {

        $("div.clickableDiv").click(function () {
            alert("Peekaboo"); 
        });
    });
</script>

สิ่งนี้จะใช้ได้กับหลาย divs - ตามความคิดเห็นของ Tom ในหัวข้อนี้


17
มันแย่มากมันไม่สามารถใช้กับคีย์บอร์ดได้คุณจะไม่เห็นลิงค์บนโฮเวอร์ มันใช้งานได้เกือบเหมือนลิงก์ แต่ไม่ใช่ลิงก์จริง คุณไม่สามารถคลิกตรงกลางได้หรือคลิกขวาเป็นลิงก์ก็ได้
WhyNotHugo

1
มันมีประโยชน์อย่างแน่นอน คุณสามารถวางสมอใน div และให้ div-click เปลี่ยนเส้นทางไปยังตำแหน่งของ child anchor ด้วยการตั้งค่าเคอร์เซอร์บน div ไปยังตัวชี้คุณจะมีรูปลักษณ์และความรู้สึกของจุดยึดรวมถึงโซลูชันทางเลือกที่ถูกต้องโดยมีเพียงตัวยึดใน div เท่านั้นหากไม่อนุญาตให้ใช้จาวาสคริปต์หรือเพื่อเหตุผลในการเข้าถึง คุณจะได้รับ html ที่ถูกต้องทั้งทางความหมายและวากยสัมพันธ์และคุณไม่ต้องยุ่งยากกับการเปลี่ยนแปลงรูปแบบการแสดงที่น่าสงสัย
Pedery

หากคุณมี div ที่มีลิงค์ที่คุณสามารถให้ตัวจัดการการคลิกจับเหตุการณ์ให้ค้นหาจุดยึด (ตรวจสอบให้แน่ใจว่ามีเพียงอันเดียว) จากนั้นใช้สิ่งนั้น สามารถเข้าถึงได้ผ่านแท็กจุดยึดปกติ สิ่งนี้จะช่วยให้มีกลุ่มของรูปภาพพร้อมคำอธิบายภาพและลิงก์ "อ่านเพิ่มเติม" - ตัวอย่างเช่น คิด?
Julix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.