Kaptan taşan esnek öğenin üstüne kaydırılamıyor


259

Bu nedenle, flexbox kullanarak faydalı bir mod oluşturmaya çalışırken, bir tarayıcı sorunu gibi görünen bir şey buldum ve bilinen bir düzeltme veya geçici çözüm olup olmadığını veya nasıl çözüleceğine dair fikir olup olmadığını merak ediyorum.

Çözmeye çalıştığım şeyin iki yönü var. İlk olarak, modal pencereyi dikey olarak ortalamak, beklendiği gibi çalışır. İkincisi, kalıcı pencerenin kaydırılmasını sağlamaktır - harici olarak, tüm modal pencere içindeki içeriği değil, kayar (bu, modalın sınırları dışına uzayabilecek açılanlar ve diğer UI öğelerine sahip olmanızdır - özel bir tarih seçici gibi)

Bununla birlikte, dikey merkezlemeyi kaydırma çubuklarıyla birleştirirken, modalın üst kısmına taşmaya başladığında erişilemez. Yukarıdaki örnekte, taşmayı zorlamak için yeniden boyutlandırabilirsiniz ve böylece modalın altına kaydırmanıza izin verir, ancak üste değil (ilk paragraf kesilir).

Örnek kodun bağlantısı (oldukça basitleştirilmiş)

https://jsfiddle.net/dh9k18k0/2/

.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  overflow-x: auto;
}
.modal-container .modal-window {
  display: -ms-flexbox;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  // Optional support to confirm scroll behavior makes sense in IE10
  //-ms-flex-direction: column;
  //-ms-flex-align: center;
  //-ms-flex-pack: center;
  height: 100%;
}
.modal-container .modal-window .modal-content {
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #fff;
  width: 100%;
  max-width: 500px;
  padding: 10px
}

Bu etkiler (mevcut) Firefox, Safari, Chrome ve Opera .. IE10 vender önek css yorum yaparsanız IE10 doğru ilginç davranır - Henüz IE11 test rahatsız etmedi, ancak davranış IE10 ile eşleşen varsayalım .

Herhangi bir fikir iyi olurdu. Bilinen sorunlara bağlantılar veya bu davranışın arkasında yatan gerekçeler de yararlı olacaktır.

Yanıtlar:


480

Sorun

Flexbox merkezlemeyi çok kolaylaştırır.

Sadece uygulayarak align-items: centervejustify-content: centerEsnek kabı esnek kabınız / eşyalarınız dikey ve yatay olarak ortalanacaktır.

Ancak, esnek öğe esnek konteynırdan daha büyük olduğunda bu yöntemle ilgili bir sorun vardır.

Soruda belirtildiği gibi, esnek öğe konteyneri taştığında üste erişilemez hale gelir.

resim açıklamasını buraya girin

Yatay taşma için, sol bölüme erişilemez (veya RTL dillerinde sağ bölüm).

İşte bir LTR konteynerine justify-content: centerve üç esnek öğeye sahip bir örnek :

resim açıklamasını buraya girin

Bu davranışın açıklaması için bu cevabın alt kısmına bakın.


Çözüm # 1

Bu sorunu düzeltmek için flexbox otomatik kenar boşluklarını kullanın,justify-content .

İle auto marjlar, bir taşan esnek öğe dikey ve yatay olarak da bir bölümünde erişimi kaybetmeden merkezli edilebilir.

Esnek konteynerdeki bu kod yerine:

#flex-container {
    align-items: center;
    justify-content: center;
}

Esnek öğede bu kodu kullanın:

.flex-item {
    margin: auto;
}

resim açıklamasını buraya girin

Gözden Geçirilmiş Demo


Çözüm # 2 (henüz çoğu tarayıcıda uygulanmadı)

Ekle safeBu gibi anahtar kelime hizalama kuralın değerini:

justify-content: safe center

veya

align-self: safe center

Gönderen CSS Kutu Hizalama Modülü şartname :

