風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

【覚書】viewport指定について

モバイルデバイス用のviewport設定についてまじめに調べようとしたら、深みにはまりそうだったので、とりあえず整理を兼ねて覚え書きを残しておく。
ついでに、viewportの簡易的な表示テストができるページも作ってみた




viewport の指定方法

viewportは、HTMLのhead内のmeta要素として指定する

<meta name="viewport" content="(viewportのパラメータ)" />

viewportのパラメータはカンマ(",")区切りで指定。

なお、これは主としてモバイルデバイス(スマートフォン・タブレットなど)用の設定であり、基本的にはデスクトップ用ブラウザの表示には影響を与えない。
ブラウザが常に全画面で表示されるために、基本、ウィンドウの幅=デバイスの表示幅となるモバイルデバイスにおいて(余白が出来たり見切れたりすることなく)適切なページを表示を行うための指定という認識。

viewportの主要なパラメータ

<meta name="viewport"> の content の値
設定可能な値 説明
width 正の整数または文字列 device-width ウェブサイトを描画したいビューポートの幅をピクセル数で定義します。
height 正の整数またはテキスト device-height ビューポートの高さを定義します。どのブラウザーでも使用されていません。
initial-scale 0.0 から 10.0 までの、正の数値 デバイスの幅 (ポートレートモードでの device-width またはランドスケープモードでの device-height) とビューポートの寸法との比率を定義します。
maximum-scale 0.0 から 10.0 までの、正の数値 ズームの最大値を定義します。この値は minimum-scale と同じまたはより大きくしなければなりません。そうではないときの動作は未定義です。ブラウザーの設定でこの規則を無視できます。また、iOS 10 以降は既定で無視します。
minimum-scale 0.0 から 10.0 までの、正の数値 ズームの最小値を定義します。この値は maximum-scale と同じまたはより小さくしなければなりません。そうではないときの動作は未定義です。ブラウザーの設定でこの規則を無視できます。また、iOS 10 以降は既定で無視します。
user-scalable yes または no no を設定すると、ユーザーはページのズームができなくなります。既定値は yes です。ブラウザーの設定でこの規則を無視できます。また、iOS 10 以降は既定で無視します。

<meta>: 文書レベルメタデータ要素 - HTML: HyperText Markup Language | MDN
viewportを指定しないとどうなる?

viewport指定を省略した場合、モバイルデバイスでは、ブラウザが暗黙的にデフォルトのwidth値(ブラウザ毎に異なる、例えば980といった値)を用いて、これをウィンドウ(≒スクリーン)内に収めるように表示される。
例えば、デスクトップ向けのページなどで、横幅がこれより大きい値を前提として設計されていたら見切れてしまう。

device-width とは?

device-widthとは、モバイルデバイスが持つ画面(スクリーン)の論理解像度(ポイント実質解像度CSSピクセル)の横幅のことで、これはカタログに載っている解像度(画素数)とは異なる。
device-heightは同じく縦幅のことだが、ほとんど使うことはないと思われる。
例えば、iPhone X のディスプレイは5.8インチ・1125x2436ピクセルの解像度を持つが、device-widthは375(device-heightは812)となる。
すなわち、ブラウザのウィンドウで375px×812pxの画像を等倍で表示した場合、画面にピッタリと収まるサイズで表示されるということになる。

initial-scale とは?

基本的には、ページを表示した際の、最初の表示倍率(拡大率)のこと。
例えば、initial-scale=1 の時は等倍で、initial-scale=0.5の時は幅が半分に縮小(矩形としては4分の1)、initial-scale=2の時には幅が倍に拡大(矩形としては4倍)となる。

これだけならばよいのだが、ややこしいのが『条件によっては viewport の大きさに影響してしまう』ということ(後述)。

viewport が影響する主な要素

JavaScript

viewportの指定によりブラウザのウィンドウの大きさが決まることになるため、window.innerWidth・innerHeightといったパラメータに影響する。
なお、window.screen.widthやwindow.screen.availWidthは、viewportの指定によらず一定で、デバイス固有の値(≒device-width)を持つ。

viewport 設定テスト用ページについて

簡易的な viewport 設定テスト用ページを作成した。

