जब फ्लेक्सबॉक्स आइटम कॉलम मोड में लपेटते हैं, तो कंटेनर इसकी चौड़ाई नहीं बढ़ाता है


167

मैं नेस्टेड फ्लेक्सबॉक्स लेआउट पर काम कर रहा हूं जो निम्नानुसार काम करना चाहिए:

सबसे बाहरी स्तर ( ul#main) एक क्षैतिज सूची है जिसे अधिक वस्तुओं के साथ जोड़े जाने पर दाईं ओर विस्तृत होना चाहिए। यदि यह बहुत बड़ा हो जाता है, तो एक क्षैतिज स्क्रॉल पट्टी होनी चाहिए।

#main {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    /* ...and more... */
}

इस सूची के प्रत्येक आइटम में ul#main > liहेडर ( ul#main > li > h2) और एक आंतरिक सूची ( ul#main > li > ul.tasks) है। यह आंतरिक सूची वर्टिकल है और जरूरत पड़ने पर कॉलम में लिपट जाना चाहिए। अधिक स्तंभों में लपेटते समय, अधिक वस्तुओं के लिए जगह बनाने के लिए इसकी चौड़ाई बढ़नी चाहिए। यह चौड़ाई वृद्धि बाहरी सूची के युक्त आइटम पर भी लागू होनी चाहिए।

.tasks {
    flex-direction: column;
    flex-wrap: wrap;
    /* ...and more... */
}

मेरी समस्या यह है कि जब खिड़की की ऊंचाई बहुत छोटी हो जाती है, तो आंतरिक सूचियाँ नहीं लपेटती हैं। मैंने सभी फ्लेक्स गुणों के साथ बहुत छेड़छाड़ की कोशिश की है, सीएसएस-ट्रिक्स में दिशानिर्देशों का सावधानीपूर्वक पालन ​​करने की कोशिश कर रहा हूं , लेकिन भाग्य नहीं।

यह JSFiddle दिखाता है कि मेरे पास अब तक क्या है।

अपेक्षित परिणाम (मुझे क्या चाहिए) :

मेरा वांछित उत्पादन

वास्तविक परिणाम (मुझे क्या मिलेगा) :

मेरा वर्तमान आउटपुट

पुराना परिणाम (2015 में मुझे जो मिला) :

मेरा पुराना आउटपुट

अपडेट करें

कुछ जांच के बाद, यह एक बड़े मुद्दे की तरह लग रहा है। सभी प्रमुख ब्राउज़र एक ही तरह से व्यवहार करते हैं , और इसका मेरे फ्लेक्सबॉक्स डिज़ाइन के साथ कोई संबंध नहीं है। यहां तक ​​कि सरल फ्लेक्सबॉक्स कॉलम लेआउट आइटम लपेटने पर सूची की चौड़ाई बढ़ाने से इनकार करते हैं।

यह अन्य JSField स्पष्ट रूप से समस्या को दर्शाता है। क्रोम, फ़ायरफ़ॉक्स और IE11 के वर्तमान संस्करणों में, सभी आइटम सही ढंग से लपेटते हैं; सूची की ऊंचाई rowमोड में बढ़ती है, लेकिन इसकी चौड़ाई columnमोड में नहीं बढ़ती है। साथ ही, किसी columnमोड की ऊँचाई को बदलते समय तत्वों का कोई तात्कालिक प्रतिक्षेप नहीं होता है , लेकिन rowमोड में है।

हालांकि, आधिकारिक चश्मा (उदाहरण 5 पर विशेष रूप से देखें) से यह संकेत मिलता है कि मैं जो करना चाहता हूं वह संभव होना चाहिए।

क्या कोई इस समस्या के समाधान के साथ आ सकता है?

अद्यतन २

घटनाओं का आकार बदलने के दौरान विभिन्न तत्वों की ऊंचाई और चौड़ाई को अद्यतन करने के लिए जावास्क्रिप्ट का उपयोग करने के बाद बहुत सारे प्रयोग करने के बाद, मैं इस निष्कर्ष पर पहुंचा हूं कि यह बहुत जटिल है और इसे हल करने के लिए बहुत अधिक परेशानी है। साथ ही, जावास्क्रिप्ट को जोड़ने से फ्लेक्सबॉक्स मॉडल निश्चित रूप से टूट जाता है, जिसे यथासंभव साफ रखा जाना चाहिए।

अभी के लिए, मैं overflow-y: autoइसके बजाय वापस गिर रहा हूं flex-wrap: wrapताकि जरूरत पड़ने पर आंतरिक कंटेनर लंबवत स्क्रॉल करें। यह सुंदर नहीं है, लेकिन यह एक ऐसा तरीका है जो कम से कम उपयोग करने की क्षमता को नहीं तोड़ता है।


