CSS: po nie dodawaniu treści do niektórych elementów

100

Mam problem ze zrozumieniem zachowania :afterwłaściwości CSS . Zgodnie ze specyfikacją ( tutaj i tutaj ):

Jak ich nazwy wskazują, że :beforei :afterpseudo-elementy określić lokalizację zawartości przed i po zawartości drzewa dokument elementu.

Wydaje się, że nie nakłada to ograniczeń na to, które elementy mogą mieć :after(lub :before) właściwość. Jednakże wydaje się, aby pracować tylko z określonych elementów ... <p>prac, <img>nie, <input>nie, <table>nie. Mógłbym przetestować więcej, ale o to chodzi. Zauważ, że wydaje się to dość spójne w różnych przeglądarkach. Co decyduje o tym, czy obiekt może przyjąć właściwość :beforei :after?

eykanal
źródło

Odpowiedzi:

156

imgi inputoba są wymienionymi elementami .

Element zastępowany to dowolny element, którego wygląd i wymiary są określone przez zasób zewnętrzny. Przykłady obejmują obrazów ( <img>znaczniki) rozszerzeń ( <object>znaczniki), oraz elementy forma ( <button>, <textarea>, <input>, i <select>znaczniki). Wszystkie inne typy elementów można nazywać elementami niezastępowanymi.

:beforei :afterdziałają tylko z niezmienionymi elementami.

Ze specyfikacji :

Uwaga. Ten opis nie jest w pełni określają wzajemne oddziaływanie :beforei :afterz elementami zamiany (np IMG w HTML). Zostanie to bardziej szczegółowo określone w przyszłej specyfikacji.

W span:before, span:afterprzypadku modelu DOM wygląda następująco:

<span><before></before>Content of span<after></after></span>

Najwyraźniej to nie zadziała <img src="" />.

trzydzieści kropek
źródło
2
„Wygenerowana treść nie zmienia drzewa dokumentu”. Byłbym więc zaskoczony, gdybyś był w stanie znaleźć <before></before>w źródle coś takiego jak „ ”.
Knu
4
@Knu: Masz rację, słabo to wyjaśniłem. Nigdy nie znajdziesz <before></before>. Powinienem był powiedzieć „udawaj DOM” czy coś. Chodziło o to, aby to pokazać :beforei :afterznaleźć się wewnątrz elementu, a nie na zewnątrz.
trzydzieści kropek
Nie, nie są one przechowywane w Shadow DOM.
narzędzie
3
Podana specyfikacja tego nie mówi :beforei :afternie działa dla wymienionych elementów; mówi tylko, że nie „w pełni” definiuje, jak i to zostanie zdefiniowane w przyszłości (co do tej pory nie miało miejsca). To, co dzieje się w DOM, nie ma tutaj znaczenia. Chociaż przeglądarki nie obsługują tych pseudoelementów dla niektórych elementów, nie ma tego w specyfikacjach, tylko co robią implementacje.
Jukka K. Korpela
Kiedyś uważałem za logiczne wyjaśnienie, że ::beforei ::afternie działa dla elementu void (pustego), który nigdy nie ma rzeczywistej treści, przed / po której można je zastosować. Ale, co zaskakujące, działają dla hrelementu w prawie wszystkich przeglądarkach.
Ilya Streltsyn,
9

:beforei :afternie są wymagane do pracy z zastępowanymi elementami, a specyfikacje CSS nie określają, jak miałyby one działać, a koncepcja zastępowanego elementu jest nieco niejasna.

Specyfikacja CSS 2.1 jasno sugeruje , że mogą one działać dla zastąpionych elementów, po prostu mówiąc, że nie „w pełni” definiuje, jak. Wiąże się to z tym, że zastępowany element ma mieć własne renderowanie wizualne, które nie jest kontrolowane przez CSS, podczas gdy pseudoelementy powinny dodawać coś do zawartości elementu. W specyfikacji dodano, że zostanie to określone „bardziej szczegółowo” w przyszłej specyfikacji, ale do tej pory nie miało to miejsca.

Producenci przeglądarek postanowili po prostu uniknąć problemów, nie implementując w ogóle tych pseudoelementów dla niektórych elementów.

