Apakah menempatkan div di dalam jangkar benar?

530

Saya pernah mendengar bahwa meletakkan elemen blok di dalam elemen inline adalah dosa 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>

Tapi bagaimana jika Anda gaya jangkar luar seperti display:blockpada stylesheet? Apakah masih salah? HTML 4.01 spec pada elemen level-blok dan inline tampaknya berpikir demikian:

Lembaran gaya menyediakan sarana untuk menentukan rendering elemen arbitrer, termasuk apakah elemen dirender sebagai blok atau inline. Dalam beberapa kasus, seperti gaya inline untuk elemen daftar, ini mungkin sesuai, tetapi secara umum, penulis tidak disarankan untuk mengesampingkan interpretasi konvensional elemen HTML dengan cara ini.

Adakah yang punya kiat lebih lanjut tentang masalah ini?

Tom
sumber
@DisgruntledGoat - Terima kasih atas tautannya - andai saya melihatnya lebih cepat :-)
Tom
Elemen anchor dan \ atau tautan adalah kontrol otomatisasi browser. Dan karenanya memiliki perenderan dan perilaku yang telah ditentukan browser. Namun untuk membungkus elemen html polos asli: div di dalam rentang adalah dosa. Alasan di balik fakta bahwa tag A tidak menambahkan perilaku tingkat adalah persyaratan dalam menandai bagian teks tanpa mengganggu aliran dokumen, bukan karena mereka dimaksudkan untuk elemen inline. Dari pov itu, A, adalah tag do nothing. Keberadaannya di luar masalah dan bukan dosa, tetapi dapat berkontribusi pada kode keburukan dan \ atau ambiguitas.
Bekim Bacaj
Semua orang yang memeriksa di sini di masa depan, harap dicatat bahwa sementara tag anchor ADALAH mampu mengandung elemen level blok di dalam HTML5, tag tersebut tidak dapat mengandung elemen level blok yang mengandung tag anchor lainnya! Karena pada dasarnya, tag anchor tidak dapat memiliki tag anchor lain di dalamnya. Anda dapat membaca lebih lanjut tentang itu di sini: stackoverflow.com/questions/13052598/…
aderchox

Jawaban:

748

Bergantung pada versi HTML yang Anda layani:

  • HTML 5 menyatakan bahwa<a>elemen "dapat membungkus seluruh paragraf, daftar, tabel, dan sebagainya, bahkan seluruh bagian, asalkan tidak ada konten interaktif di dalamnya (mis. Tombol atau tautan lain)".

  • HTML 4.01 menetapkan bahwa<a>elemen hanya dapat berisi elemen sebaris . A<div>adalah elemen blok , jadi itu mungkin tidak muncul di dalam<a>.

    Tentu saja Anda bebas untuk mendesain elemen inline sedemikian rupa sehingga tampak seperti sebuah blok, atau memang gaya sebuah blok sehingga itu diberikan inline. Penggunaan istilah inlinedan blockdalam HTML mengacu pada hubungan elemen dengan struktur semantik dokumen, sedangkan istilah yang sama dalam CSS lebih terkait dengan gaya visual elemen. Jika Anda membuat elemen inline ditampilkan dengan cara kuning, itu bagus.

    Namun Anda harus memastikan bahwa struktur dokumen masih masuk akal ketika CSS tidak ada, misalnya ketika diakses melalui teknologi bantu seperti pembaca layar - atau memang ketika diperiksa oleh Googlebot yang perkasa.

