วิธีการตั้งค่าระยะขอบหรือช่องว่างภายในเป็นเปอร์เซ็นต์ของความสูงของคอนเทนเนอร์หลัก?


236

ฉันได้รับสมองของฉันมากกว่าการสร้างการจัดตำแหน่งแนวตั้งใน CSS โดยใช้ต่อไปนี้

.base{
        background-color:green;
	    width:200px;
	    height:200px;
	    overflow:auto;
	    position:relative;
	}

    .vert-align{
		padding-top:50%;
		height:50%;
	}
<!-- and used the following div structure. -->

    <div class="base">
       <div class="vert-align">
    	   Content Here
       </div>
    </div>

ในขณะที่สิ่งนี้ดูเหมือนจะใช้ได้กับกรณีนี้ฉันรู้สึกประหลาดใจที่เมื่อฉันเพิ่มหรือลดความกว้างของ div พื้นฐานของฉันการจัดตำแหน่งแนวตั้งจะ snap ฉันคาดหวังว่าเมื่อฉันตั้งค่าคุณสมบัติการเติมด้านบนจะใช้การเติมเป็นเปอร์เซ็นต์ของความสูงของคอนเทนเนอร์หลักซึ่งเป็นฐานในกรณีของเรา แต่ค่าที่สูงกว่า 50 เปอร์เซ็นต์จะถูกคำนวณเป็นเปอร์เซ็นต์ของ ความกว้าง :(

มีวิธีตั้ง padding และ / หรือ margin เป็นเปอร์เซ็นต์ของส่วนสูงโดยไม่ต้องใช้ JavaScript หรือไม่?

คำตอบ:


223

การแก้ไขคือว่าใช่ช่องว่างในแนวตั้งและอัตรากำไรขั้นต้นจะสัมพันธ์กับความกว้างของ แต่topและbottom ไม่ได้

ดังนั้นเพียงแค่วาง div ไว้ข้างในอีกอันหนึ่งและใน div ด้านในให้ใช้สิ่งที่คล้ายกันtop:50%(จำไว้ว่าpositionถ้ามันยังใช้งานไม่ได้)


3
topใช้งานได้ดีสำหรับการปรับขนาดตามความสูงของเบราว์เซอร์ / หน้าต่าง การมี div อยู่ใต้ div นั้นเป็นอย่างไร? คุณclearจะหารกองที่ 2 ได้อย่างไรภายใต้กองที่ถูกเลื่อนลงโดยtop:50%?
Federico

เรียนรู้ sth ใหม่ ไม่ทราบว่าการขยายในแนวตั้งและระยะขอบสัมพันธ์กับความกว้างก่อนหน้านี้ ขอบคุณ.
shaosh

5
เป็นไปได้ที่จะเพิ่ม div 'ตัวเว้นวรรค' ด้วยความสูงที่กำหนดร้อยละ ดูเหมือนสกปรกเล็กน้อย แต่ก็ใช้งานได้ ดูคำตอบนี้
WCByrne

4
สิ่งที่เป็นอมตะ @%! ^? ทำไมจึงมีอัตรากำไรขั้นต้นในแนวตั้งและ padding เทียบกับความกว้าง ? อะไร? เหตุใดการตัดสินใจนั้นจึงเกิดขึ้นบนโลก
temporary_user_name

คำตอบของคุณได้รับการโหวตอย่างไม่เป็นสัดส่วนมากเมื่อเทียบกับคำตอบของ Alain ด้านล่างซึ่งเป็นวิธีแก้ปัญหาทั่วไปและฉันพบว่ามีประโยชน์มากและแทบจะไม่เห็นเลย top: 50%ไม่มีประโยชน์หากคุณต้องการจัดเนื้อหาตามกึ่งกลางของตนเอง
okovko

35

คำตอบสำหรับคำถามที่แตกต่างกันเล็กน้อย: คุณสามารถใช้vhหน่วยต่างๆเพื่อวางองค์ประกอบต่างๆไว้ที่กึ่งกลางของวิวพอร์ต :

.centerme {
    margin-top: 50vh;
    background: red;
}

<div class="centerme">middle</div>

ทำไมคำตอบนี้จึงไม่ได้รับการโหวตสูงกว่า มีอะไรผิดปกติในการใช้ vh หรือไม่?
AlanH

3
มันเป็นเพราะมันไม่ใช่คำตอบที่เหมาะกับคำถามดั้งเดิมมันเป็นกลอุบายที่มีประโยชน์ที่ใช้ได้เฉพาะในบางกรณีที่เกี่ยวข้อง
willoller

การใช้งานvhเกือบเท่ากับเปอร์เซ็นต์ ... ยิ่งแย่ลงในบางกรณี คำตอบนี้ไม่เกี่ยวข้องกับคำถาม
vsync

33

นี่คือสองตัวเลือกเพื่อเลียนแบบพฤติกรรมที่จำเป็น ไม่ใช่วิธีแก้ไขปัญหาทั่วไป แต่อาจช่วยได้ในบางกรณี การเว้นวรรคแนวตั้งที่นี่ถูกคำนวณตามขนาดขององค์ประกอบด้านนอกไม่ใช่พาเรนต์ แต่ขนาดนี้สามารถสัมพันธ์กับพาเรนต์และวิธีนี้ระยะห่างจะสัมพันธ์กันด้วย

<div id="outer">
    <div id="inner">
        content
    </div>
</div>

ตัวเลือกแรก: ใช้องค์ประกอบหลอกที่นี่ระยะห่างแนวตั้งและแนวนอนจะสัมพันธ์กับด้านนอก การสาธิต

#outer::before, #outer::after {
    display: block;
    content: "";
    height: 10%;
}
#inner {
    height: 80%;
    margin-left: 10%;
    margin-right: 10%;
}

