Help us understand the problem. What is going on with this article?

スクロールバーで横幅がずれる

More than 3 years have passed since last update.

経緯

現在、以下のような環境でフロントエンドのサイトを作成しています。

名称 バージョン
Vue.js 2.3.4
Element UI 1.4.4
Element Theme Default 1.4.4

※ 他にもありますが、ここでは省略。ブラウザはiOSのChrome。

ハマり事象

私がハマった事象の概要は、「ElementUIのダイアログを開くと、fixedされているヘッダーが15pxくらい横に動く。(ダイアログを閉じた時も動く)」というものです。

これは、以下の条件の場合に発生します。

  1. ダイアログの裏のメインコンテンツが垂直方向のスクロールを表示している場合
  2. ElementUIのダイアログを、modal: trueかつlock-scroll: true(要はデフォルト)で開いた場合
  3. Flexboxなどでメインコンテンツを中央寄せしている場合
  4. メインコンテンツのヘッダーやナビゲーションをposition: fixedしていた場合

ソースコード例は以下のような感じとします。

index.html
<html>
  <head>
  <!--省略-->
  </head>
  <body>
    <div id="app">
      <header>
        <p>ヘッダー</p>
      </header>

      <main>
        <p>メインコンテンツ</p>
        <el-button type="primary" @click="enabledDialog = true">
          ボタン
        </el-button>

        <el-dialog title="ダイアログ" :visible.sync="enabledDialog">
          ダイアログの中身
        </el-dialog>
      </main>
    </div>
  </body>
</html>
app.js
window.Vue = require('vue');

import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/ja'
import 'element-theme-default/theme/index.css'
Vue.use(ElementUI, {locale})

const vm = new Vue({
  el: '#app',
  data: {
    enabledDialog: false
  }
})

app.scss
header {
  height: 40px;
  position: fixed;
  width: 100%;
  z-index: 10;
}

main {
  // ヘッダーの分だけ余白を取る
  padding-top: 40px;
}

body {
  // スクロールの出る画面と出ない画面でずれるのを防止するため出しっ放しにする
  overflow-y: scroll;
}

という感じです。良くあるヘッダー固定の構成です。

要因

ElementUIのダイアログを上記のオプション指定で開くと、ダイアログの裏のコンテンツのスクロールバーをoverflow: hiddenにしてくれます(bodyタグのスタイルに追加する)。
こうすることで、ダイアログ内をスクロールした時に、裏のコンテンツのスクロールが動くといった問題を解決できます。

また、同様にpadding-right: 15pxbodyタグにスタイル指定しています。
これは、スクロールバーの幅が15pxくらいなので、メインコンテンツのスクロールバーを消す分を打ち消しています。

しかし、このpadding-rightは、position: fixedであるヘッダーには機能せず、ヘッダーだけがスクロールバーが消える分を打ち消せずにずれてしまうわけです。

解決策

スクロールバーの幅に依存しないスタイル指定

上記を参照し、修正した結果のコードは以下のようになりました。
※ Sassのみの変更

app.scss
header {
  height: 40px;
  position: fixed;
  // width: 100%;
  width: calc(100vw - 15px); /* 追加 */
  z-index: 10;
}

main {
  // ヘッダーの分だけ余白を取る
  padding-top: 40px;
}

body {
  // スクロールの出る画面と出ない画面でずれるのを防止するため出しっ放しにする
  overflow-y: scroll;
  width: calc(100vw - 15px); /* 追加 */
}

以上。

tds517
しがない業務系SE
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした