Flex / Grid düzenleri düğme veya alan kümesi öğeleri üzerinde çalışmıyor


91

Bir <button>etiketin iç öğelerini flexbox'larla ortalamaya çalışıyorum justify-content: center. Ancak Safari onları ortalamıyor. Aynı stili diğer tüm etiketlere uygulayabilirim ve amaçlandığı gibi çalışır (bkz. <p>-Tag). Yalnızca düğme sola hizalanır.

Firefox veya Chrome'u deneyin ve farkı görebilirsiniz.

Üzerine yazmam gereken herhangi bir kullanıcı aracısı stili var mı? Ya da bu soruna başka bir çözüm?

div {
  display: flex;
  flex-direction: column;
  width: 100%;
}
button, p {
  display: flex;
  flex-direction: row;
  justify-content: center;
}
<div>
  <button>
    <span>Test</span>
    <span>Test</span>
  </button>
  <p>
    <span>Test</span>
    <span>Test</span>
  </p>
</div>

Ve bir jsfiddle: http://jsfiddle.net/z3sfwtn2/2/


Yanıtlar:


132

Sorun

Bazı tarayıcılarda <button>öğe, ve displayarasında geçiş yapmanın ötesinde değerindeki değişiklikleri kabul etmez . Bu, bir elemanın esnek veya ızgara kapsayıcı veya a olamayacağı anlamına gelir .blockinline-block<button><table>

Öğelere ek olarak <button>, bu kısıtlamanın <fieldset>ve <legend>öğelerine de uygulandığını görebilirsiniz .

Daha fazla ayrıntı için aşağıdaki hata raporlarına bakın.

Not: Esnek kaplar olmasalar da, <button>öğeler esnek öğeler olabilir.


Çözüm

Bu sorunun tarayıcılar arası basit ve kolay bir çözümü vardır:

İçeriğini sarın buttonbir de span, ve yapmak spanesnek konteyner.

Düzenlenmiş HTML (bir içinde sarmalanmış buttoniçerik span)

<div>
    <button>
        <span><!-- using a div also works but is not valid HTML -->
            <span>Test</span>
            <span>Test</span>
        </span>
    </button>
    <p>
        <span>Test</span>
        <span>Test</span>
    </p>
</div>

Düzeltilmiş CSS (hedeflenmiş span)

button > span, p {
    display: flex;
    flex-direction: row;
    justify-content: center;
}

Gözden Geçirilmiş Demo


Referanslar / Hata Raporları

Bir üzerindeki <button>Flexbox içeriği bloke eder, ancak bir esnek biçimlendirme bağlamı oluşturmaz

Kullanıcı (Oriol Brufau): Çocukların <button>blockified edilir, zorunluluk mahiyetinde FlexBox Spec. Bununla birlikte, <button>esnek olan yerine bir blok biçimlendirme bağlamı oluşturuyor gibi görünüyor.

Kullanıcı (Daniel Holbert): Bu, HTML spesifikasyonunun gerektirdiği şeydir. Birkaç HTML kapsayıcı öğesi "özeldir" ve Gecko'daki CSS displaydeğerlerini etkin bir şekilde yok sayar [satır içi düzey ile blok düzeyi arasında olması dışında]. <button>bunlardan biri. <fieldset>ve <legend>aynı zamanda.

Görüntü desteği ekleyin: <button>elemanların içinde esnek / ızgara ve sütun kümesi düzeni

Kullanıcı (Daniel Holbert):

<button>saf CSS'de uygulanamaz (tarayıcılar tarafından), bu yüzden CSS açısından biraz kara kutu gibidirler. Bu, örneğin a'nın yapacağı gibi tepki vermeleri gerekmediği anlamına gelir <div> .

Bu flexbox'a özgü değildir - örneğin overflow:scroll, bir düğme koyarsanız kaydırma çubuklarını oluşturmayız ve üzerine koyarsanız onu bir tablo olarak oluşturmayız display:table.

Daha da geri adım atmak, buna özgü değil <button>. Düşünün <fieldset>ve <table>hangilerinin özel oluşturma davranışına sahip olduğunu düşünün .

Gibi Ve eski parçaları HTML öğeleri <button>ve <table>ve <fieldset>sadece özel desteklemeyen displayelemanı etrafında diğer içerikleri akan değerlerini, çok yüksek seviyeli soruya cevap amacıyla dışında "bu elemanları blok seviyesinden veya satır içi-seviyesidir", .

Ayrıca bkz:


3
Neden <button>s için işe yaramayabileceğini anlıyorum , ama neden bu <fieldset>ikisi için de çalışmıyor ? Bu öğenin, esnek bir konteyner için geçerli olan normal bir blok seviyesi öğesi olarak kabul edilmesi gerekmez mi?
fritzmg

3
@fritzmg. Kabul. Kural muhtemelen Flex ve Grid gibi CSS3 teknolojilerinden önce mevcuttur ve yeniden değerlendirilmelidir.
Michael Benjamin

Bu nedenle, bir düğmenin kötüye kullanılmasını önlemek istiyoruz ... ancak yine de başka bir şeyi kötüye kullanabilir ve düğmenin içine yerleştirebiliriz. Web'in geri kalanı kadar mantıklı geliyor ...
Romain Vincent

1
@Michael_B Gerçek metne atıfta bulunduğunuz yere bir referans eklemeyi düşünün. Yorumuma cevap vermenize gerek yok - eğer bunu iddiada bulunduğunuz metne eklerseniz size bir oy vereceğim.
mikemaccana

2
A div, a'nın çocuğu olamaz buttonçünkü eski okul HTML'sinde düşünürseniz, blok düzeyindeki bir öğe, satır içi düzeydeki öğenin çocuğu olamaz. Ancak bugün HTML5 ile teknik olarak doğru cevap, bir buttonöğenin yalnızca Cümle İçeriği kabul edebileceğidir . A span, İfade İçeriğini temsil eder , ancak a divdeğildir. A div, Akış İçeriğini temsil eder . Daha fazla ayrıntı
Michael Benjamin


1

Chrome 83'ten başlayarak, buttonartık çalışıyor inline-grid/grid/inline-flex/flex, bu yeni özellik hakkında daha fazla bilgiyi burada bulabilirsiniz.

İşte bir snippet (Chrome 83 ve üstünü kullananlar için)

button {
  display: inline-flex;
  height: 2rem;
  align-items: flex-end;
  width: 4rem;
  -webkit-appearance: none;
  justify-content: flex-end;
}
<!-- 

The align-items keyword should fail in Chrome 81 or earlier, but work in Chrome 83 or later. To see the error, the button needs styles that make it more of an extrinsic container. In other words, it needs a height or width set. 
 
-->
<button>Hi</button>
<input type="button" value="Hi">

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.