Là đặt một div bên trong một neo bao giờ đúng?


530

Tôi đã nghe nói rằng việc đặt một phần tử khối bên trong một phần tử nội tuyến là một lỗi 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>

Nhưng những gì về nếu bạn phong cách neo bên ngoài như display:blocktrong bản định kiểu? Có còn sai không? Thông số kỹ thuật HTML 4.01 về các yếu tố nội tuyến và cấp độ khối dường như nghĩ như vậy:

Biểu định kiểu cung cấp các phương tiện để chỉ định kết xuất các phần tử tùy ý, bao gồm cả phần tử được hiển thị dưới dạng khối hoặc nội tuyến. Trong một số trường hợp, chẳng hạn như kiểu nội tuyến cho các thành phần danh sách, điều này có thể phù hợp, nhưng nói chung, các tác giả không khuyến khích ghi đè cách giải thích thông thường của các thành phần HTML theo cách này.

Có ai có bất cứ lời khuyên thêm về vấn đề này?



@DisgruntledGoat - Cảm ơn liên kết - muốn tôi thấy điều đó sớm hơn :-)
Tom

Phần tử neo và \ hoặc liên kết là một điều khiển tự động hóa trình duyệt. Và do đó, nó có một trình duyệt được xác định trước kết xuất và hành vi. Để bọc một phần tử html đơn giản chính hãng: div bên trong một nhịp tuy nhiên là một tội lỗi. Lý do đằng sau thực tế là Thẻ không thêm bất kỳ hành vi cấp độ nào là một yêu cầu trong việc đánh dấu các phần của văn bản mà không làm xáo trộn luồng tài liệu, không phải vì chúng có nghĩa là các thành phần nội tuyến. Từ POV đó, A, là một thẻ không làm gì cả. Sự tồn tại của nó vượt ra ngoài vấn đề và không phải là một tội lỗi, nhưng có thể góp phần vào sự xấu xí và \ hoặc sự mơ hồ.
Bekim Bacaj

Mọi người khác kiểm tra ở đây trong tương lai, xin lưu ý rằng trong khi các thẻ neo CÓ thể chứa các thành phần cấp khối nằm trong HTML5, chúng không thể chứa thành phần cấp khối có chứa các thẻ neo khác! Bởi vì về cơ bản, các thẻ neo không thể có các thẻ neo khác bên trong chúng. Bạn có thể đọc thêm về điều đó tại đây: stackoverflow.com/questions/13052598/ cấp
aderchox

Câu trả lời:


748

Tùy thuộc vào phiên bản HTML bạn đang phục vụ:

  • HTML 5 nói rằng<a>phần tử "có thể được bao bọc xung quanh toàn bộ đoạn văn, danh sách, bảng, v.v., thậm chí toàn bộ các phần, miễn là không có nội dung tương tác trong (ví dụ: các nút hoặc các liên kết khác)".

  • HTML 4.01 chỉ định rằng<a>các phần tử chỉ có thể chứa các phần tử nội tuyến . A<div>là một phần tử khối , vì vậy nó có thể không xuất hiện bên trong một<a> .

    Tất nhiên, bạn có quyền tự do tạo kiểu cho một phần tử nội tuyến sao cho nó có vẻ là một khối hoặc thực sự tạo kiểu cho một khối để nó được hiển thị nội tuyến. Việc sử dụng các thuật ngữ inlineblocktrong HTML đề cập đến mối quan hệ của các yếu tố với cấu trúc ngữ nghĩa của tài liệu, trong khi các thuật ngữ tương tự trong CSS có liên quan nhiều hơn đến kiểu dáng trực quan của các yếu tố. Nếu bạn làm cho các phần tử nội tuyến hiển thị theo cách thức khối, điều đó tốt.

    Tuy nhiên, bạn nên đảm bảo rằng cấu trúc của tài liệu vẫn có ý nghĩa khi không có CSS, ví dụ như khi được truy cập thông qua một công nghệ hỗ trợ như trình đọc màn hình - hoặc thực sự khi được kiểm tra bởi Googlebot hùng mạnh.


4
Có một DTD cho 4,01 tại w3.org/TR/REC-html40/sgml/dtd.html . A có thể chứa% nội tuyến%; % inline% là một loạt các công cụ khác nhau (bạn có thể theo các liên kết) nhưng DIV không nằm trong số đó. Do đó, một A có DIV bên trong không hợp lệ với XML. Tôi nghĩ rằng DTD thể hiện ý định của ủy ban khá tốt, vì vậy tôi nói: Không
Carl Smotricz