การย้ายระยะห่างแนวนอนไปยังองค์ประกอบด้านนอกทำให้สัมพันธ์กับพาเรนต์ของด้านนอก การสาธิต

#outer {
    padding-left: 10%;
    padding-right: 10%;
}

ตัวเลือกที่สอง: ใช้การกำหนดตำแหน่งแบบสัมบูรณ์ การสาธิต

#outer {
    position: relative;
}
#inner {
    position: absolute;
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}

10

ในการทำให้องค์ประกอบย่อยอยู่ในตำแหน่งที่แน่นอนจากองค์ประกอบหลักคุณต้องตั้งค่าตำแหน่งสัมพันธ์ในองค์ประกอบหลักและตำแหน่งที่แน่นอนในองค์ประกอบย่อย

จากนั้นองค์ประกอบลูก 'ด้านบน' จะสัมพันธ์กับความสูงของผู้ปกครอง ดังนั้นคุณต้อง 'แปล' เด็กด้วยความสูง 50% ของความสูงของตัวเอง

.base{
    background-color: green;
    width: 200px;
    height: 200px;
    overflow: auto;
    position: relative;
}
    
.vert-align {
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
}
    <div class="base">
        <div class="vert-align">
            Content Here
        </div>
    </div>

มีอีกวิธีการแก้ปัญหาโดยใช้กล่องดิ้น

.base{
    background-color:green;
    width: 200px;
    height: 200px;
    overflow: auto;
    display: flex;
    align-items: center;
}
<div class="base">
    <div class="vert-align">
        Content Here
    </div>
</div>

คุณจะพบข้อดี / ข้อเสียของทั้งคู่


1
การใช้การแปลเป็นวิธีที่แท้จริงในการเคลื่อนย้ายองค์ประกอบที่สัมพันธ์กับขนาดของมันในแนวตั้ง
Eran Goldin

ขอบคุณสำหรับสิ่งนี้. นี่ควรเป็นคำตอบที่เลือก
Wessam El Mahdy

6

สามารถทำได้ด้วยwriting-modeคุณสมบัติ หากคุณตั้งค่าองค์ประกอบwriting-modeเป็นโหมดการเขียนในแนวตั้งเช่นvertical-lrค่าเปอร์เซ็นต์ของลูกหลานสำหรับการเติมและระยะขอบในทั้งสองมิติจะสัมพันธ์กับความสูงแทนความกว้าง

จากสเป็ค :

. . . ร้อยละของคุณสมบัติระยะขอบและช่องว่างภายในซึ่งคำนวณเสมอตามความกว้างของบล็อกที่มีใน CSS2.1 จะถูกคำนวณโดยคำนึงถึงขนาดอินไลน์ของบล็อกที่มีใน CSS3

ความหมายของขนาดอินไลน์ :

การวัดในมิติอินไลน์: หมายถึงความกว้างทางกายภาพ (มิติแนวนอน) ในโหมดการเขียนแนวนอนและความสูงทางกายภาพ (มิติแนวตั้ง) ในโหมดการเขียนแนวตั้ง

ตัวอย่างด้วยองค์ประกอบที่ปรับขนาดได้ซึ่งระยะขอบในแนวนอนนั้นสัมพันธ์กับความกว้างและระยะขอบแนวตั้งนั้นสัมพันธ์กับความสูง

.resize {
  width: 400px;
  height: 200px;
  resize: both;
  overflow: hidden;
}

.outer {
  height: 100%;
  background-color: red;
}

.middle {
  writing-mode: vertical-lr;
  margin: 0 10%;
  width: 80%;
  height: 100%;
  background-color: yellow;
}

.inner {
  writing-mode: horizontal-tb;
  margin: 10% 0;
  width: 100%;
  height: 80%;
  background-color: blue;
}
<div class="resize">
  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>
</div>

การใช้โหมดการเขียนในแนวตั้งนั้นมีประโยชน์อย่างยิ่งในสถานการณ์ที่คุณต้องการอัตราส่วนขององค์ประกอบให้คงที่ แต่ต้องการให้ขนาดของสเกลนั้นสัมพันธ์กับความสูงแทนที่จะเป็นความกว้าง


