CSS: จะจัด "ป้ายกำกับ" และ "อินพุต" ในแนวตั้งภายใน "div" ได้อย่างไร


92

พิจารณารหัสต่อไปนี้ :

HTML:

<div>
    <label for='name'>Name:</label>
    <input type='text' id='name' />
</div>

CSS:

div {
    height: 50px;
    border: 1px solid blue;
}

อะไรคือวิธีที่ง่ายที่สุดในการวางlabelและinputตรงกลางdiv(แนวตั้ง)?


1
สำหรับความรู้ของฉันสิ่งที่สำคัญที่สุดคือ "คุณทำไม่ได้" และวิธีที่ขี้เกียจที่สุดคือการใช้วิธีง่ายๆ<table>และใช้valign='middle'กับ<td>s ของมัน
BeemerGuy

คำตอบ:


97

div {
    display: table-cell;
    vertical-align: middle;
    height: 50px;
    border: 1px solid red;
}
<div>
    <label for='name'>Name:</label>
    <input type='text' id='name' />
</div>

ข้อดีของวิธีนี้คือคุณสามารถเปลี่ยนความสูงของdivฟิลด์เปลี่ยนความสูงของฟิลด์ข้อความและเปลี่ยนขนาดฟอนต์และทุกอย่างจะอยู่ตรงกลางเสมอ

http://jsfiddle.net/53ALd/6/


1
ดูสง่างาม :) มีใครรู้บ้างว่าเบราว์เซอร์เข้ากันได้กับวิธีนี้อย่างไร?
Zaven Nahapetyan

1
สำหรับ IE ฉันคิดว่ามันใช้ได้เฉพาะกับ IE8 หรือดีกว่า สำหรับเว็บเบราว์เซอร์อื่น ๆ ก็ใช้ได้
Marc-François

1
ฉันไม่รู้เกี่ยวกับdisplay: table-cell. รองรับในบางเบราว์เซอร์หรือไม่
BeemerGuy

7
@ มิชาคุณควรระบุข้อเท็จจริงว่าอินพุต / ฉลากของคุณอยู่ในตำแหน่งที่แน่นอน นั่นทำให้สถานการณ์ของคำถามเปลี่ยนไปโดยสิ้นเชิง ฉันให้ +1 กับ Marc คำตอบที่ดี
jessegavin

2
ฉันค่อนข้างมั่นใจว่าประเด็นที่เจนสันพยายามทำ (และควรมีข้อต่อ) คือการใช้display: table-cellทำให้ div ทำงานในรูปแบบที่พวกเขาไม่คาดคิดว่าจะทำงานเช่นการแสดงผล div ในภายหลังในบรรทัดเดียวกัน / ฯลฯ
taswyn

74

วิธีการที่ทันสมัยกว่าคือการใช้ css flex-box

div {
  height: 50px;
  background: grey;
  display: flex;
  align-items: center
}
<div>
  <label for='name'>Name:</label>
  <input type='text' id='name' />
</div>

ตัวอย่างที่ซับซ้อนมากขึ้น ... หากคุณมีองค์ประกอบหลายอย่างในโฟลว์เฟล็กซ์คุณสามารถใช้ align-self เพื่อจัดแนวองค์ประกอบเดี่ยวให้แตกต่างกันไปตามการจัดแนวที่ระบุ ...

div {
  display: flex;
  align-items: center
}

* {
  margin: 10px
}

label {
  align-self: flex-start
}
<div>
  <img src="https://de.gravatar.com/userimage/95932142/195b7f5651ad2d4662c3c0e0dccd003b.png?size=50" />
  <label>Text</label>
  <input placeholder="Text" type="text" />
</div>

นอกจากนี้ยังง่ายต่อการจัดกึ่งกลางในแนวนอนและแนวตั้ง:

div {
  position:absolute;
  top:0;left:0;right:0;bottom:0;
  background: grey;
  display: flex;
  align-items: center;
  justify-content:center
}
<div>
  <label for='name'>Name:</label>
  <input type='text' id='name' />
</div>


ฉันหวังว่าสิ่งนี้จะได้ผลเมื่อมีภาพและข้อความห่อหุ้มป้ายกำกับ ฉันมีไอคอนเล็ก ๆ ตามด้วยข้อความ แต่ข้อความไม่ขยับ
Kevin Scharnhorst

มันใช้งานได้ถ้าฉลากและข้อความเป็นองค์ประกอบแยกกันหรือถ้าคุณทำให้ฉลากของคุณเป็นเฟล็กบ็อกซ์ด้วย ...
Holger Will