2
@Ewan: liên kết đầu tiên trong câu trả lời của tôi là phần có liên quan của HTML 4.01.
NickFitz

62
Tôi đã bỏ qua khả năng thực hiện điều này trong một dự án cho đến khi tôi đọc dòng cuối cùng về HTML5, đó là điều tốt để biết, cảm ơn.
Elaine Marley

16
Mạng lưới nhà phát triển Mozilla ( developer.mozilla.org/en-US/docs/Web/HTML/Euity/a ) phản ánh thực tế các phần tử <a> HTML5 hiện hỗ trợ các thành phần nội dung dòng chảy như <div>, <ul> hoặc <bảng> .
AxeEffect

12
Dưới HTML5, một một phần tử được phân loại như là minh bạch , mà có nghĩa là nó có thể chứa dòng chảy yếu tố (đọc mặc định = khối ) CHỈ nếu phụ huynh của một phần tử có thể chứa chảy yếu tố. Mặt khác, chỉ cho phép các phần tử phrasing (đọc default = inline ). Do đó, nếu adạng hoặc div , nó có thể chứa div , nhưng bên trong p , nó không thể. Xem w3.org/TR/html-markup/terminology.html
Patanjali

81

Không, nó sẽ không xác nhận, nhưng vâng, nó thường sẽ hoạt động trong các trình duyệt hiện đại. Điều đó đang được nói, sử dụng một khoảng bên trong neo của bạn, và cũng đặt display: blocknó, nó chắc chắn sẽ hoạt động ở mọi nơi, và nó sẽ xác nhận!


7
Nếu bạn thiết lập display: block, về mặt kỹ thuật, nó có trở thành một yếu tố khối không?
WhyNotHugo

20
@hugo Có vấn đề kỹ thuật không?
Andy Chase

5
Chà, HTML 4.01 chỉ định rằng acác phần tử chỉ có thể chứa các phần tử nội tuyến. Nếu bạn biến một spanphần tử thành một phần tử khối, về mặt kỹ thuật, nó không nên nằm trong một neo.
WhyNotHugo

22
@Hugo: Có vẻ như hạn chế trong HTML4 là ngữ nghĩa, không mang tính trình bày. Về mặt ngữ nghĩa, a <div>là cấp độ khối và một <span>là nội tuyến, ngay cả khi CSS đi kèm của tài liệu ra lệnh khác.
Roy Tinker

Đã thêm style = "display: block;" trong thẻ span và nó hoạt động như một lá bùa. Chỉ cần chơi với phần đệm để có kết quả mong muốn của tôi
Harif87

31

Tài liệu W3C không sử dụng các khái niệm như saitội lỗi , nhưng nó sử dụng các khái niệm như cung cấp phương tiện , có thể phù hợpkhông được khuyến khích .

Trên thực tế, trong đoạn thứ hai của phần 4 , thông số 4.01 ghi rõ các từ của nó như sau

Các từ khóa "PHẢI", "KHÔNG PHẢI", "BẮT BUỘC", "SALL", "SALL KHÔNG", "NÊN", "KHÔNG NÊN", "KHUYẾN NGHỊ", "CÓ THỂ" và "TÙY CHỌN" trong tài liệu này là được giải thích như được mô tả trong [RFC2119]. Tuy nhiên, để dễ đọc, những từ này không xuất hiện trong tất cả các chữ cái in hoa trong đặc tả này.

Với ý nghĩ đó, tôi tin rằng tuyên bố dứt khoát nằm trong 7.5.3 Các yếu tố nội tuyến và cấp độ khối , trong đó nói

Nói chung, các phần tử nội tuyến có thể chỉ chứa dữ liệu và các phần tử nội tuyến khác.

Điều kiện "nói chung" dường như giới thiệu đủ sự mơ hồ để nói rằng HTML 4.01 không cho phép các phần tử nội tuyến chứa các phần tử khối.

Chắc chắn, CSS2 có giá trị thuộc tính hiển thị, khối nội tuyến , có vẻ phù hợp với mục đích bạn mô tả. Tôi không chắc liệu nó có được hỗ trợ rộng rãi không, nhưng có vẻ như ai đó đã lường trước sự cần thiết của loại hành vi đó.

DTD dường như ít tha thứ hơn ở đây, nhưng văn bản của DTD trì hoãn thông số kỹ thuật:

Đặc tả HTML 4.01 bao gồm các ràng buộc cú pháp bổ sung không thể được thể hiện trong các DTD.