นี่คือ IMO จะเป็นทางออกที่สวยงามมากขึ้น แต่ ( ณ วันที่ 2018/05/05) โหมดการเขียนในแนวตั้งจะไม่ได้รับการสนับสนุนอย่างดี หวังว่าการเปลี่ยนแปลงในไม่ช้า
zanerock

1
@zanerock ฉันค่อนข้างมั่นใจว่าตาราง MDN ที่เข้ากันได้นั้นล้าสมัยแล้ว ยกตัวอย่างเช่นมันบอกว่า Safari ต้องการ-webkit-คำนำหน้า แต่ตามที่ชาวแคนาดาไม่จำเป็นต้องใช้คำนำหน้าตั้งแต่ Safari 11 คุณลองกับเบราว์เซอร์ที่ใช้ไม่ได้หรือไม่
James T

1
ไม่ฉันต้องยอมรับว่าฉันแค่คิดว่ามันดีโดยอัตโนมัติ
zanerock

4

อีกวิธีหนึ่งที่จะจัดกึ่งกลางข้อความบรรทัดเดียวคือ:

.parent{
  position: relative;
}

.child{
   position: absolute;
   top: 50%;
   line-height: 0;
}

หรือเพียงแค่

.parent{
  overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}

.child{
   margin-top: 50%;
   line-height: 0;
}

0

การเติมเต็ม 50% จะไม่ทำให้ลูกของคุณอยู่ตรงกลางมันจะวางลงใต้ศูนย์ ฉันคิดว่าคุณต้องการเพิ่มส่วนแบ่ง 25% อาจเป็นเพราะพื้นที่ของคุณสูงขึ้นใช่ไหม คุณลองตั้งค่าระยะขอบแทนการเติมด้านบนด้วยหรือไม่

แก้ไข: ไม่เป็นไรเว็บไซต์ w3schools กล่าว

% ระบุการเติมเต็มเป็นเปอร์เซ็นต์ของความกว้างขององค์ประกอบที่มี

ดังนั้นอาจใช้ความกว้างเสมอ ฉันไม่เคยสังเกต

สิ่งที่คุณกำลังทำสามารถทำได้โดยใช้จอแสดงผล: ตารางแม้ว่า (อย่างน้อยสำหรับเบราว์เซอร์ที่ทันสมัย) เทคนิคที่จะมีการอธิบายที่นี่


1
ขอบคุณ Spliff ฉันเข้าใจว่า 50% ของฉันจะไม่เน้นเนื้อหาของ div ฉันมีข้อความเพียงบรรทัดเดียวที่ต้องอยู่กึ่งกลางในแนวตั้ง ขอบคุณมากสำหรับลิงค์แม้ว่า!
Ryan

3
หากคุณคิดว่าเป็นเพียงข้อความบรรทัดเดียวโดยใช้ข้อความที่มีขนาดใหญ่อย่างน่าขันline-heightลองสร้างความสูงของบรรทัด 200px หรือไม่
SpliFF

@Ryan สำหรับการจัดกึ่งกลางข้อความในแนวตั้งให้ดูstackoverflow.com/questions/8865458/…
ผู้ใช้

ลิงก์ของคุณใช้งานไม่ได้
59

0

นี่เป็นข้อผิดพลาดที่น่าสนใจมาก (ในความคิดของฉันมันเป็นข้อผิดพลาดอยู่แล้ว) Nice find!

เกี่ยวกับวิธีการตั้งค่าฉันจะแนะนำคำตอบของ Camilo Martin แต่ทำไมฉันอยากจะอธิบายเรื่องนี้สักหน่อยถ้าพวกคุณไม่สนใจ


ในรายละเอียด CSSฉันพบ:


เปอร์เซ็นต์การขยายเต็ม: อ้างถึงความกว้างของบล็อกที่มี

…ซึ่งแปลก แต่ก็โอเค

ดังนั้นกับผู้ปกครองwidth: 210pxและเด็กที่padding-top: 50%ฉันได้รับการคำนวณ / ค่าคำนวณของpadding-top: 96.5px- 105pxซึ่งไม่ได้คาดหวัง

นั่นเป็นเพราะใน Windows (ฉันไม่แน่ใจเกี่ยวกับระบบปฏิบัติการอื่น ๆ ) ขนาดของแถบเลื่อนทั่วไปเป็นค่าเริ่มต้นต่อ17px × 100%(หรือ100% × 17pxแถบแนวนอน) ผู้ที่17pxกำลัง substracted ก่อนการคำนวณจึง50%50% of 193px = 96.5px


มีเหตุผลสำหรับสเปคและสิ่งนี้อธิบายได้ดีกว่า: hongkiat.com/blog/calculate-css-percentage-margins
manikanta
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.