ศูนย์ภาพขนาดใหญ่ในกอง


175

ฉันพยายามเรียงลำดับภาพที่มีขนาดใหญ่ภายใน div โดยใช้ css เท่านั้น

เรากำลังใช้เลย์เอาต์ของเหลวดังนั้นความกว้างของภาชนะบรรจุรูปภาพจึงแตกต่างกันไปตามความกว้างของหน้ากระดาษ (แก้ไขความสูงของ div) รูปภาพตั้งอยู่ภายใน div ด้วยค่า boxshadow ที่ใส่เข้าไปเพื่อให้ปรากฏราวกับว่าคุณกำลังดูหน้าของภาพ

ขนาดของภาพเองนั้นมีขนาดใหญ่เพื่อเติม div ที่อยู่รอบ ๆ ด้วยค่าที่เป็นไปได้ที่กว้างที่สุด (การออกแบบมีmax-widthค่า)

มันค่อนข้างง่ายที่จะทำถ้าภาพเล็กกว่า div ที่อยู่โดยรอบ:

margin-left: auto;
margin-right: auto;
display: block; 

แต่เมื่อรูปภาพมีขนาดใหญ่กว่า div มันก็เริ่มที่ขอบซ้ายและอยู่กึ่งกลางทางด้านขวา (เรากำลังใช้overflow: hidden)

เราสามารถกำหนด a width=100%แต่เบราว์เซอร์ทำงานปรับขนาดภาพและศูนย์ออกแบบเว็บไซต์ให้มีภาพคุณภาพสูง

มีแนวคิดใดในการจัดกึ่งกลางภาพเพื่อoverflow:hiddenตัดขอบทั้งสองให้เท่ากัน


2
คุณเคยแก้ปัญหานี้แล้วหรือยัง @Tom? ฉันกำลังประสบปัญหาเดียวกันในขณะนี้ :)
ctrlplusb

ฉันสมมติว่าความกว้างของภาพของคุณแตกต่างกันไป
otherDewi

คำตอบ:


366

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

.parent {
    position: relative;
    overflow: hidden;
    //optionally set height and width, it will depend on the rest of the styling used
}

.child {
    position: absolute;
    top: -9999px;
    bottom: -9999px;
    left: -9999px;
    right: -9999px;
    margin: auto;

}

4
วิเศษ: มันใช้ได้กับทุกองค์ประกอบ แม้จะเป็นวิดีโอ html 5 ... ขอบคุณ!
taseenb

3
ตามที่ฉันเข้าใจ: มันใช้งานได้เพราะมันสร้างองค์ประกอบ (หวังว่า) จะใหญ่กว่าภาพ (2 * 9999px x 2 * 9999px) และจัดกึ่งกลางของภาพภายในองค์ประกอบนั้น (ระยะขอบ: อัตโนมัติ) ดังนั้นตราบใดที่ภาพไม่เกิน 2 * 9999px มันควรจะทำงาน
Michael Krupp

16
ทำไมไม่ใช้-100%กับด้านบน / ขวา / ล่าง / ซ้าย? กับที่ภาชนะที่สามารถมีตัวอักษรใด ๆความกว้าง
Simon

15
ใช่ฉันเคยประสบ-100%ปัญหาเช่นกัน ^^ Btw: ถ้าคุณเพิ่มmin-widthและmin-heightของ100%คุณโดยทั่วไปได้รับbackground-size: cover;พฤติกรรมที่มีแท็กภาพ -> jsfiddle
ไซมอน

3
@HarrisonPowers ผู้ปกครองต้องมีความสูงแน่นอนไม่ว่าจะเป็นแบบคงที่หรือแบบไดนามิก นอกจากนี้ยังสามารถใช้งานได้หากเนื้อหาอื่นเติม div ให้มีความสูง (เช่นข้อความเป็นต้น)
hyounis

162

นี่คือ Q เก่า แต่โซลูชันที่ทันสมัยโดยไม่มี flexbox หรือตำแหน่งสัมบูรณ์ทำงานเช่นนี้

margin-left: 50%;
transform: translateX(-50%);

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

เรามีสถานการณ์นี้ก่อนที่เราจะเพิ่ม CSS

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
       +-----------------------------------------------------------+
       | Element E                                                 |
       +-----------------------------------------------------------+
       |                                           |
       +-------------------------------------------+

ด้วยสไตล์ที่เพิ่มเข้ามาmargin-left: 50%เรามี

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
       |                     +-----------------------------------------------------------+
       |                     | Element E                                                 |
       |                     +-----------------------------------------------------------+
       |                     |                     |
       +---------------------|---------------------+
       |========= a ========>|

       a is 50% width of P

และtransform: translateX(-50%)เลื่อนกลับไปทางซ้าย

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
+-----------------------------------------------------------+
| Element E                 |                               |
+-----------------------------------------------------------+
|<============ b ===========|                      |
       |                    |                      |
       +--------------------|----------------------+
       |========= a =======>|

       a is 50% width of P
       b is 50% width of E