2
बस एक सिडेनोट, लेकिन क्रोम में एक बग होता है, जिसके साथ एक कंटेनर का प्रवाह होता है, जिसे column wrapलपेटते समय इसकी चौड़ाई का विस्तार नहीं करने के लिए सेट होता है। अधिक जानकारी के लिए code.google.com/p/chromium/issues/detail?id=247963 देखें ।
गेरिट बर्टियर

मैं इसे IE11 में काम करने के लिए नहीं मिल सकता है। वहां, अंतरतम वस्तुएं लपेटती हैं, लेकिन आंतरिक सूची और इसके कंटेनर (बाहरी वस्तु) उनकी चौड़ाई में वृद्धि नहीं करते हैं। वर्तमान में मैं आंतरिक सूचियों को स्क्रॉल करने के लिए वापस आ रहा हूं, लेकिन यह एक अच्छा दीर्घकालिक समाधान नहीं है, और मैं वास्तव में इस पर जावास्क्रिप्ट को जोड़ने से बचना चाहूंगा।
एंडर्स टॉर्बलाड

जवाबों:


170

समस्या

यह फ्लेक्स लेआउट में मूलभूत कमी की तरह दिखता है।

स्तंभ-दिशा में एक फ्लेक्स कंटेनर अतिरिक्त स्तंभों को समायोजित करने के लिए विस्तारित नहीं होगा। (इसमें कोई समस्या नहीं है flex-direction: row।)

यह सवाल कई बार पूछा गया है (नीचे सूची देखें), सीएसएस में कोई साफ जवाब नहीं है।

यह एक बग के रूप में पिन करना मुश्किल है क्योंकि समस्या सभी प्रमुख ब्राउज़रों में होती है। लेकिन यह सवाल उठाता है:

यह कैसे संभव है कि सभी प्रमुख ब्राउज़रों को पंक्ति-दिशा में रैप पर विस्तार करने के लिए फ्लेक्स कंटेनर मिले लेकिन कॉलम-दिशा में नहीं?

आपको लगता है कि उनमें से कम से कम एक सही होगा। मैं केवल कारण पर अटकलें लगा सकता हूं। शायद यह तकनीकी रूप से कठिन कार्यान्वयन था और इस पुनरावृत्ति के लिए आश्रय लिया गया था।

अद्यतन: मुद्दा एज v16 में हल किया गया प्रतीत होता है।


समस्या का चित्रण

ओपी ने समस्या को दर्शाते हुए एक उपयोगी डेमो बनाया। मैं इसे यहाँ कॉपी कर रहा हूँ: http://jsfiddle.net/nwccdwLw/1/


वैकल्पिक हल

स्टैक ओवरफ्लो समुदाय से हैकी समाधान:


अधिक विश्लेषण


अन्य पोस्ट उसी समस्या का वर्णन करते हुए


2
बग रिपोर्ट की टिप्पणियों के अनुसार, यह मुद्दा तब तक तय नहीं किया जाएगा जब तक कि वे अपने नए लेआउट इंजन LayoutNG
Ben.12

5
आपके द्वारा प्रदान किए गए और उन्हें वर्गीकृत किए गए लिंक की संख्या वास्तव में बहुत अच्छी है। काश ज्यादातर लोग इस तरह से उत्तर लिखते। बहुत बढ़िया जवाब।
विग्नेश

4
यहां उनके लिए कई फ्लेक्सबॉक्स बग्स और वर्कअराउंड्स की उपयोगी रेपो सूची दी गई है: यह बग # 14 पर सूचीबद्ध है
Ben.12

क्या हम CSS ग्रिड का उपयोग करके इस समस्या को ठीक कर सकते हैं?
इस्माइल फारुख

एक और अधिक वैकल्पिक विकल्प: codepen.io/_mc2/pen/PoPmJRP कुछ पहलुओं के लिए मुझे यह बेहतर लगा कि राइट-मोड दृष्टिकोण
michalczerwinski

37

पार्टी के लिए देर से, लेकिन बाद में इस मुद्दे पर चल रहा था। ग्रिड का उपयोग करके एक समाधान खोजने का प्रयास किया। कंटेनर पर आप उपयोग कर सकते हैं

display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(6, auto);

मेरे पास CodePen पर एक उदाहरण है जो flexbox समस्या और ग्रिड फिक्स के बीच टॉगल करता है: https://codepen.io/MandeeD/pen/JVLdLd


1
अगर मैंने कभी देखा है तो यह एक सुंदर समाधान है! मैं अभी ग्रिड में जा रहा हूं और मुझे आपके समाधान से प्यार है, इसके लिए आपको धन्यवाद।
अल्बर्ट

