क्रमशः ऑफसेटविदथ, क्लाइंटविद, स्क्रॉलविद और -हाइट को समझना


385

StackOverflow पर कई सवाल हैं, ऑफसेटव्यूड / क्लायंटवीड / स्क्रॉलविथ (और -हाइट, क्रमशः) के बारे में, लेकिन कोई भी उन मूल्यों का व्यापक विवरण नहीं देता है।

साथ ही, भ्रामक या गलत जानकारी देने वाले वेब पर कई स्रोत हैं।

क्या आप कुछ दृश्य संकेत सहित पूर्ण विवरण दे सकते हैं? साथ ही, स्क्रॉल बार की चौड़ाई की गणना करने के लिए उन मूल्यों का उपयोग कैसे किया जा सकता है?

जवाबों:


868

सीएसएस बॉक्स मॉडल बल्कि जटिल है, खासकर जब यह स्क्रॉलिंग सामग्री की बात आती है। जबकि ब्राउज़र आपके सीएसएस से बॉक्सों को खींचने के लिए मूल्यों का उपयोग करता है, जेएस का उपयोग करके सभी आयामों का निर्धारण सीधे-आगे नहीं है यदि आपके पास केवल सीएसएस है।

है यही कारण है कि प्रत्येक तत्व आपकी सुविधा के लिए छह डोम गुण है: offsetWidth, offsetHeight, clientWidth, clientHeight, scrollWidthऔर scrollHeight। ये केवल वर्तमान दृश्य लेआउट का प्रतिनिधित्व करने वाली विशेषताएँ हैं, और ये सभी पूर्णांक हैं (इस प्रकार संभवतः राउंडिंग त्रुटियों के अधीन हैं)।

आइए उनके बारे में विस्तार से जानें:

  • offsetWidth, offsetHeight: सभी सीमाओं सहित दृश्य बॉक्स के आकार। यदि तत्व है, तो width/ heightऔर पैडिंग और बॉर्डर को जोड़कर गणना की जा सकती हैdisplay: block
  • clientWidth, clientHeight: बॉक्स सामग्री के दृश्य भाग, सीमाओं या स्क्रॉल बार शामिल नहीं है, लेकिन गद्दी भी शामिल है। सीएसएस से सीधे गणना नहीं की जा सकती है, सिस्टम के स्क्रॉल बार आकार पर निर्भर करता है।
  • scrollWidth, scrollHeight: भागों है कि वर्तमान में स्क्रॉल क्षेत्र के बाहर छिपे हुए हैं सहित बॉक्स की सामग्री को के आकार,। सीएसएस से सीधे गणना नहीं की जा सकती, सामग्री पर निर्भर करता है।

CSS2 बॉक्स मॉडल

इसे आज़माएं: jsFiddle


चूंकि offsetWidthस्क्रॉल बार की चौड़ाई को ध्यान में रखा जाता है, इसलिए हम इसका उपयोग फॉर्मूला के माध्यम से स्क्रॉल बार की चौड़ाई की गणना करने के लिए कर सकते हैं

scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth

दुर्भाग्यवश, हम हमेशा के लिए पूर्णांक त्रुटियां प्राप्त कर सकते हैं offsetWidthऔर clientWidthहमेशा पूर्णांक होते हैं, जबकि वास्तविक आकार 1 के अलावा ज़ूम स्तर के साथ भिन्न हो सकते हैं।

ध्यान दें कि यह

scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth

क्रोम में मज़बूती से काम नहीं करता है , क्योंकि क्रोम widthस्क्रॉलबार के साथ पहले से ही वापस आ गया है। (साथ ही, क्रोम पेडिंगबॉटम को स्क्रॉल कंटेंट के निचले हिस्से तक पहुंचाता है, जबकि अन्य ब्राउज़र नहीं)


