---
slug: "ios-safari-software-keyboard-refresh-valid-window-height"
title: "iOS Safari でソフトウェアキーボードが出た時にブラウザの有効な天地サイズを取得し、レイアウトを整える"
description: "C 拡張モジュール (.pyd / .so) のコンパイルで Python のバージョンが原因で失敗する場合に、対応バージョンを確認して切り替える手順。"
url: "https://www.ytyng.com/blog/ios-safari-software-keyboard-refresh-valid-window-height"
publish_date: "2023-07-16T11:02:53Z"
created: "2023-07-16T11:02:53Z"
updated: "2026-05-11T13:21:39.524Z"
categories: ["css", "iOS"]
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20250605/b49838cc046f41228977cf84463f7901.png.webp?width=768"
has_video: true
has_music: true
video_urls: ["https://media.ytyng.net/ytyng-blog/287/featured-video-1.mp4", "https://media.ytyng.net/ytyng-blog/287/featured-video-2.mp4", "https://media.ytyng.net/ytyng-blog/287/featured-video-3.mp4"]
music_urls: ["https://media.ytyng.net/ytyng-blog/287/featured-music-287-1.mp3", "https://media.ytyng.net/ytyng-blog/287/featured-music-287-3.mp3"]
lang: "ja"
---

# iOS Safari でソフトウェアキーボードが出た時にブラウザの有効な天地サイズを取得し、レイアウトを整える

固定フッターがある場合のページレイアウトにしていると、iOS でソフトウェアキーボードが表示された時にレイアウトが破綻する場合がある。

レイアウトの最大天地の高さを CSS 変数にして、iOS の場合 は更新し続けるようなコードにして解決した。


```css
:root {
  --visual-viewport-height: 100%;
}

body {
    height: var(--visual-viewport-height);
}
```

```javascript
const w = window as any;
const refreshSize = () => {
  w.document.documentElement.style.setProperty('--visual-viewport-height', `${w.visualViewport.height}px`)
  w.scrollTo(0, 0)
}
w.mobileUIRefreshInterval = setInterval(refreshSize, 300)
refreshSize()

// 条件を解除したい場合
...
clearInterval(w.mobileUIRefreshInterval)
```


# 補足事項

## iOS Safari で、100vh を正しく計算するための -webkit-fill-available というオプションがある
今回の用途には使えなかったが、別の用途でうまく使える場合もありそうなので書いておく。


```css
body {
    height: 100vh;
}
@supports (-webkit-touch-callout: none) {
  body {
    /* The hack for Safari */
    height: -webkit-fill-available;
  }
}
```

参考: [iOSでも100vhをいい具合に調整して画面の高さいっぱいに要素を表示させる](https://zenn.dev/tak_dcxi/articles/2ac77656aa94c2cd40bf)

## ソフトウェアキーボードが表示されている時は、強制的にスクロールが有効になる
`body` に `overflow: fixed` をつけていても、iOS でソフトウェアキーボードが表示されると強制的にスクロールができるようになる。

この場合、固定フッターがあるレイアウトの Web アプリの場合、使用感が良くない。

いくつか対策はあるけど、SetInterval で `window.scrollTo(0, 0)`` を定期的に実行してしまうのが良いと思った。
実際に window のスクロールがされた時はちょっとちらついてしまう問題はあるけど、実用的には十分で安定している。
