オーバーサイズの画像をDivの中央に配置


175

私はcssのみを使用してdiv内で特大の画像を中央に配置する方法を整理しようとしています。

流動的なレイアウトを使用しているため、画像コンテナーの幅はページの幅と同じように変化します(divの高さは固定されています)。画像はdiv内にあり、値をはめ込みボックスの影で囲んでいるので、ページを画像で見ているように見えます。

画像自体は、可能な限り広い値で周囲のdivを満たすようにサイズ設定されています(デザインにはmax-width値があります)。

画像が周囲のdivよりも小さい場合は、非常に簡単です。

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

ただし、画像がdivより大きい場合は、左端から始まり、中央から右にずれています(を使用していますoverflow: hidden)。

を割り当てることもできwidth=100%ますが、ブラウザは画像のサイズを変更するというお粗末な作業を行い、Webデザインは高品質の画像を中心にしています。

画像をoverflow:hidden中央に配置して両端を均等にカットするアイデアはありますか?


2
@Tomでこの問題を解決したことがありますか?現在、同じ問題が発生しています。:)
ctrlplusb '26 / 09/26

画像の幅が異なると思います。
otherDewi 2013年

回答:


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

3
私が理解しているように、画像(2 * 9999px x 2 * 9999px)よりも大きい(うまくいけば)要素を作成し、その要素(マージン:auto)の内側に画像を中央配置するため、機能します。したがって、画像が2 * 9999pxを超えない限り、機能するはずです。
マイケルクルップ2014年

16
-100%上/右/下/左に使用しないのはなぜですか?これにより、コンテナーは文字通り任意の幅を持つことができます。
Simon

15
ええ、私も-100%問題を経験しました^^。ところで:あなたが追加min-widthmin-height100%基本的にbackground-size: cover;イメージタグでビヘイビアを取得した場合-> jsfiddle
Simon

3
@HarrisonPowersまあ、それが固定であろうと動的であろうと、親にはもちろん高さが必要です。他のコンテンツがdivをいっぱいにして高さ(テキストなど)になっている場合にも機能します。
hyounis 2014年

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-leftmargin-right、だけでなく、margin-topおよびmargin-bottom幅に対して計算されます。

ブラウザの互換性は問題ありません:https : //caniuse.com/#feat=transforms2d


垂直方向の配置では機能しません(.innerの高さが.outerよりも大きい場合)
2016

1
@cronfyいいえ。垂直方向ではmargin-top: 50%幅の 50%になるため機能しません。希望どおりの高さではありません。
yunzen 2017

2
これは、最もエレガントなソリューションです
Souhaieb Besbes

しばらくの間、最善の最も簡単な解決策を探します。乾杯
lauWM 2017

2
これは純粋な魔法の魔法です。ありがとうございました!SafariとChromeで完全に動作します(-webkit-transform: translateX(-50%);
ある程度の

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は流動的な幅と固定された高さです。
トム

1
@Tom:widthコンテナの設定を削除すると、親の幅になり、ページが画像より狭い場合でも画像が中央に配置されます。つまり、右端と同じくらい左端が非表示になります。 :jsfiddle.net/Guffa/L9BnL/2
Guffa

インスピレーションをありがとう。.imageCenterの相対位置を使用します。この方法では、親コンテナの相対位置は必要ありません。
user3153298 2015年

この質問には多くの巧妙なトリックがあり、それらにはすべて欠点があります。「上手く」機能するものもありますが、まったく理解しにくいものもあります。このソリューションは完全に理にかなっており、画像は通常、トリミングされているより広いdivの中央に配置されます。それは間違っていると感じますが、ウェブ物理学の法則を破ることなく確実に機能します。私はこのオプションを、他のいくつかの非常に理解しにくいトリックよりも、少し汚れていても選択しました。
Radley Sustaire、2018年

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
これは、画像を使用するアクセス可能な方法ではありません。装飾的な画像では問題なく機能しますが、有益な画像には代替テキストが必要です。
user2532030 2017年

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であるものに固定されているという事実が原因であるかどうかはわかりません。
トム

2
この手法は、画像がコンテナよりも小さい場合に機能します。
otherDewi 2013年

0

私はこれがflexなしのよりエレガントなソリューションであることがわかりました:

.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

使用できるオプションの1つはobject-fit: cover、動作が少し似ていることbackground-size: coverです。object-fitの詳細。

以下の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>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.