सटीक! मेरा मुद्दा हल किया।
सेलेस्टिन बोचिस

अभी भी क्रोम में इस मुद्दे पर चल रहा है। मैं ग्रिड वर्कअराउंड का उपयोग करने से बचने की उम्मीद कर रहा था। दूसरों को यह जानने के लिए अच्छा है कि वे इस दृष्टिकोण का उपयोग कर रहे हैं!
trukvl

जीवन बचाने। grid-row-end: span X;यदि आप अधिक पंक्तियों को लेने के लिए कुछ वस्तुओं की आवश्यकता है, तो आप इसका उपयोग भी कर सकते हैं ।
मेयरियन ह्यूजेस

0

यह दुर्भाग्यपूर्ण है कि इतने बड़े ब्राउज़र कई वर्षों के बाद इस बग से पीड़ित हैं। एक जावास्क्रिप्ट समाधान पर विचार करें। जब भी ब्राउज़र विंडो का आकार बदलता है, या सामग्री को तत्व में जोड़ा जाता है, तो उचित चौड़ाई के आकार के लिए इसे प्राप्त करने के लिए इस कोड को निष्पादित करें। आप इसे करने के लिए अपने ढांचे में एक निर्देश को परिभाषित कर सकते हैं।

    element.style.flexBasis = "auto";
    element.style.flexBasis = `${element.scrollWidth}px`;

0

मुझे यहाँ वास्तव में बहुत बढ़िया PURE CSS वर्कअराउंड मिला।

https://jsfiddle.net/gcob492x/3/

मुश्किल: writing-mode: vertical-lrसूची में सेट तब div writing-mode: horizontal-tbमद सूची में। मुझे JSFiddle में शैलियों को ट्विस्ट करना पड़ा (बहुत सी संरेखण शैलियों को हटा दें, जो समाधान के लिए आवश्यक नहीं हैं)।

नोट: टिप्पणी कहती है कि यह केवल क्रोमियम-आधारित ब्राउज़र में काम करता है, न कि फ़ायरफ़ॉक्स में। मैंने केवल Chrome में व्यक्तिगत रूप से परीक्षण किया है। यह संभव है कि इसे अन्य ब्राउज़रों में काम करने के लिए इसे संशोधित करने का एक तरीका है या उक्त ब्राउज़रों को अपडेट किया गया है जो इस काम को करते हैं।

इस टिप्पणी के लिए बड़ा चिल्लाहट : जब flexbox आइटम कॉलम मोड में लपेटते हैं, तो कंटेनर इसकी चौड़ाई नहीं बढ़ाता है । उस मुद्दे के माध्यम से खुदाई ने मुझे https://bugs.chromium.org/p/chromium/issues/detail?id=507397#c39 पर ले गया , जिसने मुझे इस JSFiddle की ओर अग्रसर किया।


-1

चूंकि अभी तक कोई समाधान या उचित समाधान नहीं सुझाया गया था, इसलिए मैं थोड़ा अलग दृष्टिकोण के साथ अनुरोधित व्यवहार प्राप्त करने में कामयाब रहा। लेआउट को 3 अलग-अलग विभाजनों में अलग करने के बजाय, मैं सभी वस्तुओं को 1 div में जोड़ रहा हूँ और बीच में कुछ और div के साथ पृथक्करण बना रहा हूँ।

प्रस्तावित समाधान हार्ड कोडित है, यह मानते हुए कि हमारे पास 3 खंड हैं, लेकिन एक सामान्य तक बढ़ाया जा सकता है। मुख्य विचार यह बताना है कि हम इस लेआउट को कैसे प्राप्त कर सकते हैं।

  1. सभी आइटमों को 1 कंटेनर div में जोड़ना जो आइटम लपेटने के लिए फ्लेक्स का उपयोग करता है
  2. प्रत्येक "इनर कंटेनर" (मैं इसे एक खंड कहूँगा) के पहले आइटम में एक वर्ग होगा, जो हमें कुछ जोड़तोड़ करने में मदद करता है जो प्रत्येक अनुभाग के पृथक्करण और स्टाइल को बनाते हैं।
  3. :beforeप्रत्येक पहले आइटम का उपयोग करके , हम प्रत्येक अनुभाग के शीर्षक का पता लगा सकते हैं।
  4. उपयोग spaceकरने से वर्गों के बीच अंतर पैदा होता है
  5. चूंकि spaceमैं अनुभाग की पूरी ऊंचाई को कवर नहीं करूंगा, इसलिए मैं :afterइसे पूर्ण स्थिति और सफेद पृष्ठभूमि के साथ जोड़ने वाले अनुभागों में भी जोड़ रहा हूं ।
  6. प्रत्येक अनुभाग की पृष्ठभूमि रंग की शैली के लिए मैं प्रत्येक अनुभाग के पहले आइटम के अंदर एक और div जोड़ रहा हूं। मैं पूर्ण के साथ स्थिति होगी और होगा z-index: -1
  7. प्रत्येक पृष्ठभूमि की सही चौड़ाई प्राप्त करने के लिए, मैं JS का उपयोग कर रहा हूं, सही चौड़ाई निर्धारित कर रहा हूं, और आकार बदलने के लिए श्रोता को भी जोड़ रहा हूं।

