Czy umieszczenie div wewnątrz kotwicy jest kiedykolwiek poprawne?


529

Słyszałem, że umieszczenie elementu blokowego wewnątrz elementu wbudowanego jest grzechem 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>

Ale co jeśli stylizujesz zewnętrzną kotwicę jak display:blockw arkuszu stylów? Czy to nadal źle? Wydaje się, że specyfikacja HTML 4.01 dotycząca elementów na poziomie bloku i elementów wbudowanych :

Arkusze stylów zapewniają środki do określania renderowania dowolnych elementów, w tym tego, czy element jest renderowany jako blok, czy wstawiony. W niektórych przypadkach, takich jak wbudowany styl elementów listy, może to być właściwe, ale ogólnie rzecz biorąc, autorzy są zniechęcani do zastępowania konwencjonalnej interpretacji elementów HTML w ten sposób.

Czy ktoś ma jakieś dodatkowe wskazówki na ten temat?



@DisgruntledGoat - Dzięki za link - szkoda, że ​​nie widziałem tego wcześniej :-)
Tom

Element kotwicy i \ lub link jest kontrolką automatyzacji przeglądarki. Dlatego ma wstępnie zdefiniowane renderowanie i zachowanie w przeglądarce. Aby owinąć prawdziwy zwykły element HTML: div wewnątrz zakresu jest jednak grzechem. Powodem tego, że znacznik nie dodaje żadnego zachowania na poziomie, jest wymóg oznaczania części tekstu bez zakłócania przepływu dokumentów, a nie dlatego, że mają one być elementami wstawionymi. Od tego pov, A, jest tagiem „nic nie rób”. Jego istnienie jest poza problemem i nie jest grzechem, ale może przyczyniać się do brzydoty i / lub dwuznaczności kodu.
Bekim Bacaj,

Wszyscy inni, którzy sprawdzą tutaj w przyszłości, pamiętaj, że chociaż tagi kotwiczne SĄ w stanie zawierać elementy na poziomie bloku, ignorują je w HTML5, nie mogą zawierać elementu na poziomie bloku, który zawiera inne tagi zakotwiczenia! Ponieważ w zasadzie tagi zakotwiczenia nie mogą zawierać żadnych innych tagów zakotwiczenia. Możesz przeczytać więcej na ten temat tutaj: stackoverflow.com/questions/13052598/...
aderchox

Odpowiedzi:


747

W zależności od wersji HTML, którą obsługujecie:

  • HTML 5 stwierdza, że<a>element „może być zawijany wokół całych akapitów, list, tabel itp., Nawet całych sekcji, o ile nie ma w nich interaktywnych treści (np. Przycisków lub innych linków)”.

  • HTML 4.01 określa, że<a>elementy mogą zawierać tylko elementy wbudowane . A<div>jest elementem blokowym , więc może nie pojawić się wewnątrz<a>.

    Oczywiście masz swobodę stylizowania elementu śródliniowego tak, aby wyglądał na blok, lub rzeczywiście stylizuj blok tak, aby był renderowany liniowo. Użycie terminów inlinei blockHTML odnosi się do relacji elementów do semantycznej struktury dokumentu, podczas gdy te same terminy w CSS są bardziej związane z wizualną stylistyką elementów. Jeśli sprawisz, że elementy wbudowane będą wyświetlane w sposób blokowy, nie ma sprawy.

    Powinieneś jednak upewnić się, że struktura dokumentu nadal ma sens, gdy CSS nie jest obecny, na przykład przy dostępie za pomocą technologii wspomagającej, takiej jak czytnik ekranu - lub faktycznie, gdy jest sprawdzany przez potężnego Googlebota.


4
DTD dla 4.01 znajduje się na w3.org/TR/REC-html40/sgml/dtd.html . A może zawierać% inline%; % inline% to kilka różnych rzeczy (możesz podążać za linkami), ale DIV nie ma wśród nich. Zatem A z DIV wewnątrz nie jest sprawdzalny pod kątem XML. Myślę, że DTD całkiem dobrze wyraża intencje komisji, więc powiedziałbym: Nie.
Carl Smotricz