viewport setting tester

  • radioボタンに応じて、meta[name="viewport"]を書き換えるようになっている。
  • 条件によっては、値を変更しても表示が変わらない場合がある。この場合、[Reload]を押すことで反映される。
    Mobile 版 Firefox では、[Reload]を押しても変わらない場合あり。この場合、ページをいったん閉じて、開きなおす必要がある。
  • Google Chrome の開発者ツールのモバイルデバイスエミュレータ(device toolbar)で、画面の拡大縮小(ピンチアウト/イン)の操作は、[Shift]+ドラッグ(スワイプ)で行う([Ctrl]+[+]/[-]では変化しないことに注意)。リセットは[Ctrl]+[0]。

具体的な viewport 指定の例

"width=device-width, initial-scale=1" で、万全!?

viewportについて調べていると、典型的な設定例として出てくるのは、

<meta name="viewport" content="width=device-width, initial-scale=1" />

のようなもの。

  • viewport(≒ブラウザのウィンドウ)幅を device-width に
  • 最初の表示倍率を 1 に

という指定。
f:id:furyu-tei:20180520095805p:plain

適切なレスポンシブ対応(メディアクエリのブレイクポイントの設定)が行われている場合には、この設定で問題は無い。

レスポンシブ対応がなされていない場合

レスポンシブ対応がなされておらず、『とりあえず、デスクトップ用の画面を、モバイルデバイスでも横幅が綺麗に収まる形で表示したい』という場合の設定。
例は、横幅1000pxで設計されているページの例

<meta name="viewport" content="width=1000, user-scalable=no" />

f:id:furyu-tei:20180520095818p:plain
本来ならば、width さえ指定しておけば、ブラウザが拡大率を適切に設定して、スクリーン内に収まるように調整してくれそうなもの。
ではなぜ user-scalable=no を設定しているのかというと、状況によってはこの自動調整がうまくいかないケース(等倍で表示されるケース)があったため
うまく自動調整されない場合の原因は不明。
いずれにしても、user-scalable=no にするとユーザーが拡大縮小できなくなってしまい不便なので、早期にきちんとレスポンシブ対応すべきではある。

レスポンシブ対応が不完全な場合

スマートフォンには対応したのだけれど、ある範囲(例えば横幅768px~1199px)のデバイス(タブレット)だけ表示が見切れる(デスクトップ用に1200px前提でページ設計)という場合の設定。

<meta name="viewport" content="width=device-width, initial-scale=1">

<script type="text/javascript">
(function () {
'use strict';

var minimum_screen_width_for_tablet = 768, // タブレットとみなすデバイス画面の最小論理解像度
    // ※ CSSメディアクエリの指定(例: @media (min-width: 768px) { ... })に合わせること
    viewport_width_for_tablet = 1200, // viewportとして指定する横幅(例えばデスクトップ用として想定されている最小の横幅)
    use_initial_scale = false,
    
    vieport_element = document.querySelector('meta[name="viewport"]'),
    adjust_viewport = function () {
        // TODO: 一部のWindows系モバイルデバイス(IEや旧Edgeを使用している場合等)では meta[name="viewport"] による指定が効かないので別途対応要
        try {
            var device_width = window.screen.width;
            
            if (minimum_screen_width_for_tablet <= device_width) {
                if (use_initial_scale) {
                    vieport_element.setAttribute('content', 'width=' + viewport_width_for_tablet + ', initial-scale=' + (device_width / viewport_width_for_tablet));
                    // 問題点: "width" と "initial-scale" で指定した場合うまく表示されないケースあり(デバイスを回転させた場合等)
                }
                else {
                    vieport_element.setAttribute('content', 'width=' + viewport_width_for_tablet + ', user-scalable=no');
                    // 問題点: "user-scalable=no" によりユーザーによるズーム不可となってしまう
                }
            }
            else {
                vieport_element.setAttribute('content', 'width=device-width, initial-scale=1');
            }
        }
        catch (error) {
            console.error(error);
        }
    };

window.addEventListener('orientationchange', function (event) {
    adjust_viewport();
});

window.addEventListener('resize', function (event) {
    adjust_viewport();
});

adjust_viewport();

})();
</script>