น่าเสียดายนี่ใช้งานได้สำหรับการจัดกึ่งกลางแนวนอนเท่านั้นเนื่องจากการคำนวณเปอร์เซ็นต์มาร์จิ้นจะสัมพันธ์กับความกว้างเสมอ เช่นไม่เพียงmargin-leftและmargin-rightแต่ยังmargin-topและmargin-bottomมีการคำนวณด้วยความเคารพต่อความกว้าง

ความเข้ากันได้ของเบราว์เซอร์จะไม่มีปัญหา: https://caniuse.com/#feat=transforms2d


มันไม่ทำงานสำหรับการจัดตำแหน่งในแนวตั้ง (เมื่อ .inner มีความสูงขนาดใหญ่ที่ .outer)
cronfy

1
@cronfy เลขแนวตั้งก็จะไม่ทำงานเพราะmargin-top: 50%จะเป็น 50% ของความกว้าง ไม่สูงตามที่ต้องการ
yunzen

2
นั่นคือทางออกที่งดงามที่สุด
Souhaieb Besbes

ค้นหาวิธีแก้ปัญหาในขณะที่ดีที่สุดง่ายที่สุด ไชโย
lauWM

2
นี่คือเวทย์มนตร์ที่บริสุทธิ์ ขอบคุณ! ทำงานได้อย่างสมบูรณ์ใน Safari และ Chrome (พร้อมการเพิ่ม-webkit-transform: translateX(-50%);เพื่อการวัดที่ดี)
Nick Schneble

22

วาง div ขนาดใหญ่ไว้ใน div จัดกึ่งกลางนั้นและจัดกึ่งกลางของภาพภายใน div นั้น

ศูนย์นี้อยู่ในแนวนอน:

HTML:

<div class="imageContainer">
  <div class="imageCenterer">
    <img src="http://placekitten.com/200/200" />
  </div>
</div>

CSS:

.imageContainer {
  width: 100px;
  height: 100px;
  overflow: hidden;
  position: relative;
}
.imageCenterer {
  width: 1000px;
  position: absolute;
  left: 50%;
  top: 0;
  margin-left: -500px;
}
.imageCenterer img {
  display: block;
  margin: 0 auto;
}

การสาธิต: http://jsfiddle.net/Guffa/L9BnL/

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


สิ่งนี้จบลงที่ขอบด้านซ้ายของภาพที่อยู่ตรงกลางภายใน "imageContainer" ตามที่ฉันแสดงความคิดเห็นข้างต้น div คอนเทนเนอร์รูปภาพของเราคือความกว้างของของไหลและความสูงคง
Tom

1
@ ทอม: หากฉันลบการwidthตั้งค่าบนคอนเทนเนอร์มันจะเป็นความกว้างของพาเรนต์และภาพจะอยู่กึ่งกลางแม้ว่าหน้าจะแคบกว่ารูปภาพนั่นคือขอบด้านซ้ายมากเท่ากับขอบด้านขวาเท่าที่จะถูกซ่อน : jsfiddle.net/Guffa/L9BnL/2
Guffa

ขอบคุณสำหรับแรงบันดาลใจ ฉันใช้ตำแหน่ง: สัมพันธ์กับ. imageCenter วิธีนี้ฉันไม่ต้องการตำแหน่ง: สัมพันธ์กับคอนเทนเนอร์หลัก
user3153298

มีเคล็ดลับที่ชาญฉลาดสำหรับคำถามนี้และพวกเขาได้รับข้อเสียทั้งหมด งานบางอย่าง "ดีกว่า" แต่ไม่เข้าใจง่าย วิธีการแก้ปัญหานี้ทำให้รู้สึกที่สมบูรณ์แบบภาพจะถูกจัดให้อยู่กึ่งกลางตามปกติใน div ที่กว้างขึ้นที่ถูกครอบตัด มันรู้สึกผิด แต่มันใช้งานได้โดยไม่ผิดกฎหมายของเว็บ - ฟิสิกส์ ฉันเลือกตัวเลือกนี้กับลูกเล่นที่ยากต่อการเข้าใจแม้ว่าจะรู้สึกสกปรกบ้าง
Radley Sustaire

9

มาถึงช่วงท้ายเกม แต่ฉันพบว่าวิธีนี้ใช้งานง่ายมาก https://codepen.io/adamchenwei/pen/BRNxJr

CSS

.imageContainer {
  border: 1px black solid;

  width: 450px;
  height: 200px;
  overflow: hidden;
}
.imageHolder {
  border: 1px red dotted;

  height: 100%;
  display:flex;
  align-items: center;
}
.imageItself {
  height: auto;
  width: 100%;
  align-self: center;

}

HTML

<div class="imageContainer">
  <div class="imageHolder">
    <img class="imageItself" src="http://www.fiorieconfetti.com/sites/default/files/styles/product_thumbnail__300x360_/public/fiore_viola%20-%202.jpg" />
  </div>
</div>