4.4. Taşma Hizalaması: safeve unsafeanahtar sözcükleri ve kaydırma güvenliği sınırları

[Flex öğesi] [flex kabı] 'ndan daha büyük olduğunda taşar. Bazı hizalama modları, bu durumda onurlandırılırsa, veri kaybına neden olabilir: örneğin, bir kenar çubuğunun içeriği ortalanmışsa, taştıklarında kutularının bir kısmını görünümün başlangıç ​​kenarından geçerek kaydırılamazlar .

Bu durumu kontrol etmek için bir taşma hizalama modu açıkça belirtilebilir. Unsafehizalama, veri kaybına neden olsa bile taşma durumlarında belirtilen hizalama modunu onurlandırırken, hizalama veri kaybını safeönlemek için taşma durumlarında hizalama modunu değiştirir.

Varsayılan davranış, kaydırılabilir alandaki hizalama konusunu içermektir, ancak yazma sırasında bu güvenlik özelliği henüz uygulanmamıştır.

safe

[Flex öğesinin] boyutu [flex konteynerinden] taşarsa, [flex öğesi] bunun yerine hizalama modu [ flex-start] gibi hizalanır .

unsafe

[Flex öğesi] ve [flex kabı] 'nın göreceli boyutlarından bağımsız olarak, verilen hizalama değeri dikkate alınır.

Not: Kutu Hizalama Modülü, yalnızca esnek değil, birden çok kutu düzeni modelinde kullanım içindir. Dolayısıyla yukarıdaki spesifik alıntıda, parantez içindeki terimler aslında "hizalama konusu", "hizalama kabı" ve " start" der . Bu soruna odaklanmak için esnekliğe özgü terimler kullandım.


MDN'den kaydırma sınırlaması için açıklama:

Esnek öğe değerlendirmeleri

Flexbox'ın hizalama özellikleri, CSS'deki diğer merkezleme yöntemlerinin aksine "gerçek" merkezleme yapar. Bu, esnek nesnelerin esnek kabı taşmasına rağmen ortalanmış kalacağı anlamına gelir.

Bununla birlikte, sayfanın üst kenarından veya sol kenarından [...] taşarlarsa bu bazen sorunlu olabilir, çünkü orada içerik olsa bile bu alana geçemezsiniz!

Gelecekteki bir sürümde, hizalama özellikleri de "güvenli" bir seçeneğe sahip olacak şekilde genişletilecektir.

Şimdilik, bu bir endişe ise, merkezlemeyi elde etmek için kenar boşluklarını kullanabilirsiniz, çünkü bunlar "güvenli" bir şekilde yanıt verecek ve taşmaları durumunda merkezlemeyi durduracaklardır.

align-Özellikleri kullanmak yerine, ortalamak autoistediğiniz esnek öğelerin kenar boşluklarını koymanız yeterlidir.

Onun yerine justify- , esnek kaptaki ilk ve son esnek öğelerin dış kenarlarına otomatik kenar boşlukları koyun.

autoMarjları "esnek" ve mekan artık olduğunda esnek öğeleri ortalamak, ve ne zaman normal uyum geçiş, artık uzay üstlenecek.

Ancak, justify-contentçok satırlı bir esnek kutuda kenar boşluğu tabanlı merkezleme ile değiştirmeye çalışıyorsanız , her satırdaki ilk ve son esnek öğenin kenar boşluklarını koymanız gerektiğinden muhtemelen şansınız kalmaz. Hangi öğelerin hangi satıra geleceğini önceden tahmin edemezseniz, justify-contentözelliği değiştirmek için ana eksendeki marj tabanlı merkezlemeyi güvenilir bir şekilde kullanamazsınız .


4
Evet, bu daha iyi bir çözüm ve ek değerli bilgiler sağladığınız için teşekkür ederiz.
jejacks0n

1
IE11'de çalışmadığı unutulmamalıdır. Arka plan kesilecek.
Daniel