Trong một bình luận khác, bạn đề nghị rằng bạn muốn làm cho một khối hoạt động bằng cách gói nó trong một neo. Tôi không tin rằng HTML cấm điều đó và CSS rõ ràng cho phép điều đó. Vì vậy, để trả lời câu hỏi tiêu đề về việc nó có bao giờ đúng không, tôi nói có. Theo tiêu chuẩn, đôi khi nó là chính xác.


2
Bạn đã có tôi cho đến khi bạn đề cập đến doctype.
Robert Harvey

Không phải doctype, doctype.com
Ewan Todd

Bạn có thể đúng - Tôi nên sử dụng doctype.com. Opps - Tôi sẽ cố nhớ lần sau. PHP -> SO, HTML -> doctype.com
Tom

2
Tôi thực hiện không có tùy chọn "bỏ phiếu để đóng như thuộc về doctype.com" (cũng không nên có).
Robert Harvey

7
Tôi đồng ý với Rob - Stack Overflow dành cho lập trình. HTML / CSS chắc chắn là lập trình theo quan điểm của tôi.
DisgruntledGoat

13

Với đặc tả HTML5 ... Bây giờ có thể đặt phần tử cấp khối bên trong phần tử nội tuyến. Vì vậy, bây giờ hoàn toàn thích hợp để đặt một 'div' hoặc 'h1' bên trong phần tử 'a'.


1
Chỉ các phần tử luồng bên trong (default = block ) hoặc các phần tử trong suốt (như a ) với các phần tử cho phép các phần tử luồng . Ví dụ: p không cho phép dòng chảy yếu tố (như div ), nhưng chỉ phân nhịp yếu tố (mặc định = inline ), do đó một một bên trong một p không thể chứa một div . Tuy nhiên, một một bên trong một div có thể chứa p s, div s hoặc bất kỳ khác dòng phần tử .
Patanjali

4

Bạn không thể đặt <div>bên trong <a>- nó không hợp lệ (X) HTML.

Mặc dù bạn định kiểu một khoảng với màn hình: chặn, bạn vẫn không thể đặt các phần tử mức khối bên trong nó: HTML (X) vẫn phải tuân theo DTD HTML (X) (cho dù bạn sử dụng loại nào), bất kể CSS như thế nào làm thay đổi mọi thứ

Trình duyệt có thể sẽ hiển thị nó như bạn muốn, nhưng điều đó không làm cho nó đúng.


4

Có một DTD cho HTML 4 tại http://www.w3.org/TR/REC-html40/sgml/dtd.html . DTD này là hình thức có thể xử lý bằng máy của thông số kỹ thuật, với giới hạn là DTD chi phối XML và HTML 4, đặc biệt là hương vị "nhất thời", cho phép rất nhiều thứ không phải là XML "hợp pháp". Tuy nhiên, tôi cho rằng nó gần với việc mã hóa ý định của các nhà đầu cơ.

<!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">

Tôi sẽ giải thích các thẻ được liệt kê trong hệ thống phân cấp này là tổng số các thẻ được phép.

Trong khi thông số kỹ thuật có thể nói "các yếu tố nội tuyến", tôi khá chắc chắn rằng nó không có ý định rằng bạn có thể giải quyết ý định bằng cách tuyên bố kiểu hiển thị của một phần tử khối là nội tuyến. Thẻ nội tuyến có ngữ nghĩa khác nhau cho dù bạn có thể lạm dụng chúng như thế nào.

Mặt khác, tôi thấy thú vị rằng sự bao gồm specialdường như cho phép các Ayếu tố lồng nhau . Có lẽ có một số từ ngữ mạnh mẽ trong thông số kỹ thuật không đồng ý điều này ngay cả khi nó đúng về mặt cú pháp XML nhưng tôi sẽ không theo đuổi điều này hơn nữa vì nó không phải là chủ đề của câu hỏi.


Bạn có biết những gì - - có nghĩa là. Tôi đã cố gắng tìm một lời giải thích nhưng tôi không thể tìm thấy một lời giải thích.
Ewan Todd

4

Các phần tử mức khối như <div>có thể được bọc bởi <a>các thẻ trong HTML5. Mặc dù a <div>được coi là một thùng chứa / trình bao cho nội dung luồng<a>được coi là nội dung luồng theo MDN . Về mặt ngữ nghĩa, có thể tốt hơn để tạo các phần tử nội tuyến hoạt động như các phần tử mức khối.