3
ดี! สามารถลดความซับซ้อนได้เช่นกัน เคล็ดลับจะทำโดยdisplay: flexในภาชนะแม่และalign-self: centerในภาพ นี่คือรุ่นที่ปรับให้เหมาะสมที่สุด: codepen.io/anon/pen/dWKyey
caiosm1005

5

อย่าใช้ความกว้างคงที่หรือความสูงที่แน่นอนกับแท็กรูปภาพ รหัสแทนมัน:

      max-width:100%;
      max-height:100%;

เช่นhttp://jsfiddle.net/xwrvxser/1/


1
จากนั้นปล่อยให้พื้นที่รอบ ๆ ภาพซึ่งฉันเชื่อว่าพวกเขากำลังพยายามหลีกเลี่ยง
Eoin

3

ฉันเป็นแฟนตัวยงของการสร้างภาพพื้นหลังของ div / node - จากนั้นคุณสามารถใช้background-position: centerคุณลักษณะเพื่อจัดกึ่งกลางโดยไม่คำนึงถึงขนาดของหน้าจอ


9
นี่ไม่ใช่วิธีการใช้รูปภาพที่สามารถเข้าถึงได้ มันอาจทำงานได้ดีสำหรับรูปภาพที่ตกแต่ง แต่ภาพใด ๆ ที่เป็นข้อมูลความต้องการข้อความ alt
user2532030

0

ความกว้างและความสูงเป็นเพียงตัวอย่าง:

parentDiv{
    width: 100px;
    height: 100px;
    position:relative; 
}
innerDiv{
    width: 200px;
    height: 200px;
    position:absolute; 
    margin: auto;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

มันจะต้องทำงานให้กับคุณถ้าด้านซ้ายและด้านบนของ div หลักของคุณไม่ใช่ด้านบนและด้านซ้ายของหน้าต่างหน้าจอของคุณ มันใช้งานได้สำหรับฉัน


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

2
เทคนิคนี้ใช้งานได้หากภาพมีขนาดเล็กกว่าคอนเทนเนอร์
otherDewi

0

ฉันพบว่าสิ่งนี้เป็นโซลูชันที่หรูหรากว่าโดยไม่ต้องงอ:

.wrapper {
    overflow: hidden;
}
.wrapper img {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* height: 100%; */ /* optional */
}

0

คำตอบที่ยอดเยี่ยมของ @yunzen

ฉันเดาว่าหลายคนกำลังค้นหาหัวข้อนี้กำลังพยายามใช้ภาพขนาดใหญ่เป็นภาพพื้นหลัง "ฮีโร่" เช่นในหน้าแรก ในกรณีนี้พวกเขามักจะต้องการให้ข้อความปรากฏบนภาพและทำให้ขนาดบนอุปกรณ์เคลื่อนที่ดีขึ้น

นี่คือ CSS ที่สมบูรณ์แบบสำหรับภาพพื้นหลัง (ใช้บน<img>แท็ก):

/* Set left edge of inner element to 50% of the parent element */
margin-left: 50%;

/* Move to the left by 50% of own width */
transform: translateX(-50%);

/* Scale image...(101% - instead of 100% - avoids possible 1px white border on left of image due to rounding error */
width: 101%;

/* ...but don't scale it too small on mobile devices - adjust this as needed */
min-width: 1086px;

/* allow content below image to appear on top of image */
position: absolute;
z-index: -1;

/* OPTIONAL - try with/without based on your needs */
top: 0;

/* OPTIONAL - use if your outer element containing the img has "text-align: center" */
left: 0;

-1

ทางเลือกหนึ่งที่คุณสามารถใช้ได้คือobject-fit: coverมันมีพฤติกรรมเช่นbackground-size: coverนี้เล็กน้อย เพิ่มเติมเกี่ยวกับวัตถุพอดี

ไม่สนใจ JS ทั้งหมดด้านล่างนั่นเป็นเพียงการสาธิต

กุญแจสำคัญในที่นี้คือคุณต้องตั้งค่ารูปภาพภายใน wrapper และให้คุณสมบัติดังต่อไปนี้

.wrapper img {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

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

ข้อเสียเพียงอย่างเดียวobject-fitคือมันไม่ทำงานบน IE11

// for demo only
const wrapper = document.querySelector('.wrapper');
const button = document.querySelector('button');
const widthInput = document.querySelector('.width-input');
const heightInput = document.querySelector('.height-input');


const resizeWrapper = () => {
  wrapper.style.width = widthInput.value + "px";
  wrapper.style.height = heightInput.value + "px";
}

button.addEventListener("click", resizeWrapper);
.wrapper {
  overflow: hidden;
  max-width: 100%;
  margin-bottom: 2em;
  border: 1px solid red;
}

.wrapper img {
  display: block;
  height: 100%;
  width: 100%;
  object-fit: cover;
}
<div class="wrapper">
  <img src="https://i.imgur.com/DrzMS8i.png">
</div>


<!-- demo only -->
<lable for="width">
  Width: <input name="width" class='width-input'>
</lable>
<lable for="height">
  height: <input name="height" class='height-input'>
</lable>
<button>change size!</button>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.