デフォルトとして、meta[name="viewport"]には"width=device-width, initial-scale=1"を指定しておき、JavaScript で window.screen.width によりデバイスのスクリーン幅(≒device-width)を調べ、条件に当てはまる場合だけ書き換えを行う。

上記は簡易的なものだが、
github.com
を使えばもっと細かく調整できる、かも(未確認)。

注意点・問題点など

initial-scale について

上記のとおり、initial-scaleは初期の表示倍率を示すほかに、条件によっては viewport の大きさに影響してしまう。
具体的には、

X = device-width / initial-scale
とするとき、
width < X となる場合には、viewport の幅として X が適用される(widthの指定は無視される)。

模様。
例えばdevice-widthが360のモバイルデバイスの場合に、
"width=640, initial-scale=0.5"
のような指定をすると、実際の viewport の幅としては 720(=360/0.5)が適用されてしまう(width=640の方は無視される)

また、initial-scale に 1 未満の値を指定しても、状況によってはうまく縮小表示されないケースもある。
具体的な条件は不明。ただし、この場合でも、user-scalable=no と併用すれば正しく縮小表示される模様。

ブラウザによってウィンドウサイズ(innerWidth/Height)の決定方法が異なっている?

f:id:furyu-tei:20180520095827p:plain

Google Chromeの場合
innerWidth/innerHeightは、ユーザーがscale(ピンチインで縮小表示)して表示可能な最大領域のピクセル数を示す模様。

この最大領域の横幅は、document.body の大きさと viewport の minimum-scale により、以下のように決まっている模様。

  • document.body の横幅が viewport の以下の場合には、viewport の幅
  • document.body の横幅が viewport より大きい場合、device-width / minimum-scale と document.body の横幅のうち、小さい方

あくまで最大領域に応じて決まるため、実際のユーザーの拡大縮小操作には影響されない。

Firefoxの場合
innerWidth/innerHeightは、ドキュメントのうち、ブラウザの表示領域に実際に表示されているピクセル数を示す模様。
ユーザーの拡大縮小操作に伴って変動する。

【未確認】Safariの場合
実機が無いため、確認できていない。

【未確認】Windows Tablet / Phone について

Windows 系のモバイルデバイスについては、meta[name="viewport"] による指定は効かないため、別途、CSS で @-ms-viewport による指定が必要
実機が無いこともあり、確認が取れていない。

【覚書】ノートン 360 のせいで、pip freeze がフリーズした件

Windows 10 上の Ubuntu で

$ pip freeze

を実行したら、文字通りフリーズしてしまった。
プロンプトに返ってこない。pip install 等を実行した場合も同様。

原因は、ノートン 360 Norton 360のファイアウォールだった。
同様の事が発生したときに焦らないように、メモ書きしておく。




原因と対策

Python 3(3.6.3)の python3 (実行ファイル) がブロックされていたのが原因。
ノートン 360 の
「設定」→「ファイアウォール」→「プログラム制御」
で確認すると、python3の『信頼』項目が『未確認』になっていた。
この状態で、アクセスが『自動』になっていると、ネットワークアクセスがブロックされてしまうため、これを手動で『許可』に変更して[適用する]必要があった。
ファイアウォールのプログラム制御画面

余談…というべきかどうか

ノートン 360 のライブアップデートで、インストール失敗

pip freeze や pip install が固まってしまう状態になった際、過去の経験


もあって、「どうせまた、ノートン 360 が原因だろう」と思い、軽い気持ちで手動でライブアップデートを実施したところ……再起動後に
ノートン 360のインストールでエラーがありました。続行できません。
と言われてしまい、往生した。
もちろん、ノートン 360 そのものも動作していないため、セキュリティ的にノーガード……。

その後の復旧

上記の状態で、どうしようもないのでそのまま強制的に再起動すると*1、今度は、
ライブアップデートエラー
のようなダイアログが現れた。
最初からこっちを出してくれ、と思わないでもない。
『サポートWebページに移動する』リンク先の指示に従って、『ノートン削除/再インストールツール』(NRnR.exe) をダウンロードして実行。
削除と再インストールを行うことで、なんとか復旧することができた。

*1:普通に再起動しようとすると、再起動をキャンセルしてとノートン360に言われてしまう……キャンセルせず、強制的に再起動する必要があった