W ogóle nie jest jasne, co oznacza „zastąpiony element” i wydaje się, że znaczenie nieco się zmieniło. Często jest interpretowane jako oznaczające to samo co pusty element (element z EMPTYzadeklarowaną zawartością, tj. Element, który nie może mieć żadnej treści), ale sam CSS 2.1 pokazuje przykładowy arkusz stylów z selektorem br:before(chociaż przeglądarki zignorowały to, implementując brwłasne sposób). Można argumentować, że coraz więcej elementów znalazło się w zakresie renderowania CSS, przynajmniej częściowo. Na przykład inputelementem (łącznie z czcionką, kolorami itp.) Można w większości sterować za pomocą CSS w nowoczesnych przeglądarkach.

Aktualne przeglądarek (Firefox, IE, Chrome) nie wydają się wspierać :afteri :beforepseudo-elementy do pustych elementów innych niż hr. Dla hrIE i Chrome umieścić wygenerowany zawartość wewnątrz pudełka, która graniczy jest realizacja hr; zawartość sprawia, że ​​pudełko jest wyższe. Firefox umieszcza zawartość obu (!) Pseudoelementów za poziomą regułą, jaką jest jego implementacja hr. Ta odmiana ilustruje rodzaje problemów „interakcji”, o których mowa w CSS 2.1.

Często twierdzi się, że te pseudoelementy nie mogą być używane dla pustych elementów, ponieważ ich definicje HTML nie zezwalają na jakąkolwiek zawartość. To jest błąd kategorii. Reguły składniowe języka znaczników nie ograniczają tego, co możesz zrobić w CSS

Podsumowując, :afteri :beforeobecnie nie można ich używać dla pustych elementów (z wyjątkiem marginalnie dla hr), ale jest to głównie spowodowane implementacjami i może się zmienić w przyszłości.

Jukka K. Korpela
źródło
-1

Elementy, które nie mają tagu zamykającego, są elementami void i nie mogą wyświetlać w nich zawartości:

https://www.w3.org/TR/html5/syntax.html#void-elements

Wszystkie przeglądarki Blink, Webkit i Quantum pozwalają na tworzenie pseudoelementów tylko na polach wyboru, ale jest to kontrowersyjne, ponieważ żadna specyfikacja nie zezwala na takie zachowanie.

Tutaj przykład: https://codepen.io/equinusocio/pen/BOBaEM/

input[type="checkbox"] {
  appearance: none;
  color: #000;
  width: 42px;
  height: 24px;
  border: 1px solid currentColor;
  border-radius: 100px;
  cursor: pointer;
  transition: all 100ms;
  background-size: 30%;
  outline: none;
  position: relative;
  box-sizing: border-box;
  background-color: #eee;
  transition: background-color 200ms;

  &::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    bottom: 2px;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background-color: currentColor;
    will-change: transform;
    transition: transform 200ms cubic-bezier(.01,.65,.23,1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  &:checked {
    background-color: aquamarine;

    &::before {
      transform: translateX(100%);
    }
  }
}
Mattia Astorino
źródło
nie będzie działać we wszystkich przeglądarkach ... i nie ma specyfikacji, która mówi, że teraz możemy ... jeśli masz taką, podziel się nią, ponieważ nie jest bezpiecznie rozważać pseudoelement z
danymi
Działa we wszystkich przeglądarkach oprócz IE. Nawet flexbox nie jest obsługiwany przez IE 9, więc gdzie jest problem. To rozwiązanie działa na wszystkich przeglądarkach Blink, Webkit i Quantum i może być bardzo przydatne dla osób pracujących w środowisku webkit, takim jak Electron.
Mattia Astorino,
Jak powiedziałeś w swojej odpowiedzi, nie ma na to specyfikacji, więc pewnego dnia może przestać działać. Nie jest to jedyna rzecz, która zachowuje się i działa bez określonej specyfikacji, ale nigdy nie powinniśmy na nich polegać i mówić, że działają. to jak przestarzałe tagi, nadal działają, ale powinniśmy przestać ich używać, ponieważ pewnego dnia nie będą. Więc tak, może to być przydatne dla ludzi, a moje komentarze są również przydatne, aby ostrzec ludzi, że powinni być świadomi, że to nie jest oficjalne.
Temani Afif,