2
@Ewan: pierwszy link w mojej odpowiedzi to odpowiedni rozdział HTML 4.01.
NickFitz,

62
Już miałem rzucić możliwość zrobienia tego w projekcie, dopóki nie przeczytam ostatniego wiersza o HTML5, to dobrze wiedzieć, dzięki.
Elaine Marley,

16
Sieć deweloperów Mozilla ( developer.mozilla.org/en-US/docs/Web/HTML/Element/a ) odzwierciedla fakt, że elementy HTML5 <a> obsługują teraz elementy treści przepływu, takie jak <div>, <ul> lub <table> .
AxeEffect,

12
Pod HTML5 element jest klasyfikowany jako przezroczyste , co oznacza, że może zawierać przepływowe elementy (odczyt domyślnie = blok ) tylko wtedy, gdy dominującą na elemencie może zawierać przepływ elementy. W przeciwnym razie dozwolone są tylko elementy frazowania (odczyt domyślny = wbudowany ). Zatem jeśli a jest w formie lub div , może zawierać div , ale wewnątrz p nie może. Zobacz w3.org/TR/html-markup/terminology.html
Patanjali

81

Nie, to się nie sprawdza, ale tak, ogólnie będzie działać w nowoczesnych przeglądarkach. To powiedziawszy, użyj zakresu wewnątrz swojej kotwicy i ustaw display: blockgo również, który na pewno zadziała wszędzie i zostanie zatwierdzony!


7
Jeśli ustawisz display: block, czy technicznie nie stanie się elementem blokowym?
WhyNotHugo,

20
@hugo Czy to technicznie ma znaczenie?
Andy Chase,

5
HTML 4.01 określa, że aelementy mogą zawierać tylko elementy wbudowane. Jeśli uczynisz spanelement blokowym, technicznie nie powinien on znajdować się w kotwicy.
WhyNotHugo

22
@ Hugo: Wygląda na to, że ograniczenie w HTML4 jest semantyczne, a nie prezentacyjne. Semantycznie, a <div>jest na poziomie bloku, a a <span>jest wbudowany, nawet jeśli towarzyszący CSS dokumentu nakazuje inaczej.
Roy Tinker,

Dodano styl = „display: block;” w znaczniku zakresu i działało jak urok. Po prostu grałem z
paddingiem,

31

Dokument W3C nie używa pojęć takich jak zło i grzech , ale używa takich, jak zapewnienie środków , może być odpowiedni i zniechęcony .

W rzeczywistości w drugim akapicie sekcji 4 specyfikacja 4.01 wyszczególnia słowa w następujący sposób

Słowa kluczowe „MUSZĄ”, „MUSI NIE”, „WYMAGANE”, „MUSZĄ”, „NIE MUSZĄ”, „POWINNY”, „NIE POWINNY”, „ZALECANE”, „MAJĄ” i „OPCJONALNIE” w tym dokumencie to należy interpretować zgodnie z opisem w [RFC2119]. Jednak ze względu na czytelność słowa te nie pojawiają się dużymi literami w tej specyfikacji.

Mając to na uwadze, uważam, że ostateczne stwierdzenie znajduje się w 7.5.3 Blokach i elementach wbudowanych , tam gdzie jest napisane

Zasadniczo elementy wbudowane mogą zawierać tylko dane i inne elementy wbudowane.

Warunek „ogólnie” wydaje się wprowadzać na tyle dwuznaczność, aby stwierdzić, że HTML 4.01 pozwala elementom wbudowanym zawierać elementy blokowe.

Z pewnością CSS2 ma wartość właściwości wyświetlania, blok wbudowany , która wydaje się pasować do opisanego celu. Nie jestem pewien, czy kiedykolwiek był szeroko wspierany, ale wydaje się, że ktoś przewidział potrzebę takiego zachowania.

DTD wydaje się tutaj mniej wybaczający, ale tekst DTD odsyła do specyfikacji:

Specyfikacja HTML 4.01 zawiera dodatkowe ograniczenia składniowe, których nie można wyrazić w DTD.