function calcWidth() {
  var size = $(document).width();
  var end = $(".end").offset().left;

  var todoWidth = $(".doing-first").offset().left;
  $(".bg-todo").css("width", todoWidth);

  var doingWidth = $(".done-first").offset().left - todoWidth;
  $(".bg-doing").css("width", doingWidth);

  var doneWidth = $(".end").offset().left - $(".done-first").offset().left;
  $(".bg-done").css("width", doneWidth + 20);

}

calcWidth();

$(window).resize(function() {
  calcWidth();
});
.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  height: 120px;
  align-content: flex-start;
  padding-top: 30px;
  overflow-x: auto;
  overflow-y: hidden;
}

.item {
  width: 200px;
  background-color: #e5e5e5;
  border-radius: 5px;
  height: 20px;
  margin: 5px;
  position: relative;
  box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.75);
  padding: 5px;
}

.space {
  height: 150px;
  width: 10px;
  background-color: #fff;
  margin: 10px;
}

.todo-first:before {
  position: absolute;
  top: -30px;
  height: 30px;
  content: "To Do (2)";
  font-weight: bold;
}

.doing-first:before {
  position: absolute;
  top: -30px;
  height: 30px;
  content: "Doing (5)";
  font-weight: bold;
}

.doing-first:after,
.done-first:after {
  position: absolute;
  top: -35px;
  left: -25px;
  width: 10px;
  height: 180px;
  z-index: 10;
  background-color: #fff;
  content: "";
}

.done-first:before {
  position: absolute;
  top: -30px;
  height: 30px;
  content: "Done (3)";
  font-weight: bold;
}

.bg-todo {
  position: absolute;
  background-color: #FFEFD3;
  width: 100vw;
  height: 150px;
  top: -30px;
  left: -10px;
  z-index: -1;
}

.bg-doing {
  position: absolute;
  background-color: #EFDCFF;
  width: 100vw;
  height: 150px;
  top: -30px;
  left: -15px;
  z-index: -1;
}

.bg-done {
  position: absolute;
  background-color: #DCFFEE;
  width: 10vw;
  height: 150px;
  top: -30px;
  left: -15px;
  z-index: -1;
}

.end {
  height: 150px;
  width: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">

  <div class="item todo-first">
    <div class="bg-todo"></div>
    Drink coffee
  </div>
  <div class="item">Go to work</div>

  <div class="space"></div>

  <div class="item doing-first">
    <div class="bg-doing"></div>
    1
  </div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>

  <div class="space"></div>

  <div class="item done-first">
    <div class="bg-done"></div>
    1
  </div>
  <div class="item">2</div>
  <div class="item">3</div>

  <div class="end"></div>

</div>


-2

संभव जेएस समाधान ।।

var ul = $("ul.ul-to-fix");

if(ul.find("li").length>{max_possible_rows)){
    if(!ul.hasClass("width-calculated")){
        ul.width(ul.find("li").eq(0).width()*ul.css("columns"));
        ul.addClass("width-calculated");
     }
}

यह मदद नहीं करेगा, दुर्भाग्य से, व्यक्तिगत तत्वों की ऊंचाइयों में भिन्नता हो सकती है। इसलिए तत्वों की संख्या दिलचस्प नहीं है ... लेकिन columnsस्टाइल प्रॉपर्टी का उपयोग करना काम के समाधान के लिए एक शुरुआती बिंदु हो सकता है। शायद स्तंभों की संख्या और उल की चौड़ाई को समायोजित करना ।
एंडर्स तोर्ब्लाद

1
मैंने एक जेएस समाधान के साथ इस समस्या का समाधान करने के लिए भी प्रयास किया जो कि मैं एक रिएक्ट एप्लिकेशन पर काम कर रहा हूं। यह किसी भी और भिन्न आकार के तत्वों के साथ काम करने के लिए डिज़ाइन किया गया है। उदाहरण यहाँ: djskinner.github.io/react-column-wrap । स्रोत कोड यहां: github.com/djskinner/react-column-wrap
djskinner
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.