display:flexมีความเข้ากันได้น้อยทำงานบนchrome 29+

14

วิธีนี้ใช้งานข้ามเบราว์เซอร์ช่วยให้สามารถเข้าถึงได้มากขึ้นและมาพร้อมกับมาร์กอัปน้อยลง ทิ้ง div ห่อฉลาก

label{
     display: block; 
     height: 35px; 
     line-height: 35px; 
     border: 1px solid #000; 
}

input{margin-top:15px; height:20px}

<label for="name">Name: <input type="text" id="name" /></label>

3
เห็นได้ชัดว่าสิ่งนี้ใช้ไม่ได้กับป้ายกำกับสองบรรทัด และถ้าคุณแน่ใจว่าป้ายกำกับเป็นบรรทัดเดียวเสมอไปก็จะมีทางเลือกอื่น ๆ อีกนับล้าน
Lashae

16
คำถามเกี่ยวกับป้ายกำกับบรรทัดเดียวและฉันก็ตอบตามนั้น ไม่แน่ใจในประเด็นหรือความตั้งใจของคุณตรงนี้ แต่ถ้า x ชัดเจนมากคุณควรทำตัวอย่างเป็นล้าน ๆ อย่างน้อยที่สุดเพื่อที่คุณจะได้ดีใจภายใต้คำตอบของฉันและรู้สึกถึงพลังแห่งชัยชนะนับล้านของคุณ ไชโย
albert

2
นี่คือคำตอบที่ดีที่สุดสำหรับป้ายชื่อบรรทัดเดียว ข้อกำหนดระบุว่า: "หากไม่ได้ระบุแอตทริบิวต์สำหรับแอตทริบิวต์ แต่องค์ประกอบป้ายกำกับมีองค์ประกอบรองลงมาที่เกี่ยวข้องกับรูปแบบที่มีป้ายกำกับลำดับชั้นแรกดังกล่าวตามลำดับแบบต้นไม้คือตัวควบคุมที่มีป้ายกำกับขององค์ประกอบป้ายกำกับ" ดังนั้นนี่เป็นแนวทางเดียวที่คุณสามารถละเว้นแอตทริบิวต์forและidเพื่อความเรียบง่ายสูงสุด
รัฐสภา

8

ฉันทราบว่ามีการถามคำถามนี้เมื่อสองปีก่อน แต่สำหรับผู้ชมล่าสุดนี่เป็นทางเลือกอื่นซึ่งมีข้อดีบางประการเหนือโซลูชันของ Marc-François:

div {
    height: 50px;
    border: 1px solid blue;
    line-height: 50px;
}

เราก็แค่บวกline-heightเท่ากับความสูงของ div ข้อดีคือตอนนี้คุณสามารถเปลี่ยนคุณสมบัติการแสดงผลของ div ได้ตามที่คุณเห็นว่าเหมาะสมinline-blockเป็นต้นและเนื้อหาจะยังคงอยู่กึ่งกลางในแนวตั้ง โซลูชันที่ยอมรับต้องการให้คุณปฏิบัติกับ div เป็นเซลล์ตาราง สิ่งนี้ควรทำงานได้อย่างสมบูรณ์แบบข้ามเบราว์เซอร์

ข้อได้เปรียบเพียงอย่างเดียวคือมันเป็นเพียงกฎ CSS หนึ่งกฎแทนที่จะเป็นสองข้อ :)

ไชโย!


6

การใช้งานpaddingบนdiv( ด้านบนและด้านล่าง ) และvertical-align:middleบนและlabelinput

ตัวอย่างที่http://jsfiddle.net/VLFeV/1/


มันใช้ไม่ได้กับ jsfiddle ฉันเปลี่ยนความสูงของdivและเนื้อหาข้างในไม่ขยับเลย ฉันพลาดอะไรไปรึเปล่า?
BeemerGuy

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

3

ห่อป้ายกำกับและป้อนข้อมูลใน div อื่นด้วยความสูงที่กำหนด สิ่งนี้อาจใช้ไม่ได้ใน IE เวอร์ชันที่ต่ำกว่า 8

position:absolute; 
top:0; bottom:0; left:0; right:0;
margin:auto;

0

คุณสามารถใช้display: table-cellคุณสมบัติตามรหัสต่อไปนี้:

div {
     height: 100%;
     display: table-cell; 
     vertical-align: middle;
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.