W innym komentarzu sugerujesz, że chcesz uaktywnić blok, zawijając go w kotwicy. Nie wierzę, że HTML tego zabrania, a CSS wyraźnie na to pozwala. Aby odpowiedzieć na tytułowe pytanie dotyczące tego, czy kiedykolwiek jest poprawne, mówię tak. Według standardów jest to czasem poprawne.


2
Miałeś mnie, dopóki nie wspomniałeś o doctype.
Robert Harvey

Nie doctype, doctype.com
Ewan Todd

Prawdopodobnie masz rację - powinienem był użyć doctype.com. Opps - postaram się zapamiętać następnym razem. PHP -> SO, HTML -> doctype.com
Tom

2
Uważam, że nie ma opcji „głosuj na zamknięcie, jak należy na doctype.com” (i nie powinno być).
Robert Harvey

7
Zgadzam się z Robem - przepełnienie stosu służy do programowania. Moim zdaniem HTML / CSS z pewnością programuje.
DisgruntledGoat

13

Dzięki specyfikacji HTML5 ... Można teraz umieścić element na poziomie bloku wewnątrz elementu wbudowanego. Dlatego teraz idealnie jest umieścić „div” lub „h1” wewnątrz elementu „a”.


1
Tylko wewnątrz elementów przepływu (domyślnie = blok ) lub elementów przezroczystych (jak a ) z rodzicami, które pozwalają na elementy przepływu . Na przykład, P nie umożliwiają przepływ elementów (takich jak dz ), lecz jedynie frazowania elementy (standard = rolki ) tak, wewnątrz p nie może zawierać div . Jednakże wewnątrz div może zawierać s s, dz S lub dowolny inny przepływowy element.
Patanjali

4

Nie możesz umieścić w <div>środku <a>- to nie jest prawidłowy (X) HTML.

Mimo że projektujesz rozpiętość za pomocą display: block, nadal nie możesz umieścić w nim elementów na poziomie bloku: (X) HTML nadal musi być zgodny z (X) HTML DTD (w zależności od tego, którego używasz), bez względu na sposób CSS zmienia rzeczy.

Przeglądarka prawdopodobnie wyświetli go tak, jak chcesz, ale to nie poprawia tego.


4

DTD dla HTML 4 znajduje się na stronie http://www.w3.org/TR/REC-html40/sgml/dtd.html . To DTD jest przetwarzalną maszynowo formą specyfikacji, z ograniczeniem, że DTD rządzi XML i HTML 4, szczególnie „przejściowy” smak, pozwala na wiele rzeczy, które nie są „legalne” XML. Mimo to uważam, że zbliża się to do kodyfikacji intencji specyfikatorów.

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

Zinterpretowałbym tagi wymienione w tej hierarchii jako całkowitą dozwoloną liczbę tagów.

Chociaż specyfikacja może powiedzieć „elementy śródliniowe”, jestem całkiem pewien, że nie jest zamierzone, aby obejść ten zamiar, deklarując, że typ wyświetlania elementu blokowego jest wbudowany. Tagi wbudowane mają inną semantykę, bez względu na to, jak możesz ich nadużywać.

Z drugiej strony intrygujące specialwydaje mi się, że włączenie wydaje się pozwalać na zagnieżdżanie Aelementów. Prawdopodobnie w specyfikacji jest pewne mocne sformułowanie, które nie zezwala na to, nawet jeśli jest poprawne pod względem składniowym XML, ale nie będę kontynuował tego dalej, ponieważ nie jest to temat pytania.


Czy wiesz co - - znaczy? Próbowałem znaleźć wyjaśnienie, ale nie znalazłem.
Ewan Todd,

4

Elementy poziomu bloku, takie jak, <div>mogą być zawijane przez <a>tagi w HTML5. Chociaż a <div>jest uważane za pojemnik / opakowanie na zawartość przepływu, a <a>s są uważane za zawartość przepływu zgodnie z MDN . Semantycznie może być lepiej tworzyć elementy wbudowane, które działają jak elementy na poziomie bloku.