NickFitz
sumber
4
Ada DTD untuk 4.01 di w3.org/TR/REC-html40/sgml/dtd.html . A dapat mengandung% inline%; % inline% adalah banyak hal yang berbeda (Anda dapat mengikuti tautannya) tetapi DIV tidak ada di antaranya. Dengan demikian, A dengan DIV di dalamnya bukan XML-validatable. Saya pikir DTD mengekspresikan niat panitia dengan cukup baik, jadi saya akan mengatakan: Tidak.
Carl Smotricz
2
@Wan: tautan pertama dalam jawaban saya adalah ke bagian HTML 4.01 yang relevan.
NickFitz
62
Saya akan membuang kemungkinan untuk melakukan ini dalam proyek sampai saya membaca baris terakhir tentang HTML5, itu bagus untuk diketahui, terima kasih.
Elaine Marley
16
Jaringan Pengembang Mozilla ( developer.mozilla.org/en-US/docs/Web/HTML/Element/a ) mencerminkan fakta HTML5 <a> elemen sekarang mendukung elemen konten aliran seperti <div>, <ul> atau <table> .
AxeEffect
12
Di bawah HTML5, sebuah sebuah elemen digolongkan sebagai transparan , yang berarti dapat mengandung aliran elemen (read default = block ) HANYA jika induk dari sebuah elemen dapat berisi mengalir elemen. Jika tidak, hanya elemen frase (baca default = sebaris ) yang diizinkan. Jadi, jika a adalah dalam bentuk atau div , itu bisa berisi div , tetapi di dalam p , itu tidak bisa. Lihat w3.org/TR/html-markup/terminology.html
Patanjali
81

Tidak itu tidak akan divalidasi, tapi ya itu umumnya akan berfungsi di browser modern. Yang sedang berkata, gunakan rentang di dalam jangkar Anda, dan atur display: blockdi atasnya juga, yang pasti akan bekerja di mana-mana, dan itu akan divalidasi!

Eloff
sumber
7
Jika Anda mengatur display: block, bukankah, secara teknis, menjadi elemen blok?
WhyNotHugo
20
@ hugo Apakah secara teknis penting?
Andy Chase
5
Yah, HTML 4.01 menetapkan bahwa aelemen hanya dapat berisi elemen sebaris. Jika Anda membuat spanelemen elemen blok, itu seharusnya tidak, secara teknis, berada di dalam jangkar.
WhyNotHugo
22
@Hugo: Tampaknya pembatasan dalam HTML4 adalah semantik, bukan presentasi. Secara semantik, a <div>adalah blok-level dan a <span>inline, bahkan jika dokumen yang menyertai CSS menentukan sebaliknya.
Roy Tinker
Menambahkan style = "display: block;" dalam tag rentang dan itu bekerja seperti pesona. Baru saja bermain dengan bantalan untuk mendapatkan hasil yang saya inginkan
Harif87
31

Dokumen W3C tidak menggunakan konsep-konsep seperti salah dan dosa , tetapi menggunakan konsep-konsep seperti menyediakan sarana , mungkin sesuai dan tidak dianjurkan .

Sebenarnya, dalam paragraf kedua bagian 4 , spesifikasi 4.01 memerinci kata-katanya sebagai berikut

Kata kunci "HARUS", "HARUS TIDAK", "DIPERLUKAN", "AKAN", "TIDAK AKAN", "HARUS TIDAK", "HARUS TIDAK", "DIREKOMENDASIKAN", "MUNGKIN", dan "OPTIONAL" dalam dokumen ini adalah untuk ditafsirkan seperti yang dijelaskan dalam [RFC2119]. Namun, untuk keterbacaan, kata-kata ini tidak muncul dalam semua huruf besar dalam spesifikasi ini.

Dengan mengingat hal itu, saya percaya pernyataan definitif ada di 7.5.3 Elemen level-blok dan inline , di mana katanya

Secara umum, elemen sebaris mungkin hanya berisi data dan elemen sebaris lainnya.

Kondisi "umumnya" tampaknya memperkenalkan ambiguitas yang cukup untuk mengatakan bahwa HTML 4.01 memungkinkan elemen inline mengandung elemen blok.

Tentu saja, CSS2 memiliki nilai properti tampilan, inline-block , yang tampaknya sesuai dengan tujuan yang Anda jelaskan. Saya tidak yakin apakah itu didukung secara luas, tetapi tampaknya seseorang mengantisipasi perlunya perilaku semacam itu.

DTD tampaknya kurang memaafkan di sini, tetapi teks DTD tidak sesuai dengan spesifikasi:

Spesifikasi HTML 4.01 mencakup kendala sintaksis tambahan yang tidak dapat diungkapkan dalam DTD.

Di komentar lain, Anda menyarankan agar Anda ingin membuat blok aktif dengan membungkusnya di jangkar. Saya tidak percaya HTML melarang itu, dan CSS dengan jelas mengizinkannya. Jadi untuk menjawab pertanyaan judul tentang apakah itu benar, saya katakan ya. Menurut standar, kadang-kadang itu benar.

