0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[tips]画像をdivで囲み縦横比を指定することで読み込み時のズレを防止する

Last updated at Posted at 2020-09-05

画像の読み込みを制することでイライラをなくす

自分のwiki の転記です。

Code

環境

お試しのため create react app を使っている

$ npx create-react-app my-app
$ cd my-app
$ npm start

コード

App.js
import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>Loading Spinner</h1>
        <img alt="" src="https://penguin-ogp.vercel.app/api/ogp?text=こんにちは人類" />
        <p>イメージを表示します</p>
      </header>
    </div>
  );
}

export default App;

表示する画像は https://github.com/itizawa/penguin-ogp で生成したもの。

このコードには読み込み時の問題がある。
読み込みが遅い環境の場合、「イメージを表示します」のメッセージが読み込まれた画像によってその分だけ下にずれる。

gamen_test1 (1).gif

改善するために、img に height と width を指定しようとするがうまくは行かない

うまく行かない指定
<img width="100%" height="auto" alt="" src="https://penguin-ogp.vercel.app/api/ogp?text=こんにちは人類" />
読み込み後に初めて width と height の情報が得られるため、初めからその画像分の幅を取ることはできない。

縦横比を指定して読み込み前に幅を指定する

create react app では sass が使えないため、
$ yarn add node-sass
を実行しインストールしておく。

元の画像は、 w1200, h660 なので、高さ 1 に対して横幅は 0.55。
それを踏まえたコードが次のようになる。

js

App.js
import React from 'react';
import './App.scss';

function App() {
  return (
    <div className="App">
      <div className="App-container">
        <h1>Loading Spinner</h1>
        <div className="fix-aspect-box">
          <img alt="" src="https://penguin-ogp.vercel.app/api/ogp?text=こんにちは人類" />
        </div>
        <p>イメージを表示します</p>
      </div>
    </div>
  );
}

export default App;

scss

App.scss
.fix-aspect-box {
  position: relative;
  width: 100%;
  padding-top: 55%;

  img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}

イメージは初めに額縁を用意しておいて、後から届いた画像を収まるように収縮して当てはめるという感じ。

gamen_test1 (2).gif

縦横比を指定しているから小さくなっても画像が引き伸ばされたりはしない。

最後に spinner を追加する。

先ほどの状態だと、無の空間にいきなり画像が表示される。
想定していないものがいきなり現れるのは気持ちの良いものではない。

そこで読み込み中は spinner を表示する。
https://design.webclips.jp/svg-loading-icon/

public に svg を配置しbackground-imageで読み込むことができる。

App.scss
.fix-aspect-box {
  position: relative;
  width: 100%;
  padding-top: 55%;

  img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

    // show spinner
    background-image: url('/spinner.svg');
    background-repeat: no-repeat;
    background-position: center center;
  }
}

gamen_test1.gif

完成 :tada:

コードはこちら
https://github.com/itizawa/loading-spinner

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?