1
Jako a elementy są przezroczyste , tylko wtedy, gdy element dominującą A pozwala na przepływ (domyślnie jako blokowych ) elementów.
Patanjali

2

Jeśli chcesz uniknąć semantycznych problemów związanych z umieszczaniem div w tagach anchor, po prostu umieść tag anchor na tym samym poziomie co div, owiń je wszystkie pojemnikiem z pozycją: krewny, ustaw pozycję tagu anchor: absolutną i rozwiń ją do napełnij pojemnik. Również, jeśli nie ma go na końcu przepływu treści, upewnij się, że umieściłeś tam indeks Z, aby umieścić go nad treścią.

Zgodnie z sugestią dodałem kod znaczników:

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

I css:

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

1
Chociaż twoja odpowiedź może być poprawna, pomocne byłoby zilustrowanie jej znacznikami.
datashaman

1

Jeśli masz zamiar podjąć trud tworzenia <a>bloku, dlaczego nie umieścić go <a>w div, będąc elementem bloku, da ci ten sam efekt.


36
Ponieważ może chcę, aby kotwica zawierała wiele elementów div.
Tom

1

Jeśli zmienisz go na element w stylu bloku, to nie, nie będzie już „zły”, ale prawdopodobnie nie będzie się sprawdzał. Ale robienie tego, co robisz, nie ma większego sensu. Powinieneś po prostu zatrzymać tag zakotwiczenia jako element na poziomie bloku bez wewnętrznego div lub umieścić div na zewnątrz.


1

To jest źle. Używać rozpiętości .


4
rofl to to samo, co użycie div. myślę, że widziałem to zrobione (z div) na blip.tv, ale jak inni wspominają, że to źle, zgodnie ze specyfikacją block = block, jeśli div lub span lub cokolwiek to jest to samo!
James Mitch

0

Myślę, że przez większość czasu, gdy ludzie zadają to pytanie, budowali witrynę z tylko divami, a teraz jeden z div musi być linkiem.

Widziałem, jak ktoś używa przezroczystego pustego obrazu, PNG, wewnątrz tagu kotwicy, aby utworzyć łącze w div, a obraz miał ten sam rozmiar co div.

Właściwie to dość smutne ... ale to działa ...


0

możesz to osiągnąć, dodając pseudoelement „:: before”

Pure CSS Trick;)

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

Tak jak FYI.

Jeśli Twoim celem jest umożliwienie kliknięcia div, możesz użyć jQuery / Java Script.

Zdefiniuj div tak:

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

Twoja jQuery zostanie zaimplementowana w następujący sposób:

 <script type="text/javascript">

    $(document).ready(function () {

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

Działa to również dla wielu div - zgodnie z komentarzem Toma w tym wątku


17
To okropne, nie można go używać z klawiaturą, nie widać łącza po najechaniu myszą. Działa prawie jak link, ale nie jest prawdziwym linkiem. Nie można kliknąć środkowego przycisku ani kliknąć prawym przyciskiem myszy jako linku.
WhyNotHugo,

1
Z pewnością ma swoje zastosowania. Możesz umieścić kotwicę w div i przekierować kliknięcie div do lokalizacji kotwicy potomnej. Ustawiając kursor na wskaźniku div na wskaźnik, zyskujesz wygląd i działanie kotwicy, a także prawidłowe rozwiązanie rezerwowe z tylko kotwicą wewnątrz div, jeśli javascript jest niedozwolony lub z przyczyn związanych z dostępnością. Otrzymujesz poprawny semantycznie i składniowo HTML i nie musisz majstrować przy wątpliwych zmianach stylu wyświetlania.
Pedery

Jeśli masz div, który zawiera link, możesz sprawić, by moduł obsługi kliknięć złapał zdarzenie, znajdź zakotwiczenie (upewnij się, że jest tylko jeden), a następnie użyj go. Dostępne za pośrednictwem normalnego znacznika kotwicy. Umożliwiłoby to na przykład zestaw figurek z obrazem i podpisem oraz link „czytaj więcej”. Myśli?
Julix,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.