Korzystanie z „margin: 0 auto;” w przeglądarce Internet Explorer 8

81

Jestem w trakcie przeprowadzania zaawansowanych testów IE8 i wygląda na to, że stara technika używania margin: 0 auto;nie działa we wszystkich przypadkach w IE8.

Poniższy fragment kodu HTML zawiera wyśrodkowany przycisk w FF3, Opera, Safari, Chrome, IE7 i IE8, ale NIE w standardzie IE8:

<div style="height: 500px; width: 500px; background-color: Yellow;">
    <input type="submit" style="display: block; margin: 0 auto;" />
</div>

(Aby obejść ten problem, mogę dodać wyraźną szerokość do przycisku).

Pytanie brzmi: które przeglądarki są poprawne? Czy jest to jeden z tych przypadków, w których zachowanie jest nieokreślone?

(Myślę, że wszystkie przeglądarki są nieprawidłowe - czy przycisk nie powinien mieć 100% szerokości, jeśli jest to „display: block”?)

UPDATE: Jestem głupkiem. Ponieważ dane wejściowe nie są elementem blokowym, powinienem po prostu zawrzeć je w elemencie div za pomocą „text-align: center”. Powiedziawszy to, ze względu na ciekawość, nadal chciałbym wiedzieć, czy przycisk powinien, czy nie powinien być wyśrodkowany w powyższym przykładzie.

DLA BOUNTY: Wiem, że robię dziwne rzeczy w tym przykładzie i jak wskazałem w aktualizacji, powinienem po prostu wyrównać to do środka. Jeśli chodzi o nagrodę, chciałbym odwołać się do specyfikacji, które odpowiadają:

  1. Jeśli ustawię „display: block”, czy przycisk powinien mieć szerokość 100%? Czy jest to niezdefiniowane?

  2. Ponieważ wyświetlacz jest blokowy, powinien "margin: 0 auto;" wyśrodkować przycisk, czy nie, czy undefined?

stusmith
źródło
Lepiej się pospiesz: IE8 RTM jest już dziś i będzie dostępny do pobrania za około 2 godziny.
Joel Coehoorn
Wciąż jest w fazie beta, więc brak pełnej obsługi IE8 to tylko jedna z wielu rzeczy, które należy naprawić przed wydaniem.
stusmith

Odpowiedzi:

71

Jest to błąd w IE8.

Zaczynając od drugiego pytania: „margin: 0 auto” centruje blok, ale tylko wtedy, gdy szerokość bloku jest ustawiona na mniejszą niż szerokość elementu nadrzędnego. Zazwyczaj stają się takie same. Dlatego tekst w poniższym przykładzie nie jest wyśrodkowany.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
    <b style="display: block; margin: 0 auto; ">text</b>
</div>

Gdy styl wyświetlania elementu b jest ustawiony na blok, jego szerokość jest domyślnie ustawiona na szerokość nadrzędną. Specyfikacja CSS 10.3.3 Niezastępowane elementy na poziomie bloku w normalnym przepływie opisuje, jak: „Jeśli„ szerokość ”jest ustawiona na„ auto ”, wszelkie inne wartości„ auto ”przyjmują wartość„ 0 ”, a„ szerokość ”wynika z wynikowej równości . ” Wspomniana tam równość jest

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = szerokość zawierającego bloku

Tak więc, zwykle wszystkie automaty powodują, że szerokość bloku jest równa szerokości bloku zawierającego.

Jednak tego obliczenia nie należy stosować do INPUT, który jest elementem zastępowanym. Wymienione elementy są objęte 10.3.4 na poziomie bloku, wymienione elementy w normalnym przepływie . Tekst tam mówi: „Użyta wartość 'width' jest określana tak, jak dla elementów zastępowanych w wierszu.” Odpowiednia część 10.3.2 Inline, elementy zastępowane to: „jeśli„ szerokość ”ma obliczoną wartość„ auto ”, a element ma wewnętrzną szerokość, wówczas ta wewnętrzna szerokość jest używaną wartością„ szerokości ””.

Myślę, że scenariusz, na którym zależy CSS, to element IMG. Logo Stackoverflow w tym przykładzie będzie wyśrodkowane we wszystkich przeglądarkach.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
    <img style="display: block; margin: 0 auto; " border="0" src="http://stackoverflow.com/content/img/so/logo.png" alt="">
</div>

Element INPUT powinien zachowywać się w ten sam sposób.

buti-oxa
źródło
155

Dodanie <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">rozwiązuje problem

Kumpel
źródło
13
Bez DOCTYPE IE automatycznie przechodzi w tryb renderowania Osobliwości. Pomocne :-)
Andy McCluggage
7
TAKŻE nie powiedzie się, jeśli masz coś przed doctype (np. Komentarze, rozpoczynający się tag html itp.)
Shanimal
Również z bootstrapem złamał wszystko
user956584
5

Tak, możesz przeczytać specyfikację sto razy i łączyć różne fragmenty, aż uzyskasz właściwą interpretację - ale dokładnie to zrobili dostawcy przeglądarek i dlatego jesteśmy w takiej sytuacji, w jakiej jesteśmy dzisiaj.

Zasadniczo, kiedy zastosujesz szerokość 100% do elementu, powinien on rozciągnąć się do 100% szerokości swojego rodzica, jeśli ten rodzic jest elementem blokowym. Nie możesz już go wyśrodkować, margin: 0 auto;ponieważ zajmuje już 100% dostępnej szerokości.

