Невелике зображення в центрі Div


175

Я намагався розібратися, як централізувати негабаритний образ у div лише за допомогою css.

Ми використовуємо текучий макет, тому ширина контейнерів зображень змінюється залежно від ширини сторінки (висота Div встановлюється). Зображення сидить у діалоговому вікні, знецінивши вставку тіні, щоб воно виглядало так, ніби ви переглядаєте сторінку біля зображення.

Саме зображення було розміщене для заповнення навколишнього діва за найширшим можливим значенням (дизайн має max-widthзначення).

Це зробити досить просто, якщо зображення менше, ніж навколишній div:

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

Але коли зображення більше, ніж діва, воно просто починається з лівого краю та знаходиться від центру праворуч (ми використовуємо overflow: hidden).

Ми можемо призначити width=100%, але веб-переглядачі виконують велику роботу щодо зміни розмірів зображень та веб-дизайну навколо високоякісних зображень.

Будь-які ідеї щодо центрування зображення, щоб overflow:hiddenрівномірно відрізати обидва краї?


2
Ви коли-небудь вирішували цю проблему @Tom? На даний момент я стикаюся з тим же питанням. :)
ctrlplusb

Я припускаю, що ширина вашого зображення змінюється.
іншеДеві

Відповіді:


365

Спробуйте щось подібне. Це повинно зосереджувати будь-який величезний елемент посередині вертикально та горизонтально щодо його материнської точки зору, незалежно від їх розмірів.

.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, воно повинно працювати.
Майкл Крупп

16
Чому б не використовувати -100%верхній / правий / нижній / лівий? При цьому контейнер може мати буквально будь-яку ширину.
Саймон,

15
Так, я також відчував цю -100%проблему ^^. Btw: якщо ви додаєте min-widthі min-heightз 100%вас в основному отримати background-size: cover;поведінку з тегами зображення -> jsfiddle
Simon

3
@HarrisonPowers Добре, що батько повинен мати висоту курсу, будь то фіксований чи динамічний. Він також спрацює, якщо якийсь інший вміст заповнює div, що спричиняє його висоту (наприклад, текст).
hyounis

162

Це давнє питання Q, але сучасне рішення без флексбоксу або абсолютного положення працює так.

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 має більшу висоту, ніж.)
cronfy

1
@cronfy No. вертикально це не спрацює, бо margin-top: 50%буде 50% ширини . не висота за бажанням.
юнзен

2
Це, безумовно, найелегантніше рішення
Сухаїб Бесбес

деякий час шукати рішення, найкраще, найпростіше; Ура
lauWM

2
Це чиста магія чарівника. Дякую! Відмінно працює в Safari та Chrome (з -webkit-transform: translateX(-50%);хорошою мірою)
Нік Шнебл

22

Помістіть великий діл всередину діва, по центру його і в центрі зображення всередині цього діва.

Це центрує його горизонтально:

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/

Для центрування його також можна вертикально використовувати для внутрішнього поділу, але вам знадобиться висота зображення, щоб розмістити його абсолютно всередині нього.


Це закінчилося, щоб лівий край зображення був по центру в "imageContainer". Як я коментував вище, наш контейнер із зображеннями контейнера для зображень має ширину рідини та фіксовану висоту.
Том

1
@Tom: Якщо я видаляю widthналаштування на контейнері, він буде шириною батьківського, і зображення буде по центру, навіть якщо сторінка вужча, ніж зображення, тобто стільки лівого краю, скільки правий край буде приховано : jsfiddle.net/Guffa/L9BnL/2
Guffa

Дякую за натхнення Я використовую позицію: відносно для .imageCenter. Таким чином, мені не потрібна позиція: відносна для батьківського контейнера.
user3153298

У цьому питанні є багато хитромудрих хитрощів, і всі вони мають свої недоліки. Деякі працюють «краще», але їх зовсім не легко зрозуміти. Це рішення має ідеальний сенс, зображення зазвичай зосереджується в більш широкому розділі, який обрізається. Він почуває себе неправильно, але, безумовно, працює, не порушуючи законів веб-фізики. Я вибрав цей варіант через кілька інших дуже важких для розуміння хитрощів, навіть якщо він відчуває себе трохи брудним.
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

Я величезний шанувальник створення зображення фоном діва / вузла - тоді ви можете просто використовувати background-position: centerатрибут, щоб відцентрувати його незалежно від розміру екрана


9
Це не доступний спосіб використання зображень. Це може спрацювати для декоративних зображень, але будь-яке інформаційне зображення потребує введення тексту.
користувач2532030

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;
}

Це повинно працювати для вас, якщо ліворуч і верхній частині вашої батьківської діви не у верхній і лівій частині вікна вашого екрана. Це працює для мене.


Здавалося, нічого не змінило. Не впевнений, чи це пов’язано з тим, що ширина є текучою, тоді як висота визначається тим, що було б батьківським ділом.
Том

2
Ця методика працює, якщо зображення менше, ніж контейнер.
іншеДеві

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 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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.