1
Như một yếu tố minh bạch , chỉ khi các yếu tố cha mẹ của một phép lưu lượng (mặc định là block ) các yếu tố.
Patanjali

2

Nếu bạn muốn tránh những rắc rối về ngữ nghĩa khi đặt div bên trong thẻ neo, chỉ cần đặt thẻ neo ở cùng cấp độ với div, bọc tất cả chúng bằng một thùng chứa có vị trí: tương đối, tạo vị trí thẻ neo của bạn: tuyệt đối và mở rộng nó sang điền vào thùng chứa. Ngoài ra, nếu nó không ở cuối dòng nội dung, hãy đảm bảo bạn ném chỉ số z vào đó để đặt nó lên trên nội dung.

Theo đề xuất, tôi đã thêm một mã đánh dấu:

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

Và css:

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

1
Mặc dù câu trả lời của bạn có thể đúng, nhưng nó sẽ hữu ích nếu bạn minh họa nó bằng đánh dấu.
datashaman

1

Nếu bạn đang nỗ lực tạo <a>khối, tại sao không đặt <a>bên trong div, là một phần tử khối, nó sẽ mang lại cho bạn hiệu ứng tương tự.


36
Bởi vì tôi có thể muốn mỏ neo bao quanh nhiều div.
Tom

1

Nếu bạn thay đổi nó thành một yếu tố kiểu khối, thì không, nó không còn "sai" nữa, nhưng có lẽ nó sẽ không hợp lệ. Nhưng nó không có ý nghĩa gì để làm những gì bạn đang làm. Bạn chỉ nên giữ thẻ neo dưới dạng phần tử mức khối không có div bên trong hoặc đặt div ở bên ngoài.


1

Nó sai. Sử dụng một nhịp .


4
rofl đó là điều tương tự như sử dụng div. Tôi nghĩ rằng tôi đã thấy điều này được thực hiện (với div) trên blip.tv nhưng như những người khác đề cập đến sai của nó theo spec block = block nếu div hoặc span hoặc bất cứ điều gì giống nhau!
James Mitch

0

Tôi nghĩ rằng hầu hết thời gian khi mọi người hỏi câu hỏi này, họ đã xây dựng một trang web chỉ có div, và bây giờ một trong những div cần phải là một liên kết.

Tôi thấy ai đó sử dụng một hình ảnh trống trong suốt, PNG, bên trong thẻ neo chỉ để tạo liên kết bên trong div và hình ảnh có cùng kích thước với div.

Thực sự khá buồn ... nhưng nó hoạt động ...


0

bạn có thể đạt được điều này bằng cách thêm phần tử giả ":: trước"

Thủ thuật CSS thuần túy;)

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

Cũng như một FYI.

Nếu mục tiêu của bạn là làm cho div có thể nhấp được, bạn có thể sử dụng Tập lệnh jQuery / Java.

Xác định div của bạn như vậy:

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

JQuery của bạn sau đó sẽ được triển khai như vậy:

 <script type="text/javascript">

    $(document).ready(function () {

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

Điều này cũng sẽ hoạt động cho nhiều div - theo nhận xét của Tom trong chủ đề này


17
Điều này thật kinh khủng, nó không thể được sử dụng với bàn phím, bạn không thể thấy liên kết khi di chuột. Nó hoạt động gần giống như một liên kết, nhưng không phải là một liên kết thực sự. Bạn cũng không thể nhấp vào nó hoặc nhấp chuột phải vào liên kết.
WhyNotHugo

1
Nó chắc chắn có công dụng của nó. Bạn có thể đặt một neo bên trong div và chuyển hướng nhấp chuột đến vị trí của neo con. Bằng cách đặt con trỏ trên div thành con trỏ, do đó bạn có giao diện của neo, cộng với giải pháp dự phòng hợp lệ chỉ có neo bên trong div nếu javascript không được phép hoặc vì lý do truy cập. Bạn nhận được html chính xác về mặt ngữ nghĩa và cú pháp, và bạn không phải loay hoay với những thay đổi đáng ngờ của kiểu hiển thị.
Pedery

Nếu bạn có một div chứa liên kết, bạn có thể có trình xử lý nhấp chuột để nắm bắt sự kiện, hãy tìm neo (đảm bảo chỉ có một) và sau đó sử dụng liên kết đó. Có thể truy cập thông qua thẻ neo bình thường. Điều này sẽ cho phép có một thùng các hình có hình ảnh và chú thích và liên kết "đọc thêm" - ví dụ. Suy nghĩ?
Julix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.