IPhone Xの発売が間近に迫っているので、私はゲームを先取りし、デザインの変更を処理できるようにいくつかのWebアプリケーションを準備しようとしています。その最大のものはフロントカメラを収容する新しい「ノッチ」です。
Javascriptでこれをどうにかして検出する方法があるのか、またはある可能性があるのではないかと思っていました。
興味深いことに、Chris Coyierが The "Notch" and CSS についての記事を書いており、safe-area-inset-right
絶え間ない。これはJavaScriptでアクセスできる方法はありますか?これは信頼できるテストですか?.
if (window.constant.safeAreaInsetRight) {
var notch = true;
}
これは少しやりにくいかもしれませんが、画面の利用可能な高さと幅を取得し、これらをこの仕様に一致させることで、iPhone Xかどうかを判断できます。
ご注意ください
縦向きでは、iPhone Xのディスプレイの幅は、iPhone 6、iPhone 7、およびiPhone 8の4.7インチディスプレイの幅と一致します。ただし、iPhone Xのディスプレイは、4.7インチディスプレイよりも145 pt高いです...
したがって、最初に、それがuserAgentを介してiPhoneであるかどうかを確認します。次に、実際の画面の領域をチェックします(デフォルトで縦向きになっている方向を除く)。最後に、それが画面を介してiPhoneXであることがわかったら、方向を決定できる寸法(上のiPhone X図の下の表に基づく)
if (navigator.userAgent.match(/(iPhone)/)){
if((screen.availHeight == 812) && (screen.availWidth == 375)){
if((window.innerHeight == "375") && (window.innerWidth == "812")){
// iPhone X Landscape
}else{
// iPhone X Portrait
}
}
}
参照:
CSSソリューションに関しては、私は昨日それについて有用なかもしれない興味深い記事を見つけました
固定位置のヘッダーバーがあり、iOS 10のCSSが現在次のようになっているとします。
header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 44px;
padding-top: 20px; /* Status bar height */
}
IPhone Xおよびその他のiOS 11デバイス用に自動的に調整するには、viewportメタタグにviewport-fit = coverオプションを追加し、定数を参照するようにCSSを変更します。
header {
/* ... */
/* Status bar height on iOS 10 */
padding-top: 20px;
/* Status bar height on iOS 11+ */
padding-top: constant(safe-area-inset-top);
}
Constant()構文の解釈方法がわからない古いデバイスでは、フォールバック値をそのままにしておくことが重要です。 CSSのcalc()式で定数を使用することもできます。
// iphone X detection
function hasNotch() {
if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
let div = document.createElement('div');
div.style.paddingBottom = 'env(safe-area-inset-bottom)';
document.body.appendChild(div);
let calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom, 10);
document.body.removeChild(div);
if (calculatedPadding > 0) {
return true;
}
}
return false;
}
@ youssef-makboulの回答と@hjellekによるコメント以降、iOSはconstant()からenv()構文に変更され、現在のすべてのiPhone X iOSバージョンでこのアプローチをサポートするにはフォールバックが必要です。
const hasNotch = function () {
var proceed = false;
var div = document.createElement('div');
if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
div.style.paddingBottom = 'env(safe-area-inset-bottom)';
proceed = true;
} else if (CSS.supports('padding-bottom: constant(safe-area-inset-bottom)')) {
div.style.paddingBottom = 'constant(safe-area-inset-bottom)';
proceed = true;
}
if (proceed) {
document.body.appendChild(div);
let calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom);
document.body.removeChild(div);
if (calculatedPadding > 0) {
return true;
}
}
return false;
};
最近これにぶつかった。 CSS環境変数(env())の値をCSSカスタムプロパティに設定し、JavaScriptを介してその値を読み取ることができます。
CSS:
:root {
--sat: env(safe-area-inset-top);
--sar: env(safe-area-inset-right);
--sab: env(safe-area-inset-bottom);
--sal: env(safe-area-inset-left);
}
JS:
getComputedStyle(document.documentElement).getPropertyValue("--sat")
0.7k notch-detected-event スクリプトをページに追加します。デバイスにノッチが含まれている場合は、notch-detected
イベントを発生させます。
window.addEventListener('notch-detected', function(e) {
console.log("Notch detected, move shit around");
});
また、data-notch="true"
要素にdata-orientation="portrait|landscape"
および<html>
を追加して、CSSを使用してレイアウトを微調整できるようにします。
/* make room for the notch at the top */
html[data-notch][data-orientation="portrait"] body {
padding-top: 44px;
height: calc(100% - 44px);
}
/* make room for the notch at the sides */
html[data-notch][data-orientation="landscape"] body {
padding-left: 44px;
padding-right: 44px;
width: calc(100% - 44px - 44px);
}
お役に立てれば!
追加するもののカップル:
Index.htmlに以下が含まれていることを確認してください
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
さらに:
これに関する素晴らしい記事: CSS Tricks Notch
私はこれを使っています:
function hasNotch() {
//iphone X 1.11
if (document.documentElement.clientHeight == 812 && document.documentElement.clientHeight == 375 && !!window.matchMedia && window.matchMedia("only screen and (-webkit-device-pixel-ratio: 3)").matches && iOSversion()[0] == 11) {
return true;
}
var proceed = false;
var div = document.createElement('div');
if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
div.style.paddingBottom = 'env(safe-area-inset-bottom)';
proceed = true;
} else if (CSS.supports('padding-bottom: constant(safe-area-inset-bottom)')) {
div.style.paddingBottom = 'constant(safe-area-inset-bottom)';
proceed = true;
}
if (proceed) {
return true;
}
return false;
};
[〜#〜] css [〜#〜]はTypeScriptのグローバルインターフェイスライブラリです。
interface CSS {
escape(value: string): string;
supports(property: string, value?: string): boolean;
}
declare var CSS: CSS;
または[〜#〜] css [〜#〜]:
$margin_max_constant_notch:unquote('max(-12px, constant(safe-area-inset-left))');
$margin_max_env_notch:unquote('max(-12px, env(safe-area-inset-left))');
/*** iphone X 1.11, iphone XS (quote is OR) ***/
@media only screen
and (device-width : 375px)
and (max-device-width : 812px)
and (-webkit-device-pixel-ratio : 3),
/*** iphone XR ***/
screen and (device-width : 414px)
and (device-height : 896px)
and (-webkit-device-pixel-ratio : 2),
/*** iphone XS Max ***/
screen and (device-width : 414px)
and (device-height : 896px)
and (-webkit-device-pixel-ratio : 3),
/*** iphone XS Max Retina ***/
only screen and (-webkit-min-device-pixel-ratio: 3),
only screen and ( min--moz-device-pixel-ratio: 3),
only screen and ( -o-min-device-pixel-ratio: 3/1),
only screen and ( min-device-pixel-ratio: 3),
only screen and ( min-resolution: 458dpi),
only screen and ( min-resolution: 3dppx),
/** Google Pixel 3 XL **/
screen and (device-width: 360px)
and (device-height: 740px)
and (-webkit-min-device-pixel-ratio: 4),
only screen and ( min--moz-device-pixel-ratio: 4),
only screen and ( -o-min-device-pixel-ratio: 4/1),
only screen and ( min-device-pixel-ratio: 4),
only screen and ( min-resolution: 523dpi),
only screen and ( min-resolution: 4dppx) {
@media(orientation: portrait) {
/* mobile - vertical */
@media (max-width: 768px) {
/* up to 768px */
}
@media (max-width: 480px) {
/* up to 480px */
}
@media only screen and (max-width: 400px) {
/* up to 400px */
}
}
@media(orientation: landscape) {
html,body {
padding: $margin_max_constant_notch;
padding: $margin_max_env_notch;
}
/* mobile - horizontal */
@media screen and (max-width: 900px) {
/* up to 900px */
}
}
}
/** iphone X 1.12 **/
@supports(padding: max(0px)) {
@media screen and (device-width : 375px)
and (device-height : 812px)
and (-webkit-device-pixel-ratio : 3) {
@media(orientation: portrait) {
/* mobile - vertical */
@media (max-width: 768px) {
//até 768px
}
@media (max-width: 480px) {
/* up to 480px */
}
@media only screen and (max-width: 400px) {
/* up to 400px */
}
}
@media(orientation: landscape) {
html, body {
padding: $margin_max_constant_notch;
padding: $margin_max_env_notch;
}
@media screen and (max-width: 900px) {
/* up to 900px */
}
}
}
}
/** iphone 8 **/
@media only screen
and (device-width : 375px)
and (device-height : 667px)
and (-webkit-device-pixel-ratio : 2),
/** iphone 8 PLUS **/
screen and (device-width : 414px)
and (device-height : 736px)
and (-webkit-device-pixel-ratio : 3) {
@media(orientation: portrait) {
/* mobile - vertical */
}
@media(orientation: landscape) {
/* mobile - horizontal */
}
}
@media only screen
/** IPADS **/
and (min-device-width: 1024px)
and (max-device-width: 1366px)
and (-webkit-min-device-pixel-ratio: 2) {
/* for ipads */
@media(orientation: portrait) {
/* ipad - vertical */
}
@media(orientation: landscape) {
/* ipad - horizontal */
}
}