【アマゾン注文履歴フィルタ】CSVファイルとExcelを使って必要な注文だけを印刷(PDF出力)する手順

アマゾン注文履歴フィルタ
furyu.hatenablog.com
で、『領収書を必要な分だけ細かく指定して印刷(PDF出力)したい』といった場合、いったん全件表示を行い、そこからダウンロードした CSV ファイルを Excel で読み込ませて必要な注文を絞り込むのが、比較的楽な方法だと思います。
ここでは、その手順を示します。




CSV ファイルと Excel を使って、必要な注文だけを絞り込む方法

  1. まず、対象月等の最低限の条件を指定し、
    f:id:furyu-tei:20180301002736p:plain
    [領収書印刷用画面]を開きます。

     

  2. 領収書の読み込みが完了したら(印刷はせずに)[注文履歴CSV(参考用)ダウンロード]をクリックし、
    f:id:furyu-tei:20180301002803p:plain
    CSVファイルをダウンロードします。

     

  3. ダウンロードしたCSVファイルをExcelで開き、適当な位置に作業用の列を挿入します(例では「チェック」列としています)。
    f:id:furyu-tei:20180301002831p:plain
    商品名などを確認しつつ、必要なものに印(○印など)をつけて仕分けていきます。
    同一の注文番号のものは、一番上の奴だけ印を付ければ大丈夫です。
    なお、作業用列は必須ではありません。例えば、支払い方法で絞り込みたい場合、「クレカ種類」列をオートフィルタの対象にすれば同様のことが可能です。

     

  4. 仕分け終わったら、Excelの機能でフィルタをかけます。
    f:id:furyu-tei:20180301002849p:plain

     

  5. 結果から、「注文番号」列の表示されているセルだけを選択します。
    表示されているものだけを選択するには(普通に範囲選択した状態で)「[Alt]+[;](セミコロン)」を押します(これはWindowsの場合です。Macの場合、「[shift] + [command] + [Z]」だそうです)。
    f:id:furyu-tei:20180301013017p:plain
    選択したら、コピー([Ctrl]+[C])します。

     

  6. 上でコピーした注文番号を、別のシートに貼り付けます([Ctrl]+[V])。
    f:id:furyu-tei:20180301002927p:plain
    その上で、TEXTJOIN関数を使って、各注文番号を" OR "でつなぎます。
    =TEXTJOIN( " OR ", TRUE, <注文番号の入ったセルの範囲> )
    なお、TEXTJOINはExcel2016からサポートされたワークシート関数だそうです
    Excel2013以前をご使用の場合、後で示すアドインを入れてみて下さい
    もしくは、別途テキストエディタ等に注文番号列をコピー&ペーストし、改行を" OR "に変換します。

     

  7. 得られた文字列(注文番号を" OR "でつなげたもの)を、注文履歴フィルタの「絞り込み」欄に貼り付け、[適用]ボタンを押します。
    f:id:furyu-tei:20180301013309p:plain
    必要な注文のみが抽出されるので、再度[領収書印刷用画面]を開き、印刷(PDF出力)を行います。

     

TEXTJOINなどのExcel2013以前ではサポートしていない関数を、疑似的に使えるようにするアドイン

上で述べたTEXTJOINは便利な関数なのですが、残念なことにExcel2016より前のバージョンでは含まれていません。
幸い、Excel2013以前でもTEXTJOIN等のワークシート関数を、ユーザー定義関数として使う方法を紹介してくださっている一連の記事がありました。
ありがとうございます!>はけた @さん
https://www.excelspeedup.com/category/kansuu/www.excelspeedup.com


これらをまとめて、アドイン(Excel2016Func.xlam)としてインストールできるようにしてみました。
以下からダウンロードできます。

Excel2016Funcのダウンロード

GitHub - furyutei/Excel2016Func: Excel2013以前で未サポートのワークシート関数の一部を疑似的に使用可能にするアドイン