Ewan Todd
sumber
2
Anda punya saya sampai Anda menyebutkan doctype.
Robert Harvey
Bukan doctype, doctype.com
Ewan Todd
Anda mungkin benar - saya seharusnya menggunakan doctype.com. Opps - Saya akan mencoba mengingat untuk kali berikutnya. PHP -> SO, HTML -> doctype.com
Tom
2
Pendapat saya adalah tidak ada pilihan "suara untuk ditutup sebagai milik pada doctype.com" (juga tidak boleh ada).
Robert Harvey
7
Saya setuju dengan Rob - Stack Overflow untuk pemrograman. HTML / CSS tentu pemrograman dalam pandangan saya.
DisgruntledGoat
13

Dengan spesifikasi HTML5 ... Sekarang dimungkinkan untuk menempatkan elemen level blok di dalam elemen inline. Jadi sekarang sangat tepat untuk meletakkan 'div' atau 'h1' di dalam elemen 'a'.

Abir
sumber
1
Hanya elemen di dalam aliran (default = blok ), atau elemen transparan (seperti a ) dengan orang tua yang memungkinkan elemen aliran . Sebagai contoh, p tidak mengijinkan elemen aliran (seperti div ), tetapi hanya elemen frase (default = inline ), jadi a di dalam p tidak dapat berisi div . Namun, a di dalam div dapat berisi p s, div s atau elemen aliran lainnya .
Patanjali
4

Anda tidak dapat memasukkan ke <div>dalam <a>- itu tidak valid (X) HTML.

Meskipun Anda mendesain rentang dengan tampilan: blok Anda tetap tidak dapat memasukkan elemen level blok di dalamnya: (X) HTML masih harus mematuhi (X) HTML DTD (mana pun yang Anda gunakan), tidak peduli bagaimana CSS mengubah banyak hal.

Peramban mungkin akan menampilkannya seperti yang Anda inginkan, tetapi itu tidak membuatnya benar.

Greg
sumber
4

Ada DTD untuk HTML 4 di http://www.w3.org/TR/REC-html40/sgml/dtd.html . DTD ini adalah bentuk spec yang dapat diproses dengan mesin, dengan batasan bahwa DTD mengatur XML dan HTML 4, terutama rasa "sementara", memungkinkan banyak hal yang bukan XML "legal". Namun, saya menganggap itu mendekati kodifikasi maksud dari specifier.

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

Saya akan menafsirkan tag yang tercantum dalam hierarki ini sebagai total tag yang diizinkan.

Sementara spek dapat mengatakan "elemen sebaris," saya cukup yakin itu tidak dimaksudkan bahwa Anda dapat menyiasati maksud dengan menyatakan tipe tampilan elemen blok yang akan sebaris. Tag inline memiliki semantik berbeda, tidak peduli bagaimana Anda dapat menyalahgunakannya.

Di sisi lain, saya menemukan hal yang menarik bahwa masuknya elemen specialnampaknya memungkinkan A. Mungkin ada beberapa kata-kata yang kuat dalam spek yang melarang ini meskipun itu XML-sintaksis benar tetapi saya tidak akan mengejar ini lebih jauh karena itu bukan topik pertanyaan.

Carl Smotricz
sumber
Apakah Anda tahu apa - - artinya. Saya mencoba menemukan penjelasan tetapi saya tidak dapat menemukannya.
Ewan Todd
4

Elemen tingkat blok seperti <div>dapat dibungkus dengan <a>tag dalam HTML5. Meskipun a <div>dianggap sebagai wadah / pembungkus untuk konten aliran dan <a>dianggap sebagai konten aliran menurut MDN . Semantik mungkin lebih baik untuk membuat elemen sebaris yang bertindak sebagai elemen tingkat blok.

Beepye
sumber
1
Sebagai sebuah elemen yang transparan , hanya jika elemen induk dari sebuah memungkinkan aliran (default sebagai blok ) elemen.
Patanjali
2