2
@ Daniel, ben sadece IE11 kodu test. Hiçbir şeye erişilemez. Aslında, soruda açıklanan sorun IE11'de bile mevcut değildir. Yalnızca IE11'de gerçekleşen metin taşmasına atıfta bulunuyorsunuz. Bu başka bir soru için başka bir mesele.
Michael Benjamin

11
IE11'deki sorunu düzeltmek için: align-items: flex-startflex kabına ekleyin ve margin: autoflex öğesini saklayın .
Eugene Fidelin

2
Esnek yön: sütunu kullanılırken bu benim için çalışmaz;
Stefan

22

Murphy Kanununda olduğu gibi, bu soruyu gönderdikten sonra yaptığım okuma birkaç sonuçla sonuçlandı - tamamen çözülmedi, ancak yine de yararlı oldu.

Göndermeden önce minimum yükseklikle oynadım, ancak spesifikasyon için oldukça yeni olan içsel boyutlandırma kısıtlamalarının farkında değildim.

http://caniuse.com/#feat=intrinsic-width

min-height: min-contentEsnek kutu alanına a eklemek , Chrome'daki sorunu çözer ve Firefox çözümlenmemiş kalmasına rağmen, satıcı önekleriyle Opera ve Safari de giderilir.

min-height: -moz-min-content; // not implemented
min-height: -webkit-min-content // works for opera and safari
min-height: min-content // works for chrome

Hala Firefox ve diğer potansiyel çözümler hakkında fikirler arıyor.


Firefox'ta zaten benim için çalıştığını söylemek istedim. Böylece min içerikli çözüm mükemmeldi.
pudgereyem

@pudgereyem Sanırım uyguladılar. Diğer çözüm benim için çalışmayı margin: autodurdururken flex-basis, bu cevap her iki sorunu da çözdü.
Martin Dawson

Gerçekten de mükemmel bir çözüm. Edge veya IE umurumda değil, bu yüzden benim için mükemmel çalışıyor!
Ohgodwhy

18

Bunu sadece 3 konteynırla çekmeyi başardım. İşin püf noktası, esnek kutu kabını kaydırmayı kontrol eden kaptan ayırmaktır. Son olarak, hepsini ortalamak için her şeyi bir kök kaba koyun. Efekti oluşturmak için gerekli stiller:

CSS:

.root {
  display: flex;
  justify-content: center;
  align-items: center;
}

.scroll-container {
  margin: auto;
  max-height: 100%;
  overflow: auto;
}

.flex-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

HTML:

<div class="root">
  <div class="scroll-container">
    <div class="flex-container">
      <p>Lorem ipsum dolor sit amet.</p>
    </div>
  </div>
</div>

Burada bir demo oluşturdum: https://jsfiddle.net/r5jxtgba/14/


kaydırma konteyner ipuçları için thx, ben benim kaydırma kaydırma düzeltme için iki günden beri aradım !!!
artSx

, do not vermek hatırlamak flex: 1 1 autoiçin scroll-container. Bunu alışkanlıkla yapıyordum ve sorun yaşadım.
AmirHossein

1
Jsfiddle, kap içine daha fazla içerik eklediğinizde çalışmadığını gösterir.
bplittle

4

Sanırım bir çözüm buldum. Çok sayıda metin ve küçük bir metinle çalışır . Hiçbir şeyin genişliğini belirtmeniz gerekmez ve IE8'de çalışması gerekir .

.wrap1 {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  overflow-y: auto;
}
.wrap2 {
  display: table;
  width: 100%;
  height: 100%;
  text-align: center;
}
.wrap3 {
  vertical-align: middle;
  display: table-cell;
}
.wrap4 {
  margin: 10px;
}
.dialog {
  text-align: left;
  background-color: white;
  padding: 5px;
  border-radius: 3px;
  margin: auto;
  display: inline-block;
  box-shadow: 2px 2px 4px rgba(0, 0, 0, .5);
}
<div class="wrap1">
  <div class="wrap2">
    <div class="wrap3">
      <div class="wrap4">
        <div class="dialog">
          <p>Lorem ipsum dolor sit amet.</p>
        </div>
      </div>
    </div>
  </div>