27
पूर्णांक की तुलना में बारीक ग्रैन्युलैरिटी चाहने वालों के लिए, element.getBoundingClientRect()( डेवलपर.
mozilla.org/en-US/docs/Web/API/Element.clientWidth

1
ध्यान दें कि आपके लेआउट के आधार पर, स्क्रॉलविथ और स्क्रॉलहाइट आपके छद्म तत्वों का आकार पाने के लिए वास्तव में उपयोगी हो सकते हैं :: पहले और बाद में।
डेविड

इसके अलावा, यह बताना उपयोगी होगा कि वे कैसे संबंधित हैं naturalWidthऔरnaturalHeight
याकॉव

क्यों scrollHeightशामिल है, padding-bottomलेकिन इसमें शामिल scrollWidthनहीं हैpadding-right
JunGor

clientWidthके लिए document.documentElement.clientWidthअलग अलग रूप में यह शामिल करने के लिए लगता है padding, bordersऔरmargin
Drenai

49

मैंने एक अधिक व्यापक और क्लीनर संस्करण बनाया है जो कुछ लोगों को यह याद रखने के लिए उपयोगी हो सकता है कि कौन सा नाम किस मूल्य से मेल खाता है। मैंने क्रोम देव टूल के कलर कोड का इस्तेमाल किया और उपमाओं को तेज़ी से लेने के लिए सममित रूप से लेबल आयोजित किए जाते हैं:

यहां छवि विवरण दर्ज करें

  • नोट 1: clientLeftइसमें वर्टिकल स्क्रॉल बार की चौड़ाई भी शामिल है यदि टेक्स्ट की दिशा दाएं-से-बाएं सेट है (क्योंकि उस स्थिति में बार बाईं ओर प्रदर्शित होता है)

  • नोट 2: सबसे बाहरी लाइन करीबी का प्रतिनिधित्व करता है तैनात माता पिता (एक तत्व जिसका positionसंपत्ति की तुलना में एक मूल्य के अलग करने के लिए सेट कर दिया जाता staticया initial)। इस प्रकार, यदि प्रत्यक्ष कंटेनर एक नहीं है स्थिति में तत्व है, तो लाइन पदानुक्रम में पहले कंटेनर लेकिन एक और तत्व पदानुक्रम में प्रतिनिधित्व नहीं करता है। यदि कोई तैनात माता पिता पाया जाता है, ब्राउज़र ले जाएगा htmlया body संदर्भ के रूप में तत्व


आशा है कि किसी को यह उपयोगी लगता है, बस मेरे 2 सेंट;)


30

यदि आप "REAL" कंटेंट WIDTH / HEIGHT प्राप्त करने के लिए स्क्रोलविथ का उपयोग करना चाहते हैं (जैसा कि सामग्री css- परिभाषित चौड़ाई / ऊंचाई-बॉक्स की तुलना में बड़ा हो सकता है) तो स्क्रॉलविथ / हाइट बहुत ही UNLELIABLE है जैसा कि कुछ ब्राउज़र को "MOVE" कर रहे हैं। यदि सामग्री बड़ी है तो & पेडिंगबॉटम। वे फिर "बहुत व्यापक / उच्च सामग्री" के राइट / बीओटीओएम पर पैडिंग लगाते हैं (नीचे चित्र देखें)।

==> इसलिए कुछ ब्राउज़रों में वास्तविक कंटेंट को प्राप्त करने के लिए आपको स्क्रॉल बैंडविड्थ से बीओटीएच पैडिंग को बदलना होगा और कुछ ब्राउज़रों में आपको केवल लेफ्ट पेडिंग को बदलना होगा।

मुझे इसके लिए एक समाधान मिला और मैं इसे एक टिप्पणी के रूप में जोड़ना चाहता था, लेकिन इसकी अनुमति नहीं थी। इसलिए मैंने तस्वीर ली और इसे "स्थानांतरित पैडिंग" और "अविश्वसनीय स्क्रॉलविथ" के संबंध में थोड़ा स्पष्ट कर दिया। BLUE AREA में आप "REAL" कंटेंट WIDTH प्राप्त करने के तरीके के बारे में मेरा समाधान जानेंगे!

आशा है कि यह चीजों को और भी स्पष्ट करने में मदद करता है!

यहां छवि विवरण दर्ज करें


13

MDN पर एक अच्छा लेख है जो उन अवधारणाओं के पीछे सिद्धांत की व्याख्या करता है: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_imimensions_of_elements

यह बाउंडक्लाइंटRect की चौड़ाई / ऊँचाई बनाम ऑफ़सेटविंड / ऑफसेटहाइट के बीच महत्वपूर्ण वैचारिक अंतर भी बताता है।

फिर, सिद्धांत को सही या गलत साबित करने के लिए, आपको कुछ परीक्षणों की आवश्यकता है। यही मैंने यहां किया है: https://github.com/lingtalfi/dimensions-cheatsheet

यह chrome53, ff49, safari9, edge13 और ie11 के लिए परीक्षण कर रहा है।

परीक्षणों के परिणाम साबित करते हैं कि सिद्धांत आम तौर पर सही है। परीक्षणों के लिए, मैंने प्रत्येक में 10 लोरेम इप्सम पैराग्राफ वाले 3 डिविज़ बनाए। कुछ सीएसएस उन्हें लागू किया गया था:

.div1{
    width: 500px;
    height: 300px;
    padding: 10px;
    border: 5px solid black;
    overflow: auto;
}
.div2{
    width: 500px;
    height: 300px;
    padding: 10px;
    border: 5px solid black;
    box-sizing: border-box;
    overflow: auto;
}

.div3{
    width: 500px;
    height: 300px;
    padding: 10px;
    border: 5px solid black;
    overflow: auto;
    transform: scale(0.5);
}