Jika Anda ingin menghindari masalah semantik menempatkan div di dalam tag jangkar, cukup tempatkan tag jangkar pada tingkat yang sama dengan div, bungkus semuanya dengan wadah dengan posisi: relatif, buat posisi tag jangkar Anda: absolut dan perluas untuk isi wadahnya. Juga jika itu tidak di akhir aliran konten pastikan Anda melemparkan indeks-z di sana untuk meletakkannya di atas konten.

Seperti yang disarankan, saya telah menambahkan kode markup:

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

Dan css:

.div__container {
  position: relative; 
}
.div__container a {
  position: absolute;
  top: 0;
  bottom: 0;      
  left: 0;
  right: 0;
  z-index: 999;
}
Eugen
sumber
1
Meskipun jawaban Anda mungkin benar, akan sangat membantu jika Anda menggambarkannya dengan markup.
datashaman
1

Jika Anda akan pergi ke upaya membuat <a>blok, mengapa tidak dimasukkan <a>ke dalam div, menjadi elemen blok itu akan memberi Anda efek yang sama.

Dave
sumber
36
Karena saya mungkin ingin jangkar untuk melampirkan banyak div.
Tom
1

Jika Anda mengubahnya ke elemen gaya blok, maka tidak, itu tidak lagi 'salah', tetapi mungkin tidak akan divalidasi. Tetapi tidak masuk akal untuk melakukan apa yang Anda lakukan. Anda harus menyimpan tag jangkar sebagai elemen level blok tanpa div dalam, atau meletakkan div di luar.

Chris
sumber
1

Itu salah. Gunakan rentang .

Jon Hadley
sumber
4
rofl itu sama dengan menggunakan div. saya pikir saya telah melihat ini dilakukan (dengan divs) di blip.tv tetapi karena orang lain menyebutkan salahnya menurut spec block = block if div atau span atau apalah itu sama!
James Mitch
0

Saya pikir sebagian besar waktu ketika orang mengajukan pertanyaan ini, mereka telah membangun situs dengan divs saja, dan sekarang salah satu dari div perlu menjadi tautan.

Saya melihat seseorang menggunakan gambar kosong transparan, PNG, di dalam tag jangkar hanya untuk membuat tautan di dalam div, dan gambar itu berukuran sama dengan div.

Cukup sedih sebenarnya ... tapi berhasil ...

pengguna1081070
sumber
0

Anda dapat mencapai ini dengan menambahkan ":: before" Pseudo-element

Trik CSS Murni;)

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>

AkshayKumar
sumber
-9

Sama seperti FYI.

Jika tujuan Anda adalah membuat div Anda dapat diklik, Anda dapat menggunakan jQuery / Java Script.

Tentukan div Anda seperti ini:

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

Kemudian jQuery Anda akan diimplementasikan seperti ini:

 <script type="text/javascript">

    $(document).ready(function () {

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

Ini juga akan berfungsi untuk beberapa div - sesuai komentar Tom di utas ini

pemecahan
sumber
17
Ini mengerikan, tidak bisa digunakan dengan keyboard, Anda tidak dapat melihat tautannya saat di-hover. Ini berfungsi hampir seperti tautan, tetapi bukan tautan yang sebenarnya. Anda juga tidak dapat mengklik tengahnya, atau mengeklik kanannya sebagai tautan.
WhyNotHugo
1
Ini tentu memiliki kegunaannya. Anda bisa meletakkan jangkar di dalam div dan minta redirect klik-div ke lokasi anchor anak. Dengan mengatur kursor pada div ke pointer Anda memiliki tampilan dan nuansa jangkar, ditambah solusi mundur yang valid dengan hanya jangkar di dalam div jika javascript tidak diperbolehkan atau untuk alasan aksesibilitas. Anda mendapatkan html yang benar secara semantik dan sintaksis, dan Anda tidak perlu mengutak-atik perubahan gaya tampilan yang dipertanyakan.
Pedery
Jika Anda memiliki div yang berisi tautan, Anda bisa meminta penangan klik menangkap acara tersebut, cari jangkar (pastikan hanya ada satu) dan kemudian gunakan itu. Dapat diakses melalui tag anchor normal. Ini akan memungkinkan memiliki seember gambar dengan gambar dan teks dan tautan "baca lebih lanjut" - misalnya. Pikiran?
Julix