Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@mucaci

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

経緯

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

名称 バージョン
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); /* 追加 */
}

以上。

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
15
Help us understand the problem. What are the problem?