और यहाँ परिणाम हैं:

  • div1

    • ऑफसेट: 530 (chrome53, ff49, safari9, edge13, ie11)
    • ऑफसेट: 330 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.width: 530 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 330 (chrome53, ff49, safari9, edge13, ie11)

    • ग्राहक: 505 (क्रोम 53, ff49, सफारी 9)

    • ग्राहक: 508 (एज 13)
    • ग्राहक: 503 (यानी 11)
    • क्लाइंटहाइट: 320 (chrome53, ff49, safari9, edge13, ie11)

    • स्क्रॉलविद: 505 (क्रोम 53, सफारी 9, ff49)

    • स्क्रॉलविद: 508 (एज 13)
    • स्क्रॉलविद: 503 (यानी 11)
    • स्क्रॉलहाइट: 916 (क्रोम 53, सफारी 9)
    • स्क्रॉलहाइट: 954 (ff49)
    • स्क्रॉलहाइट: 922 (एज 13, यानी 11)
  • DIV2

    • ऑफसेट: 500 (chrome53, ff49, safari9, edge13, ie11)
    • ऑफसेट: 300 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.width: 500 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 300 (chrome53, ff49, safari9)
    • bcr.height: 299.9999694824219 (एज 13, यानी 11)
    • ग्राहक: 475 (chrome53, ff49, सफारी 9)
    • क्लाइंटविड: 478 (एज 13)
    • ग्राहक: 473 (यानी 11)
    • क्लाइंटहाइट: 290 (chrome53, ff49, safari9, edge13, ie11)

    • स्क्रॉलविद: 475 (chrome53, safari9, ff49)

    • स्क्रॉलविद: 478 (एज 13)
    • स्क्रॉलविद: 473 (यानी 11)
    • स्क्रॉलहाइट: 916 (क्रोम 53, सफारी 9)
    • स्क्रॉलहाइट: 954 (ff49)
    • स्क्रॉलहाइट: 922 (एज 13, यानी 11)
  • DIV3

    • ऑफसेट: 530 (chrome53, ff49, safari9, edge13, ie11)
    • ऑफसेट: 330 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.width: 265 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 165 (chrome53, ff49, safari9, edge13, ie11)
    • ग्राहक: 505 (क्रोम 53, ff49, सफारी 9)
    • ग्राहक: 508 (एज 13)
    • ग्राहक: 503 (यानी 11)
    • क्लाइंटहाइट: 320 (chrome53, ff49, safari9, edge13, ie11)

    • स्क्रॉलविद: 505 (क्रोम 53, सफारी 9, ff49)

    • स्क्रॉलविद: 508 (एज 13)
    • स्क्रॉलविद: 503 (यानी 11)
    • स्क्रॉलहाइट: 916 (क्रोम 53, सफारी 9)
    • स्क्रॉलहाइट: 954 (ff49)
    • स्क्रॉलहाइट: 922 (एज 13, यानी 11)

इसलिए, किनारे 13 और ie11 में बाउंडिंगक्लायंटRect की ऊंचाई मान (299.99996924219 के बजाय अपेक्षित 300) के अलावा, परिणाम पुष्टि करते हैं कि इस काम के पीछे सिद्धांत।

वहाँ से, यहाँ उन अवधारणाओं की परिभाषा है:

  • ऑफ़सेटविद / ऑफसेटहाइट: लेआउट बॉर्डर बॉक्स के आयाम
  • boundingClientRect: रेंडरिंग बॉर्डर बॉक्स के आयाम
  • clientWidth / clientHeight: लेआउट पैडिंग बॉक्स के दृश्य भाग के आयाम (स्क्रॉल पट्टियों को छोड़कर)
  • स्क्रॉलविद / स्क्रॉलहाइट: लेआउट पैडिंग बॉक्स के आयाम अगर यह स्क्रॉल बार द्वारा विवश नहीं किया गया था

नोट: डिफ़ॉल्ट वर्टिकल स्क्रॉल बार की चौड़ाई एज 13 में 12px, क्रोम क्रोम में 15px, ff49 और सफारी 9, और 1711 यानी 11 में (स्क्रीनशॉट से फ़ोटोशॉप में माप द्वारा किया गया है, और परीक्षणों के परिणामों द्वारा सही साबित हुआ)।

हालाँकि, कुछ मामलों में, शायद आपका ऐप डिफ़ॉल्ट वर्टिकल स्क्रॉल बार की चौड़ाई का उपयोग नहीं कर रहा है।

तो, उन अवधारणाओं की परिभाषा को देखते हुए, ऊर्ध्वाधर स्क्रॉल बार की चौड़ाई (छद्म कोड में) के बराबर होनी चाहिए:

  • लेआउट आयाम: ऑफ़सेटविद - क्‍लाइंटविदथ - (बॉर्डर लिफ़्टवार्ड + बॉर्डरराइट)

  • रेंडरिंग आयाम:

ध्यान दें, यदि आपको लेआउट बनाम रेंडरिंग समझ में नहीं आता है तो कृपया mdn लेख पढ़ें।

इसके अलावा, यदि आपके पास एक और ब्राउज़र है (या यदि आप अपने लिए परीक्षण के परिणाम देखना चाहते हैं), तो आप यहाँ मेरा परीक्षण पृष्ठ देख सकते हैं: http://codepen.io/lingtalfi/pen/BLdBdL

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.