インストール方法などは、こちらをご覧ください。
なお、Mac の場合には、インストール/アンインストール用のスクリプト(VBScript)は動作しないため、"Excel2016Func.xlam" を適当なディレクトリにコピーした上で、手動でインストールする必要があります。
support.office.com
を参考にしてください。
[ツール] メニューの [アドイン] を選択し、 [アドイン] ダイアログ ボックスの [参照] をクリックして、"Excel2016Func.xlam"をコピーした場所を探して指定し、[OK]を押します。
「☑Excel2016Func」にチェックがついていることを確認してください。

なお、作者はMacを持っていないため、詳細はわかりません。あしからずご了承ください。

参考にした記事など

artfulplace.hatenablog.com

https://www.excelspeedup.com/textjoin2/www.excelspeedup.com

fnya.cocolog-nifty.com

【アマゾン注文履歴フィルタ】キーワードによる絞り込み・返金情報CSVダウンロード機能などを追加しました

前回の記事後のアマゾン注文履歴フィルタ
furyu.hatenablog.com
への機能追加分をまとめます。
以下の機能説明は、2018/02/12時点(バージョン:0.1.0.1001)でのものです。




キーワードによる絞り込みができるようになりました

「絞り込み」フィルタを追加し、
f:id:furyu-tei:20180212195646p:plain
キーワードによる絞り込みが可能となりました。

f:id:furyu-tei:20180212195652p:plain
" "(スペース)区切りで AND 検索、" OR "区切りで OR 検索となります。

また、「☑ 除外」にチェックを付けると、
f:id:furyu-tei:20180212195700p:plain
キーワードで指定した以外のものが表示されます。

[クリア]ボタンは、キーワード入力をクリアするためのものです。

絞り込みの際の制限事項
  • 標準の [注文を検索] では
    「タイトル」「注文番号」「カテゴリー」「Eメールアドレス」「届け先」
    が対象ですが、アマゾン注文履歴フィルタでは
    「カテゴリー」「Eメールアドレス」
    については対象外となります。
    「届け先」は別途「お届け先」フィルタを組み合わせて指定してください。
  • 一件につき五品目以上を注文している場合には、五品目以降が検索にかかりません。
便利な使い方

より詳細に絞り込みが必要な方のために、ダウンロードしたCSVとExcelを用いる方法を記事にしました。
furyu.hatenablog.com


返金情報ファイルがダウンロードできるようになりました

領収書印刷用画面において、読み込み完了後、表示されている注文に対応した返金(払い戻し)がある場合には、右上に
f:id:furyu-tei:20180212194024p:plain
[返金情報CSV(参考用)ダウンロード]ボタンが表示されます。

これをクリックすると、返金情報が CSV 形式でダウンロードされ、Excel 等で開くことができます。
f:id:furyu-tei:20180212194035p:plain

その他

注文履歴 CSV ファイルに配送料、ポイント払い等の情報を追加・Amazonギフト券購入対応

配送料・手数料や、ポイント・ギフト券等による支払いの情報も、注文履歴 CSV ファイル中に含むようにしました。
また、Amazonギフト券購入情報が含まれていなかったので、これを追加しました

【アマゾン注文履歴フィルタ】注文履歴をCSVでダウンロードできるようになったり、いろいろ進化しました!

アマゾン注文履歴フィルタ
furyu.hatenablog.com

が思わぬ反響をいただいているようで、本人がいちばんびっくりしております。
ギフト券を送ってくださった方々、重ねてお礼申し上げます。

気をよくして(笑)、いくつかの機能追加等を行っております。いちど使っていただいた方も、新機能を試していただけると幸いです。
以下の機能説明は、2018/02/08時点(バージョン:0.1.0.601)でのものです。




注文履歴を CSV 形式でダウンロードできるようになりました

領収書印刷用画面で読み込みが完了すると、右上の方に[注文履歴CSV(参考用)ダウンロード]というボタンが表示されるようになります。
f:id:furyu-tei:20180208204609p:plain

これを押すと、
f:id:furyu-tei:20180208204626p:plain
現在開いている領収書の内容を元にしたデータが、CSV ファイルとしてダウンロードされます。

ダウンロードした CSV ファイルは Excel 等で開くことができますので、
f:id:furyu-tei:20180208204638p:plain
いろいろと使い道はあると思います。
CSV ファイルの文字コードは BOM付 UTF-8(改行コードはCR+LF)になっています。
ただ、Mac の Excel では開けない、というようなことを昔どこかで見た気がする……5年前(2013年)の記事か。今はどうなのかな?

