Чи правильне введення діва всередину якіря?


529

Я чув, що введення елемента блоку всередині вбудованого елемента - це гріх 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.

Хтось має якісь подальші поради щодо цього питання?



@DisgruntledGoat - Дякую за посилання - бажаю, щоб я це бачив раніше :-)
Том,

Елемент якоря та \ або посилання - це контроль автоматизації браузера. А отже, у браузері заздалегідь визначена візуалізація та поведінка. Обернути справжній звичайний html-елемент: div всередині прольоту однак є гріхом. Причина того, що тег не додає будь-якої поведінки рівня, є вимогою до маркування частин тексту, не порушуючи документообіг, не тому, що вони мають бути вбудованими елементами. З цього POV A - це тег "нічого не робити". Його існування виходить за межі питання і не є гріхом, але може сприяти кодовій потворності та \ або неоднозначності.
Бекім Бакай

Всім іншим, хто перевіряє тут у майбутньому, зверніть увагу, що, хоча теги прив’язки здатні містити елементи рівня блоку, вонинідіють їх у HTML5, вони не можуть містити елемент рівня блоку, який містить інші теги прив’язки! Тому що в основному теги прив’язки не можуть містити інших тегів якоря всередині них. Ви можете дізнатися більше про те , що тут: stackoverflow.com/questions/13052598 / ...
aderchox

Відповіді:


747

Залежно від версії HTML, яку ви надаєте:

  • HTML 5 зазначає, що<a>елемент "може бути обгорнутий цілими абзацами, списками, таблицями тощо, навіть цілими розділами, доки в ньому немає інтерактивного вмісту (наприклад, кнопок або інших посилань)".

  • HTML 4.01 визначає, що<a>елементи можуть містити лише вбудовані елементи . A<div>- це блок-елемент , тому він може не відображатися всередині<a>.

    Звичайно, ви можете вільно стилізувати вбудований елемент таким чином, що він здається блоком або дійсно стилем блоку, щоб він був наданий в рядку. Використання термінів inlineі blockв HTML означає ставлення елементів до смислової структури документа, тоді як ті самі терміни в CSS більше пов'язані з візуальною стилізацією елементів. Якщо ви роблячи вбудовані елементи без обмежень, це добре.

    Однак ви повинні переконатися, що структура документа все-таки має сенс, коли CSS відсутній, наприклад, при доступі за допомогою допоміжної технології, такої як зчитувач екрана, або ж коли її оглядає могутній Googlebot.


4
Існує DTD на 4.01 за адресою w3.org/TR/REC-html40/sgml/dtd.html . А може містити% inline%; % inline% - це купа різних матеріалів (ви можете переходити за посиланнями), але DIV - не серед них. Таким чином, A з DIV всередині не може перевіряти XML. Я думаю, що DTD висловлює наміри комітету досить добре, тому я б сказав: Ні.
Карл Смотрич

2
@Ewan: Перше посилання в моїй відповіді - на відповідний розділ HTML 4.01.
NickFitz

62
Я збирався позбутися можливості зробити це в проекті, поки не прочитав останній рядок про HTML5, це добре знати, дякую.
Елейн Марлі

16
Мережа розробників Mozilla ( developer.mozilla.org/en-US/docs/Web/HTML/Element/a ) відображає той факт, що HTML5 <a> елементи тепер підтримують елементи вмісту потоку, такі як <div>, <ul> або <table> .
AxeEffect

12
Під HTML5, елемент класифікуються як прозорі , що означає , що він може містити потік елементів (читання по замовчуванням = блок ) , тільки якщо батько в елементі може містити текти елементи. В іншому випадку дозволяються лише елементи фразування (читання за замовчуванням = вбудовані ). Таким чином, якщо a є у формі або div , він може містити div , але всередині p він не може. Дивіться w3.org/TR/html-markup/terminology.html
Патанджалі

81

Ні, це не буде підтверджено, але так, як правило, він буде працювати в сучасних браузерах. Коли це говориться, використовуйте проліт всередині свого якоря, а також встановіть display: blockна ньому, що, безумовно, буде працювати всюди, і воно підтвердиться!