Aby cokolwiek wyśrodkować margin: 0 auto;, musisz zdefiniować wyraźną szerokość. Aby wyśrodkować element wbudowany, możesz użyć go text-align: center;na elemencie nadrzędnym, chociaż może to mieć niepożądane skutki uboczne, jeśli rodzic ma inne dzieci.

Wolfr
źródło
5

Kontrolki formularza są zastępowanymi elementami w CSS.

10.3.4 Na poziomie bloku, wymienione elementy w normalnym przepływie

Użyta wartość „width” jest określana jak dla elementów zastępowanych w wierszu . Następnie w celu określenia marginesów stosowane są reguły dotyczące niezastąpionych elementów blokowych.

Dlatego formant formularza nie powinien być rozciągany do 100% szerokości.

Jednak powinien być wyśrodkowany. Wygląda jak zwykły błąd w IE8. Wyśrodkowuje element, jeśli ustawisz określoną szerokość:

<input type="submit" style="display: block; width:100px; margin: 0 auto;" />
Kornel
źródło
3

Jak wyjaśnił buti-oxa, jest to błąd związany ze sposobem, w jaki IE8 obsługuje zastąpione elementy. Jeśli nie chcesz dodawać wyraźnej szerokości do swojego przycisku, możesz zmienić go na blok inline i wyśrodkować zawartość:

<div style="height: 500px; width: 500px; background-color: Yellow; text-align: center;">
  <input type="submit" style="display: inline-block;" />
</div>

Jeśli chcesz, aby to działało w starszych wersjach Mozilli (w tym FF2), które nie obsługują blokowania inline, możesz dodać display: -moz-inline-stack;to do przycisku.

Simon Dyson
źródło
2

O ile jest to „błąd” w stosunku do specyfikacji; nie jest. Jako autor pytań posta zachowanie w tym przypadku byłoby „nieokreślone”, ponieważ takie zachowanie w IE występuje tylko w kontrolkach formularza, zgodnie ze specyfikacją:

CSS 2.1 nie definiuje, które właściwości mają zastosowanie do kontrolek formularzy i ramek ani jak można użyć CSS do ich stylizacji. Programy użytkownika mogą stosować właściwości CSS do tych elementów. Zaleca się autorom traktowanie takiego wsparcia jako eksperymentalnego.

( http://www.w3.org/TR/CSS21/conform.html#conformance )

Twoje zdrowie!


źródło
2

Jeszcze raz: wszyscy nienawidzimy IE!

<div style="width:100%;background-color:blue;">
    <div style="margin:0 auto;width:300px;background-color:red;">
        Not Working
    </div>
</div>

<div style="width:100%;background-color:green;text-align:center;">
    <div style="margin:0 auto;width:300px;background-color:orange;text-align:left;">
        Working, but dumb that you have to use text-align
    </div>
</div>
zeroasterisk
źródło
2

próbowałem wszystkich powyższych, w końcu robiąc to

<div style="width:100%; background-color:red; text-align:center;">
        <div style="width:900px; margin:0 auto; background-color:blue;">
            hello
        </div>
    </div>
Rouslan Karimov
źródło
2

Dodaj <!doctype html>u góry wyjścia HTML.

Mohammad Naji
źródło
1

przycisk nie powinien mieć 100% szerokości, jeśli jest to „display: block”

Nie. To po prostu oznacza, że ​​jest to jedyna rzecz w przestrzeni w pionie (zakładając, że nie używasz innej sztuczki, aby wymusić coś innego). Nie oznacza to, że musi wypełniać szerokość tej przestrzeni.

Myślę, że twój problem w tym przypadku polega na tym, że inputnatywnie nie jest elementem blokowym. Spróbuj zagnieździć go w innym elemencie div i ustaw na nim margines. Ale w tej chwili nie mam przeglądarki IE8, aby to przetestować, więc to tylko przypuszczenie.

Joel Coehoorn
źródło
1

„margin: 0 auto” wyśrodkowuje element w IE tylko wtedy, gdy element nadrzędny ma „text-align: center”.

Chris
źródło
0
  1. Zakładając, margin: 0 autoże element powinien być wyśrodkowany, ale szerokość pozostaje taka, jaka jest - niezależnie od tego, na co jest obliczana, z pominięciem jakichkolwiek ustawień marginesów.
  2. Jeśli ustawisz <INPUT>tag na display:block, to powinien być wyśrodkowany za pomocą margin: 0 auto.

Zobacz szczegóły modelu formatowania wizualnego - obliczanie szerokości i marginesów na podstawie specyfikacji CSS 2.1, aby uzyskać więcej informacji. Relavent bity obejmują:

W kontekście formatowania bloku lewa zewnętrzna krawędź każdego pola styka się z lewą krawędzią bloku zawierającego.

i

Gdy całkowita szerokość pól liniowych w wierszu jest mniejsza niż szerokość pola liniowego, które je zawiera, ich rozmieszczenie w poziomie w polu liniowym jest określone przez właściwość „text-align”.

Wreszcie

Jeśli „szerokość” jest ustawiona na „auto”, wszelkie inne wartości „auto” zmieniają się na „0”, a „szerokość” wynika z wynikowej równości.

Jeśli zarówno „margin-left”, jak i „margin-right” mają wartość „auto”, ich użyte wartości są równe. Powoduje to wyśrodkowanie elementu w poziomie w stosunku do krawędzi bloku zawierającego.

Jon Adams
źródło