</div>


Bu, eski tarayıcılar için en iyi çözümdür. Çok teşekkür ederim!
Daniel

5
Vay be, bu çok fazla şey.
Nathan Arthur

1
Vay be, bunu başarmak için saatler harcadım . (Animasyon eklediğinizde diğer tüm yöntemler mobil kromda başarısız olur. Bu olmaz) Çok teşekkür ederim!
falsePockets

1

MDN'ye göre, safedeğer şimdi align-itemsve gibi özelliklere verilebilir justify-content. Aşağıdaki gibi açıklanmıştır:

Öğenin boyutu hizalama kabından taşarsa, öğe hizalama modu gibi hizalanır start.

Yani, aşağıdaki gibi kullanılabilir.

.rule
{
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: safe center;
}

Bununla birlikte, ne kadar tarayıcı desteğine sahip olduğu belli değil, kullanımıyla ilgili herhangi bir örnek bulamadım ve kendimle ilgili bazı sorunlar yaşıyorum. Burada daha fazla dikkat çekmek için bahsediyoruz.


7 Haziran 2018'de hala kromda uygulanmadı.
AmirHossein

(Şu anki) MDN sayfalarına göre, "güvenli" ve "güvensiz" hala bu noktada yalnızca Firefox'tur (Safari ve çoğu mobil tarayıcının bilinmeyen desteği var - bunu güvenli oynarım ve destek olmadığını varsayıyorum).
JaMiT

MDN, Firefox desteğini bildirdi, ancak Firefox'ta test ettiğimde işe yaramadı. jsbin.com/pimoqof/1/edit?html,css,output
Oliver Joseph Ash

Haziran 2020 ve çoğu tarayıcıda değil, caniuse göre
den232

0

Ayrıca ekstra konteyner kullanarak yapmayı başardım

HTML

<div class="modal-container">
  <div class="modal">
    <div class="content-container">
       <div class="content">
         <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
        </div>
      </div>
  </div>  
</div>

CSS

.modal-container {
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: black;
}

.modal {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #aaa;
  height: 80%;
  width: 90%;
}

.content-container {
  background-color: blue;
  max-height: 100%;
  overflow: auto;
  padding:0;
}

.content {
  display: flex;
  background-color: red;
  padding: 5px;
  width: 900px;
  height: 300px;
}

jsfiddle> https://jsfiddle.net/Nash171/cpf4weq5/

içerik genişlik / yükseklik değerlerini değiştirin ve bkz.


0

2 Table flexback ile Konteyner Flex Yöntemi test IE8-9, flex IE10,11 çalışır. Düzenleme: Minimum içerik olduğunda dikey merkezleme sağlamak için düzenlendi, eski destek eklendi.

Sorun, Michael'ın cevapladığı gibi, çocukların taşmasına neden olan görünüm boyutundan miras alınmasından kaynaklanıyor. https://stackoverflow.com/a/33455342/3500688

daha basit bir şey ve mizanpajı konteyner içinde düzenlemek için flex kullanın (içerik):

#popup {
position: fixed;
top: 0;
left: 0;
right: 0;
min-height: 100vh;
background-color: rgba(0,0,0,.25);
margin: auto;
overflow: auto;
height: 100%;
bottom: 0;
display: flex;
align-items: flex-start;
box-sizing:border-box;
padding:2em 20px;
}
.container {
background-color: #fff;
margin: auto;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
/* width: 100%; */
max-width: 500px;
padding: 10px;
    /* display: flex; */
    /* flex-wrap: wrap; */
}
		<!--[if lt IE 10]>
<style>
	  #popup {
			display: table;
			width:100%;
		}
		.iewrapper {
			display: table-cell;
			vertical-align: middle;
		}
	</style>
	<![endif]-->
<div id="popup">
	<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
    <div class="container">
        <p class="p3">Test</p>
    <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    </div>
	<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
</div>

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.