7
Якщо ви встановите display: block, чи технічно це не стає блоковим елементом?
WhyNotHugo

20
@hugo Це технічно має значення?
Енді Чейз

5
Ну, HTML 4.01 визначає, що aелементи можуть містити лише вбудовані елементи. Якщо ви робите spanелемент блоковим елементом, технічно він не повинен знаходитися всередині якоря.
WhyNotHugo

22
@Hugo: Схоже, обмеження в HTML4 є семантичним, а не презентаційним. Семантично а <div>є рівнем блоку і а <span>є вбудованим, навіть якщо супровідний документ CSS диктує інше.
Рой Тінкер

Додано стиль = "дисплей: блок;" у тезі span, і це працювало як шарм. Просто грав з
накладкою,

31

Документ W3C не використовує такі поняття, як помилка та гріх , але він використовує такі, як надає засоби , може бути доцільним і не рекомендується .

Власне, у другому пункті розділу 4 специфікація 4.01 розміщує свої слова наступним чином

У цьому документі ключові слова "ОБОВ'ЯЗКОВО", "НЕ ПОВИННІ", "ПОТРІБНО", "ПОТРІБНО", "НЕ ПОТРІБНО", "ПОТРІБНО", "НЕ БУДЕ", "РЕКОМЕНДОВАНО", "МОЖУ" та "ОПЦІЙНО" інтерпретувати так, як описано в [RFC2119]. Однак для читабельності ці слова не містяться в усіх великих літерах цієї специфікації.

Зважаючи на це, я вважаю, що остаточне твердження міститься в елементах рівня 7.5.3 та блоках , де це написано

Як правило, вбудовані елементи можуть містити лише дані та інші вбудовані елементи.

Умова "загалом", як видається, вносить достатньо двозначності, щоб сказати, що HTML 4.01 дозволяє вбудованим елементам містити елементи блоку.

Безумовно, CSS2 має значення властивості відображення, вбудований блок , який, схоже, підходить до описаної вами мети. Я не впевнений, чи це колись широко підтримувалося, але, здається, хтось передбачив необхідність такої поведінки.

Здається, DTD тут менш прощає, але текст DTD відповідає специфікації:

Специфікація HTML 4.01 включає додаткові синтаксичні обмеження, які неможливо виразити в DTD.

В іншому коментарі ви пропонуєте зробити блок активним, загорнувши його в якір. Я не вірю, що HTML це забороняє, і CSS це чітко дозволяє. Отже, щоб відповісти на головне запитання про те, чи це колись правильно, я кажу так. За мірками це іноді правильно.


2
Ти мав мене до тих пір, поки не згадав про вчення.
Роберт Харві

Не doctype, doctype.com
Еван Тодд

Ви, мабуть, праві - я повинен був використовувати doctype.com. Опси - я спробую запам'ятати наступний раз. PHP -> Так, HTML -> doctype.com
Том

2
Я вважаю, що немає опції "голосування за закриття, як належить на doctype.com" (і не повинно бути).
Роберт Харві

7
Я погоджуюся з Rob - Stack Overflow призначений для програмування. На мій погляд, HTML / CSS, безумовно, програмує.
НезадоволенняГотуйте

13

Із специфікацією HTML5 ... Тепер можна розмістити елемент рівня блоку всередині вбудованого елемента. Тому зараз цілком доречно помістити "div" або "h1" всередину елемента "a".


1
Тільки внутрішні елементи потоку (за замовчуванням = блок ) або прозорі елементи (наприклад, а ) з батьками, які дозволяють елементами потоку . Наприклад, р не допускає потік елементів (наприклад , DIV ), але тільки фразування елементів ( по замовчуванням = рядні ), так що всередині р не може містити DIV . Тим НЕ менше, всередині DIV може містити р с, DIV з або будь-яким іншим потоком елемента.
Патанджалі

4

Ви не можете помістити <div>всередину <a>- це недійсний (X) HTML.