なお、領収書印刷用画面に表示されるデータを適当に拾って並べただけですので、もともと表示されている以上のことはわかりません。
また、手抜きして領収書上には表示されているデータであっても CSV の中には含まれないもの(Amazonポイントとか送料・手数料とか)も存在しますので、悪しからず。
ボタンに「(参考用)」とあるのはそのためです。
Amazonポイントや送料・手数料等については、0.1.0.701以降反映するようになりました。
作りが甘いこともあって、間違っているところもあると思いますので、くれぐれもそのことを念頭に置いたうえで、ご利用ください。確定申告用等の重要な書類を作成される際には、必ず元データを確認するようにしてください。
結構ひどい古き良き時代を感じさせるHTMLだったため、スクレイピングには苦労しました……。

そうそう、「商品小計」「注文合計」「請求額」「クレカ請求額」の項目が、同一の注文(搬送)内では最初(一番上)の行にしか含まれていないのは、わざとです。
縦の合計を計算するときなどに重複してしまうのを避けるため。

「お届け先」フィルタを追加しました

注文を「お届け先」で絞り込み出来る機能を追加しました。
f:id:furyu-tei:20180208204700p:plain
経費とその他に分けたい時などにご利用ください。
この機能は、ぬん。さん(@)よりご要望いただいたものです。

領収書の宛名を指定できるようになりました

領収書印刷用画面で読み込みが終わったら、
f:id:furyu-tei:20180208204718p:plain
[宛名変更]ボタンが表示され、これを押すと、
f:id:furyu-tei:20180208204736p:plain
プロンプトが出て、宛名を入れることが出来るようになります。

f:id:furyu-tei:20180208204756p:plain
「___様」に重なるように指定した宛名が表示されます。

元は宛名欄が空白なので、手動で入れないといけないのですが、あまりこれに関する愚痴などは聞きませんね……確定申告用の領収書は宛名は別に必要ないのでしょうか。まあ、必要な人だけ使ってください、ということで。

Firefox 向けに、印刷プレビューボタンが付きました

Firefox アドオン版のみですが、領収書印刷用画面で、
f:id:furyu-tei:20180208204857p:plain
[印刷プレビュー]ボタンが表示されるようになりました。
これを押すと、
f:id:furyu-tei:20180208204821p:plain
すぐプレビューできるので、わざわざハンバーガーメニュー(≡)を開いて、印刷をクリックしなくてもよくなります。
こっそりショートカットキーがもともとあったりしたら笑えますが。

その他

安定性の向上

最初の方の版では、いつまで経っても領収書読み込みが完了しない、という現象が、状況によっては割と頻繁に発生していました。
特に、一度に処理する領収書数が多い方の場合。

ひとつの原因として、領収書の取得を行うには認証状態であることが条件なのですが、読み込み処理中に認証期限が切れてサインインを要求されて(ログインフォームが表示されて)しまい、バックグラウンドで読んでいるページが処理が続けられなくなる、というのがありました。
処理が止まるタイミングは前回のサインインをいつ行ったかに依存するため(期間もかなり短くしてある模様・15分くらい?)、なるべく認証期間を有効に使うために、開始直前にサインインを行うように修正しました。

デメリットとして、領収書印刷用画面を開く毎に必ずサインイン画面が表示されるため、少し煩わしくなってしまいましたが、あと少しのところで固まるよりはマシだと割り切ってくださるよう、お願いします。

領収書読み込み時のカウンタ追加

領収書読み込み中、画面右上に
f:id:furyu-tei:20180208214629p:plain
のようにカウンタが表示されるようになったので、進行状況がすぐわかります。
また、何らかの不具合で固まってしまっても、見ていれば止まっているのが分かるようになりました……(汗)。
一応、一定時間待っても変化が無ければ、ダイアログが表示されて中断できるようにはしています。

蛇足

これがきっかけでブログに訪れて下さった方、他には Twitter 用の拡張機能(本人は便利だと思っている)も公開しておりますので、そちらもよかったら合わせてご覧ください。
furyu.hatenablog.com