Незважаючи на те, що ви стилюєте проміжок із відображенням: блок, ви все одно не можете помістити елементи рівня блоку всередину нього: (X) HTML все ще повинен підкорятися (X) HTML DTD (який би ви не використовували), незалежно від того, як CSS змінює речі.

Браузер, ймовірно, відображатиме його так, як вам хочеться, але це не робить його правильним.


4

На веб- сайті http://www.w3.org/TR/REC-html40/sgml/dtd.html є DTD для HTML 4 . Цей 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, але я не буду цього робити далі, оскільки це не тема питання.


Ви знаєте, що - - означає. Я намагався знайти пояснення, але не зміг його знайти.
Еван Тодд

4

Елементи рівня блоку, як-от, <div>можна обернути <a>тегами в HTML5. Хоча A <div>вважається контейнером / обгорткою для вмісту потоку, а <a>s вважаються вмістом потоку згідно з MDN . Семантично може бути краще створити вбудовані елементи, які виступають як елементи рівня блоку.


1
Як а елементи є прозорими , тільки якщо батьківський елемент а дозволяє потоку ( по замовчуванням в якості блоку ) елементів.
Патанджалі

2

Якщо ви хочете уникнути смислових проблем з розміщенням знаків всередині тегів якоря, просто розмістіть тег прив’язки на тому ж рівні, що і діви, оберніть їх усім контейнером з позицією: відносно, зробіть позицію тега прив’язки: абсолютною та розгорніть її на наповнити контейнер. Крім того, якщо він не знаходиться в кінці потоку вмісту, переконайтеся, що ви кидаєте туди 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>всередину діл, будучи блоковим елементом, це дасть вам такий же ефект.


36
Тому що, можливо, я хочу, щоб якор містив декілька дівок.
Том

1

Якщо ви зміните його на елемент блочного стилю, то ні, він більше не "неправильний", але він, ймовірно, не перевірить. Але не має сенсу робити те, що ти робиш. Вам слід або просто зберегти тег прив’язки як елемент рівня блоку без внутрішнього поділу, або поставити div на зовнішній стороні.


1

Це неправильно. Використовуйте проліт .


4
rofl це те саме, що і використовувати div. Я думаю, я бачив це, що робилося (з divs) на blip.tv, але, як інші згадують його неправильно відповідно до специфікації block = block, якщо div або span або будь-якого іншого!
Джеймс Мітч

0

Я думаю, що більшу частину часу, коли люди задають це питання, вони створюють сайт лише з divs, і зараз один з div повинен бути посиланням.

Я бачив, як хтось використовує прозоре порожнє зображення, PNG, всередині тега прив’язки просто для того, щоб зробити посилання всередині div, і зображення було такого ж розміру, як і div.

Насправді дуже сумно ... але це працює ...


0

ви можете досягти цього, додавши ":: перед" псевдоелемент

Чистий фокус 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

Так само, як вигадка.

Якщо ваша мета полягає в тому, щоб зробити ваш дивний клік, ви можете використовувати 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>

Це також може працювати для кількох дівок - відповідно до коментаря Тома в цій темі


17
Це жахливо, його не можна використовувати з клавіатурою, ви не можете бачити посилання на наборі. Він працює майже як-посилання, але не є справжнім посиланням. Не можна середнього клацання мишею або правою кнопкою миші на неї як посилання.
WhyNotHugo

1
Це, безумовно, має своє використання. Ви можете поставити якір всередині div і мати переспрямування натискання div на місце розташування дочірного якіра. Встановивши курсор на div на вказівник, ви отримаєте зовнішній вигляд якоря, а також дійсне резервне рішення з лише якорем всередині div, якщо JavaScript не дозволений або з міркувань доступності. Ви отримуєте семантично та синтаксично правильний html, і вам не доведеться волати із сумнівними змінами стилю відображення.
Педері

Якщо у вас є div, який містить посилання, ви могли б змусити обробника клацання зловити подію, знайдіть якір (переконайтеся, що є лише один), а потім скористайтеся цим. Доступний через звичайний тег прив’язки. Це дозволило б мати відро з фігурами із зображенням та підписом та посиланням "читати більше" - наприклад. Думки?
Джулікс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.