iPhoneのメッセージアプリで実際にやりとりした画面を、Webページで再現したい。スクリーンショット(キャプチャ画像)じゃなくて、HTMLとCSSで(JavaScriptも使います)。
ツールを用いて吸い出して、それをコピペしてWebページ上に再現する方法を解説します。
特別なツールを使わなくても、メッセージの内容をエディタで手打ちしてレイアウトするだけなら、別の記事でご紹介しました。
-
Webページで iPhoneのメッセージ画面を再現する
iPhoneのメッセージの画面をHTMLとCSSでブログ等のWebページに再現する方法。 画像として記事に表示させるんだったら、スクリーンショットを撮って配置すれば比較的簡単。下の画像が ...
続きを見る
内容があまり多くなければ上の記事の方法で問題ないかと思いますが、ツールを使えば実際にメッセージでやりとりした内容をそのままコピペして使えるのが便利です。
完成図
下の画像は、iPhoneのメッセージアプリで実際にやりとりした画面のスクリーンショットの一例です。
上のメッセージを吸い出したデータをもとにレイアウトしたのが下。
デフォルトでは、iPhone11Proの縦横比に合わせてあって、はみ出したメッセージはスクロールして表示できます。
モックアップ用のiPhone11Proのフレームを用意して配置すれば、かなりiPhone11Proの見た目に近いかと。
(スマホ、タブレットでは表示されないのでMac/PCでみてください。)
また、次のように上部と下部のインターフェースを省いて、高さを内容に合わせて成り行きで表示することもできます。
あるいは、任意の親ボックスに対して横幅100%で表示させることもできます。
これらを実現するソースコードと方法をご紹介します。
CMSにはWord Press、テキストエディタにはSublime Textを使用しています。
アプリケーションの入手
iPhone(およびiOSデバイス)内のコンテンツを管理・操作できるサードパーティー製Mac/PC用アプリケーションを使用します。
この手のアプリケーションはいくつかありますが、私が使った中で一番使い勝手が良かったのが「AnyTrans」というアプリケーションです。
下記のリンクから入手できます。
なお、この記事ではMacの環境で説明しています。Windowsもほぼ同様ですが、AnyTransについて不明な点は上記リンクの公式サイトでお確かめください。
メッセージをMac/PCにダウンロードする
AnyTrans for iOSのインストールが終わっているものとして、以下進めます。
iPhoneとMac/PCをケーブルで接続してAnyTransを起動。
「メッセージ」を選択します。
初めて使用するときや、最新のメッセージを読み込むときは、「増分バックアップを起動」ボタンをクリックします。
iTunesでバックアップを暗号化するオプションを選択している場合は、暗号化をオフにするようダイアログが出ます。その場合は...
iTunesを開いて、デバイスの概要-バックアップの「iPhoneのバックアップを暗号化」のチェックを外してオフにしてから再度操作します。
最新のメッセージの読み込みが終わったら、メッセージリストからダウンロードしたい会話にチェックを入れて「Macへ転送」ボタンをクリック...
「.htmlの形式にエクスポート」を選択します。
しばらく待って、「転送完了」と表示されたら、「ファイルの表示」ボタンをクリックしてみましょう。
ダウンロードされたデータがFinder(PCの場合はエクスプローラー)上で表示されます。
データは「AnyTrans-Export-(年)-(月)-(日)」という名称のフォルダに格納されます。
ちなみにMacでは、ダウンロードされたデータフォルダはデフォルトでログインユーザーの「書類」のルートに保存されます(環境設定で変更可能です)。
画像でHTMLファイルは「●●●●.html」という伏字にしていますが、この●●●●の部分は、iPhoneのメッセージリストのスレッド名=会話のタイトル(連絡先アプリに登録してある相手の名前か、アドレスあるいは電話番号)になります(下画像)。
「img」フォルダには、メッセージ画面のフキダシ背景のグラフィックスに使用する画像と、メッセージに添付した写真の画像ファイル等が格納されています。
ファイル「●●●●.html」をそのままブラウザで開いてみると下の画像のような感じです。
「●●●●.html」ファイルと「img」フォルダをサーバーの適当なところにアップすればそのまま公開することも可能です。
とはいえ、そのままだとたいていの場合かなりの分量になりますし、プライバシーの問題とか、いろいろ編集は必要になることの方が多いでしょう。
次にHTMLファイルの中身を調べて、編集する方法について解説します。
HTMLコードの編集
データの整形
ダウンロードされたHTMLファイル「●●●●.html」をテキストエディタで開いてみると、ファイル圧縮(Minify)されているので編集はおろか判読も困難(下画像)。
使用しているテキストエディタがSublime Text なら、ソースコードを自動で整形してくれるプラグイン:「HTML/CSS/JS Prettify」があるのでインストールして使いましょう。
インストールしてあれば[Tools」メニュー[HTML/CSS/JS Prettify]-[Prettify Code]で...
一瞬で、綺麗にインデントして整形してくれます。
HTMLファイルの構造
編集の際の手がかりになるように、HTMLファイルの基本的な構造がどうなっているのか、サンプルのコードを下に載せましたので参考にしてください。
なお実際は、head
要素内にスタイルシートが記述されていますがここでは省略しています。
また、body
要素の開始タグ<body>
が抜けているんですが下のコードでは補ってあります。
iMessageの場合とSMS/MMSの場合と(→iMessageとSMS/MMSについて:Appleサポート)でHTMLファイルの構造が違っていて、まず「iMessage」の場合。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>タイトル</title> <!-- ここにスタイルシート --> </head> <body> <div class="wrap"> <div class="top">タイトル</div> <div class="cont"> <h1>スレッド名(相手の名前)</h1> <p class="imessage">iMessage</p> <div class="cont_block"> <p class="date">日時</p> <div class="block_table"> <table class="left" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top2"></td> <td width="auto" class="bg_color2" height="12"></td> <td class="right_top2"></td> </tr> <tr> <td height="auto" class="right_mid2"></td> <td class="bg_color2">相手側のメッセージ </td> <td class="bg_color2" width="14"></td> </tr> <tr> <td class="left_bottom2"></td> <td class="bg_color2"></td> <td class="right_bottom2"></td> </tr> </table> </div> <!-- /.block_table --> </div> <!-- /.cont_block --> <div class="cont_block"> <p class="date">日時</p> <div class="block_table"> <table class="right" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top"></td> <td width="auto" class="bg_color" height="12"></td> <td class="right_top"></td> </tr> <tr> <td height="auto" class="bg_color" width="14"> </td> <td class="bg_color">自分側のメッセージ(iMessage)</td> <td class="right_mid"></td> </tr> <tr> <td class="left_bottom"></td> <td class="bg_color"></td> <td class="right_bottom"></td> </tr> </table> </div> <!-- /.block_table --> </div> <!-- /.cont_block --> </div> <!-- /.cont --> </div> <!-- /.wrap --> </body> </html>
14行目から37行目までと、39行目から61行目までの <div class="cont_block">...</div>
のブロックが相手側、自分側それぞれのメッセージ部分に当たります。
<div class="cont_block">...</div>
内の <div class="block_table">...</div>
の中にある3行3列のtable
要素がフキダシ部分です。
レガシーなテーブルレイアウトなのが残念なところですが、そのtable
要素でメッセージのフキダシの見た目を作っています。
クラス名がright
のtable
要素が自分の側のメッセージで右揃え、クラス名がleft
のtable
要素が相手の側のメッセージで左揃えのフキダシになります。
2行目2列目のtd要素がメッセージ内容のテキストを含む部分です。メッセージの内容を編集したいときはここ。
つまり、メッセージを丸ごと削除したり、移動したりしたいときは、<div class="cont_block">...</div>
のブロックを選択すればOK。
次に「SMS/MMS」の場合。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>タイトル</title> <!-- ここにスタイルシート --> </head> <body> <div class="wrap"> <div class="top">タイトル</div> <div class="cont"> <h1>スレッド名(相手の名前)</h1> <p class="imessage">SMS</p> <p class="date">日時</p> <div class="block_table"> <div class="block_table"> <table class="left" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top2"></td> <td width="auto" class="bg_color2" height="12"></td> <td class="right_top2"></td> </tr> <tr> <td height="auto" class="right_mid2"></td> <td class="bg_color2">相手側のメッセージ </td> <td class="bg_color2" width="14"></td> </tr> <tr> <td class="left_bottom2"></td> <td class="bg_color2"></td> <td class="right_bottom2"></td> </tr> </table> </div> <!-- /.block_table --> </div> <!-- /.block_table --> <p class="date">日時</p> <div class="cont_block"> <div class="block_table"> <table class="right" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top3"></td> <td width="auto" class="bg_color3" height="12"></td> <td class="right_top3"></td> </tr> <tr> <td height="auto" class="bg_color3" width="14"> </td> <td class="bg_color3">自分側のメッセージ(SMS/MMS)</td> <td class="right_mid3"></td> </tr> <tr> <td class="left_bottom3"></td> <td class="bg_color3"></td> <td class="right_bottom3"></td> </tr> </table> </div> <!-- /.block_table --> </div> <!-- /.cont_block --> </div> <!-- /.cont --> </div> <!-- /.wrap --> </body> </html>
「iMessage」 の場合との大きな違いは、日時を表示する<p class="date">...</p>
のブロックです。
上で説明した「iMessage」の場合では、<p class="date">...</p>
は <div class="cont_block">...</div>
の内部にあったのに、この「SMS/MMS」の場合は、外にあります(14行目39行目)。
もう一つの大きな違いは、相手の方のメッセージ - つまり、クラス名がleft
のtable
要素の方は<div class="cont_block">...</div>
で包含されておらず、<div class="block_table">...</div>
でネストされているということです(16行目)。クラス名がright
の方はiMessageと同様<div class="cont_block">...</div>
で包含されています。
どういう理由でこうなっているのかわかりませんが、こういう仕様のようです。
ということで、メッセージを丸ごと削除したり、移動したりしたいときは、<p class="date">...</p>
と次のdiv
要素(<div class="cont_block">...</div>
または<div class="block_table">...</div>
)を選択すれば良いということです。
メッセージの編集
上記を踏まえれば、「●●●●.html」をブラウザで開いて確認しながら容易に編集できると思います。
そのあと、次でご紹介するテンプレートを利用すれば、冒頭のようにiPhoneのメッセージ画面を再現することができます。
気をつける点をいくつか。
画像は、リンク先が新規ウインドウでメディアファイルへのa
要素で包含されていますが、これは必要なければ外しても問題ありません。
画像が添付されてる場合、「●●●●.html」ではフキダシの中に余白付きで表示されますが、テンプレートを使えば、そのままのコードでフキダシの形にトリミングされた状態で表示されます。
添付画像と同時にテキストがある場合は、画像のフキダシとテキストのフキダシが接した状態で表示されます。
また、iPhone上で改行をいれたメッセージの場合、ソースコード上では次のようになっていて...
「●●●●.html」では次のように改行なしで表示されますが...
テンプレートを使えば、改行付きで表示されますので、br
要素を追加する必要はありません。
それから、iPhoneのメッセージアプリで見たときと違って、「●●●●.html」では、それぞれのメッセージごとに日時情報が出力されてしまっているのですが、適宜、削除してしまいましょう。<p class="date">...</p>
の要素です。
次に、iPhoneでの見た目を実現するテンプレートおよびデータを解説します。
テンプレートおよびその他データ
全部まとめてアーカイブしておきましたので、よろしかったらダウンロードしてお使いください。あるいは、このあとコードおよび画像データを載せておくのでそこからコピペしてもらっても構いません。
ダウンロードデータ
- HTMLファイル「template.html」
- CSSファイル「message.css」
- JavaScriptファイル「jquery.remold.js」
- フォルダ「images」
「template.html」は、iPhoneメッセージ画面の上部と下部のインターフェースを追加したテンプレートファイルです。サンプルのメッセージが配置してありますが、上記で編集したメッセージと置き換えて使用します。
ブラウザでの表示は次のようになります。
ソースコードは下記、長くなるので必要な方のみ「ソースを表示」ボタンをクリックして展開してださい。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="message.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script type="text/javascript" src="jquery.remold.js"></script> </head> <body> <div class="message"><!-- ここからコピー --> <div class="frame"><!-- iPhoneを再現しないとき削除1/2ここから --> <div class="header"><!-- 高さ成り行きにするとき削除1/2ここから --> <div class="top"> <div class="current_time">00:00</div> </div><!-- /.top --> <div class="account"> <div class="name">スレッド名(相手の名前)</div> </div><!-- /.account --> </div><!-- /.header --><!-- 高さ成り行きにするとき削除1/2・iPhoneを再現しないとき削除1/2ここまで --> <div class="cont"><!-- div要素class="cont"を置き換え_ここから --> <!-- iMessage自分側テキストのみ --> <p class="imessage">iMessage</p> <div class="cont_block"> <p class="date">月曜日,1月 13,2020,07:20</p> <div class="block_table"> <table class="right" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top"></td> <td width="auto" class="bg_color" height="12"></td> <td class="right_top"></td> </tr> <tr> <td height="auto" class="bg_color" width="14"> </td> <td class="bg_color">自分側メッセージiMessage</td> <td class="right_mid"></td> </tr> <tr> <td class="left_bottom"></td> <td class="bg_color"></td> <td class="right_bottom"></td> </tr> </table> </div> </div> <!-- iMessage相手側テキストのみ --> <div class="cont_block"> <p class="date">月曜日,1月 13,2020,07:30</p> <div class="block_table"> <table class="left" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top2"></td> <td width="auto" class="bg_color2" height="12"></td> <td class="right_top2"></td> </tr> <tr> <td height="auto" class="right_mid2"></td> <td class="bg_color2">相手側のメッセージiMessage</td> <td class="bg_color2" width="14"></td> </tr> <tr> <td class="left_bottom2"></td> <td class="bg_color2"></td> <td class="right_bottom2"></td> </tr> </table> </div> </div> <!-- iMessage自分側画像1枚 --> <div class="cont_block"> <p class="date">月曜日,1月 13,2020,07:40</p> <div class="block_table"> <table class="right" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top"></td> <td width="auto" class="bg_color" height="12"></td> <td class="right_top"></td> </tr> <tr> <td height="auto" class="bg_color" width="14"> </td> <td class="bg_color"><br /><a href="images/sample.jpg" target="_blank"><img src="images/sample.jpg" /></a><br /><br /></td> <td class="right_mid"></td> </tr> <tr> <td class="left_bottom"></td> <td class="bg_color"></td> <td class="right_bottom"></td> </tr> </table> </div> </div> <!-- SMS自分側テキストのみ --> <p class="imessage">SMS</p> <p class="date">月曜日,1月 13,2020,07:50</p> <div class="cont_block"> <div class="block_table"> <table class="right" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top3"></td> <td width="auto" class="bg_color3" height="12"></td> <td class="right_top3"></td> </tr> <tr> <td height="auto" class="bg_color3" width="14"> </td> <td class="bg_color3">SMSの自分側メッセージ</td> <td class="right_mid3"></td> </tr> <tr> <td class="left_bottom3"></td> <td class="bg_color3"></td> <td class="right_bottom3"></td> </tr> </table> </div> </div> <!-- SMS相手側画像1枚テキストつき --> <p class="date">月曜日,1月 13,2020,08:10</p> <div class="block_table"> <div class="block_table"> <table class="left" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top2"></td> <td width="auto" class="bg_color2" height="12"></td> <td class="right_top2"></td> </tr> <tr> <td height="auto" class="right_mid2"></td> <td class="bg_color2"><br /><a href="images/sample.jpg" target="_blank"><img src="images/sample.jpg" /></a><br />画像と同時にテキストメッセージ<br /></td> <td class="bg_color2" width="14"></td> </tr> <tr> <td class="left_bottom2"></td> <td class="bg_color2"></td> <td class="right_bottom2"></td> </tr> </table> </div> </div> <!-- SMS自分側複数の画像 --> <p class="date">月曜日,1月 13,2020,08:20</p> <div class="cont_block"> <div class="block_table"> <table class="right" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top3"></td> <td width="auto" class="bg_color3" height="12"></td> <td class="right_top3"></td> </tr> <tr> <td height="auto" class="bg_color3" width="14"> </td> <td class="bg_color3"><br /> <a href="images/sample.jpg" target="_blank"> <img src="images/sample.jpg" /> </a><br /><br /> <a href="images/sample.jpg" target="_blank"> <img src="images/sample.jpg" /> </a><br /><br /> <a href="images/sample.jpg" target="_blank"> <img src="images/sample.jpg" /> </a><br /><br /> </td> <td class="right_mid3"></td> </tr> <tr> <td class="left_bottom3"></td> <td class="bg_color3"></td> <td class="right_bottom3"></td> </tr> </table> </div> </div> <!-- SMS相手側複数の画像とテキスト --> <p class="date">月曜日,1月 13,2020,08:30</p> <div class="block_table"> <div class="block_table"> <table class="left" width="auto" height="auto" border="0" cellpadding="0" cellspacing="0"> <tr> <td class="left_top2"></td> <td width="auto" class="bg_color2" height="12"></td> <td class="right_top2"></td> </tr> <tr> <td height="auto" class="right_mid2"></td> <td class="bg_color2"><br /><a href="images/sample.jpg" target="_blank"><img src="images/sample.jpg" /></a><br /><br /><a href="images/sample.jpg" target="_blank"><img src="images/sample.jpg" /></a>複数の画像とテキストを同時にメッセージした場合<br /></td> <td class="bg_color2" width="14"></td> </tr> <tr> <td class="left_bottom2"></td> <td class="bg_color2"></td> <td class="right_bottom2"></td> </tr> </table> </div> </div> </div><!-- /.cont --><!-- div要素class="cont"を置き換え_ここまで --> <div class="footer"><!-- iPhoneを再現しないとき削除2/2ここから・高さ成り行きにするとき削除2/2ここから --> <!-- no-contents --> </div><!-- /.footer --><!-- 高さ成り行きにするとき削除2/2ここまで --> </div><!-- /.frame --><!-- iPhoneを再現しないとき削除2/2ここまで --> </div><!-- /.message --><!-- ここまでコピー --> </body> </html>
「message.css」は説明するまでもなくスタイルシート。下記、長くなるので必要な方のみ「ソースを表示」ボタンをクリックして展開してださい。
@charset "UTF-8"; /* ================================ AnyTransVersion iPhoneMessageStyle Author URI: https://jisuijisan.com; Version: 20221109 ================================== */ /*-------------------- 初期化と基本設定 ---------------------*/ .message * { margin: 0; padding: 0; line-height: 1.4!important; font-family: "ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic Pro","Helvetica Neue", "Lucida Sans Unicode", "Arial"; font-weight: normal; color: #333; } .message img { display: block; width: 100%; height: auto; border: none; } /*iPhone幅のフレーム(高さ成り行き)*/ .message .frame { position: relative; width: 325px; height: auto; overflow: hidden; margin: 0 auto; border: solid #ddd 1px; } /*ヘッダーとフッター*/ .message .frame .header, .message .frame .footer { position: absolute; width: 100%; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); z-index: 100; } /*===================================== 各エリア設定 ======================================*/ /*------------------------------- ヘッダー --------------------------------*/ /*ヘッダーの基本設定*/ .message .frame .header { height: 101px; left: 0; top: 0; border-bottom: 1px #b9b9b9 solid; background: rgba(247,247,247,0.9); text-align: center; } /*Firefox*/ @-moz-document url-prefix() { .message .frame .header { background: rgba(247,247,247,0.95); }} /*戻るボタン*/ .message .frame .header::before { position: absolute; content: ""; width: 14px; height: 14px; left: 13px; top: 49px; border: none; background: none; box-shadow: 3px 3px 0 0 #2793fa inset; transform: rotate(-45deg); } /*ヘッダーイメージ*/ .message .frame .top { height: 42px; background: url(images/header.png); } /*ヘッダー時刻表示*/ .message .frame .current_time { position: absolute; top: 11px; left: 17px; line-height: 15px; font-family: "Helvetica Neue"; font-size: 14px !important; } /*Firefox*/ @-moz-document url-prefix() { .message .frame .current_time { left: 13px; font-size: 14px !important; }} /*Chrome*/ _:lang(x)::-internal-media-controls-overlay-cast-button, .message .frame .current_time { left: 13px; font-size: 14px !important; } /*ヘッダー:相手のアイコン*/ .message .frame .account { height: 59px; padding: 34px 0 0 6px; background: url(images/avatar.png) center 0 no-repeat; } /*ヘッダー:スレッド名(相手の名前)*/ .message .frame .name { display: inline-block; line-height: 10px !important; font-size: 10px !important; } /*次へボタン*/ .message .frame .name::after { display: inline-block; content: ""; width: 6px; height: 6px; margin-bottom: 1px; border: none; background: none; box-shadow: -2px 2px 0 0 #999 inset; transform: rotate(45deg); } /*--------------------------------- フッター ----------------------------------*/ .message .frame .footer { height: 108px; left: 0; bottom: 0; background: rgba(255,255,255,0.75) url(images/footer.png) no-repeat; } /*Firefox*/ @-moz-document url-prefix() { .message .frame .footer { background: rgba(255,255,255,0.9) url(images/footer.png) no-repeat; }} /*---------------------------------- メッセージボディ -----------------------------------*/ .message .cont { padding: 10px 0 10px;/*iPhone再現サイズ以外*/ background: #fff; z-index: 1; } /*iPhone再現サイズ(.headerがあるとき)*/ .message .frame .header ~ .cont { width: 340px;/*スクロールバーをはみ出させて隠す*/ height: 483px; padding-top: 101px; padding-bottom: 120px; overflow-x: hidden; overflow-y: scroll; } /* Edge */ @supports (-ms-ime-align: auto) { .message .frame .header ~ .cont > div:last-of-type { margin-bottom: 120px; }} /*Firefox */ @-moz-document url-prefix() { .message .frame .header ~ .cont > div:last-of-type { margin-bottom: 120px; }} /*スマホ、タブレット.細いスクロールバーに対応*/ @media only screen and (max-width: 1112px) { .message .frame .header ~ .cont { width: 330px; }} /*====================================== メッセージボディ内パーツ =======================================*/ /*メッセージの日時*/ .message .date, .message .imessage { margin: 2em 14px 0.8em; text-align: center; font-family: "ヒラギノ角ゴ Pro W6"; font-size: 11px!important; color: #aaa; } .message .imessage { margin-bottom: -2em; } /*------------------------- フキダシ --------------------------*/ .message .block_table table { position: relative; width: 100%; margin: 0; border: none; } .message table tr td { position: relative; clear: both; border-style: none; overflow-x: visible; overflow-wrap: break-word; font-size: 14px; color: white; } .message .block_table td .wrap_img { display: block; position: relative; width: 100%; } /*フキダシの左右揃え*/ .message .right td { float: right; } .message .left td { float: left; } /*フキダシにしない行*/ .message .block_table tr:first-of-type, .message .block_table tr:last-of-type { display: none; } /*フキダシにしないセル*/ .message .block_table tr td:first-of-type, .message .block_table tr td:last-of-type { display: none; } /*フキダシとして表示するセル*/ .message .block_table td:not(:first-of-type):not(:last-of-type) { display: block; } /*テキストフキダシ*/ .message .block_table tr td.only-txt { max-width: 192px; box-sizing: content-box; margin: 1px 14px 6px; padding: 9px 14px; border-radius: 15px; text-align: left; } /*テキストフキダシの背景色_iMessage*/ .message .block_table tr td.only-txt.bg_color { background: #2793fa; } /*テキストフキダシの背景色_相手側*/ .message .block_table tr td.only-txt.bg_color2 { background: #e9e9ed; color: black; } /*テキストフキダシの背景色_SMS/MMS*/ .message .block_table tr td.only-txt.bg_color3 { background: #32cd54; } /*画像フキダシ_共通*/ .message .block_table tr td:not(.only-txt) { width: 216px; margin: 1px 9px 6px; padding: 0; overflow: hidden; } /*画像(テキスト同時)*/ .message .block_table tr td.wt-img { margin: 1px 9px 0px; } /*画像フキダシに出力されたbrを非表示*/ .message .block_table tr td:not(.only-txt) br { display: none; } /*============================== フキダシのしっぽ ===============================*/ /*テキスト・画像共通*/ .message .block_table td::after, .message .block_table td::before, .message .block_table td .wrap_img::after, .message .block_table td .wrap_img::before { position: absolute; border: none; background: none; z-index: 10; } /*テキストしっぽ_共通*/ .message .block_table td.only-txt::after { content: ""; width: 15px; height: 17px; bottom: 0; } /*テキストしっぽ_iMessage*/ .message .block_table td.bg_color.only-txt::after { right: -5px; border-radius: 0 0 0 15px/0 0 0 11px; box-shadow: 13px 2px 0 -3px #2793fa inset; } /*テキストしっぽ_相手側*/ .message .block_table td.bg_color2.only-txt::after { left: -5px; border-radius: 0px 0 15px 0px/ 0px 0 11px 0; box-shadow: -13px 2px 0 -3px #e9e9ed inset; } /*テキストしっぽ_SMS/MMS*/ .message .block_table td.bg_color3.only-txt::after { right: -5px; border-radius: 0 0 0 15px/0 0 0 11px; box-shadow: 13px 2px 0 -3px #32cd54 inset; } /*画像(単独)しっぽ_共通*/ .message .block_table td.only-img::after { content: url(images/img_tail.svg); width: 23px; height: 13px; bottom: -1px; } /*画像(単独)しっぽ_相手側*/ .message .block_table .left td.only-img::after { left: -1px; } /*画像(単独)しっぽ_自分側*/ .message .block_table .right td.only-img::after { right: -1px; transform: scale(-1, 1); } /*画像しっぽ上側辺マスク_共通*/ .message .block_table td.wt-img::before, .message .block_table td.only-img::before { content: ""; width: 6px; height: 3000px; bottom: 8px; background: #fff; overflow-y: hidden; } /*画像しっぽ上側辺マスク_相手側*/ .message .block_table .left td:not(.only-txt)::before { left: 0px; } /*画像しっぽ上側辺マスク_自分側*/ .message .block_table .right td:not(.only-txt)::before { right: 0px; } /*画像上左右の角丸_共通*/ .message .block_table td *:first-child .wrap_img::before, .message .block_table td > .wrap_img:first-child::before { content: ""; width: 210px; height: 16px; top: 0px; border-radius: 15px 15px 0 0; box-shadow: 0 -6px 0 5px #fff; } /*画像上左右の角丸_相手側*/ .message .block_table .left td .wrap_img::before { left: 6px; } /*画像上左右の角丸_自分側*/ .message .block_table .right td .wrap_img::before { right: 6px; } /*角丸(しっぽなし・内側下角)_共通*/ .message .block_table td *:last-child .wrap_img::after, .message .block_table td > .wrap_img:last-child::after, .message .block_table td.wt-img::after { content: ""; bottom: 0; width: 16px; height: 16px; } /*画像内側下角_相手側(右下)*/ .message .block_table .left td .wrap_img::after { right: 0; border-radius: 0 0 15px 0; box-shadow: 4px 4px 0 3px #fff; } /*画像内側下角_自分側(左下)*/ .message .block_table .right td .wrap_img::after { left: 0; border-radius: 0 0 0 15px; box-shadow: -4px 4px 0 3px #fff; } /*画像(テキスト同時)しっぽなし_相手側*/ .message .block_table .left td.wt-img::after { left: 6px; border-radius: 0 0 0 15px; box-shadow: -5px 5px 0 4px #fff; } /*画像(テキスト同時)しっぽなし_自分側*/ .message .block_table .right td.wt-img::after { right: 6px; border-radius: 0 0 15px 0; box-shadow: 5px 5px 0 4px #fff; } /*連投した画像区切り*/ .message .block_table td *:not(:first-child) .wrap_img img, .message .block_table td > .wrap_img:not(:first-child) img { border-top: #fff 1px solid; }
「jquery.remold.js」はJavaScriptのスクリプトです。なんのためのスクリプトかというと、「●●●●.html」では、テーブルレイアウトでフキダシを作ってるんですが、それをCSS3を使ったレイアウトにするために、これで強引に要素の置き換えをしています。
また、WordPressが自動整形で出力するp
要素やbr
要素の除去も行なっています。
/* |* jQuery script |* https://jisuijisan.com |* Version: 2022.11.10 */ jQuery(function($){ $('.message td img').wrap('<span class="wrap_img"></span>');//画像を包含してクラス付与 $('.message br').remove();//brを削除 $('.message td p > *').unwrap();//自動整形で出力されるpを除去 $('.message > p, .message .frame > p, .message .header p, .message .cont p:empty, .message .footer p').remove();//自動整形で出力されるp要素を削除 $('.message td:has(img)').each(function(){//画像のあるセル $(this).children().wrapAll('<span class="unwrap_later">');//このセルの要素をまとめて包含 if($(this).text().match(/\S/g)){//このセルに文字があれば $(this).before('<td class="wt-img"></td>').children().appendTo($(this).prev('td'));//クラス付新要素をこの要素の上に作りこのセルの要素をそこへ移動 } else { $(this).addClass('only-img');//このセルに文字がなければこのセルにクラスを付与 } }); $('.message td:has(img) .unwrap_later > *').unwrap();//まとめて包含した要素を除去 $('.message td:not(:has(img))').each(function(){//画像のないセル if($(this).text().match(/\S/g)){//このセルに文字があれば var str = $(this).text(); $(this).html(str.replace(/\n/g,'<br>')).addClass('only-txt');//改行文字をbrに置き換えてセルにクラスを付与 } }); $('.only-txt br:first-child').remove();//画像を移動後自動生成された改行文字が変換された要素先頭のbrを削除 });
「images」フォルダには、iPhoneメッセージ画面の上部と下部のインターフェースに必要な画像ファイルと、フキダシの形のグラフィックスに必要な画像ファイルが入ってます。
「images」フォルダの画像ファイル
avatar.png img_tail.svg
header.png
footer.png
sample.jpg
以上の「template.html」、「message.css」、「jquery.remold.js」、「images」フォルダを、AnyTransでダウンロードしてあった「●●●●.html」、「img」フォルダと同じディレクトリに配置します。
最終的には、私の場合、サーバーのルートに作成した「upload」フォルダ内の「anytrans」フォルダにアップロードするので、ローカルの同フォルダに配置するものとします(アップロードはまだしませんよ)。
あとで、画像ファイルのリンクを書き換えるので、サーバーのどこにアップロードするかはこの時点で決めておきましょう。
メッセージを置き換える
編集が済んだメッセージを、「template.html」と組み合わせます。
編集が済んだHTMLファイル「●●●●.html」のソースコードのなかの、<div class="cont">...</div>
を「template.html」の21行目から195行目までの<div class="cont">...</div><!-- /.cont -->
と置き換えます。
<h1>...</h1>
は不要なので削除してください。
画面左上の時刻表記を編集するときは15行目の<p class="current_time">...</p>
を編集。
<div class="top"> <div class="current_time">00:00</div> </div><!-- /.top -->
スレッド名(相手の名前)を編集するときは18行目の<p class="name">...</p>
を編集してください。
<div class="account"> <div class="name">スレッド名(相手の名前)</div> </div><!-- /.account -->
ここまで置き換えたら「template.html」をブラウザで開いて、表示を確認してみましょう。
リンクの修正
この後のコードの貼り付け・データのアップロードの前に、添付ファイルへのリンクを修正します。画像添付がない場合は必要ありません。
ここでは「img」フォルダを、サイトルート直下の 「upload」-「anytrans」にアップロードすることにしているので、これに合わせてHTMLファイル内のパスを変更します。
エディタの検索-置換で...
<a href="img/
を <a href="/upload/anytrans/img/
に、
<img src="img/
を <img src="/upload/anytrans/img/
に置換しました。
高さ成り行きの場合など
上部と下部のインターフェースを省いて、高さを成り行きで表示する場合は、<div class="header">
(13行目)から</div><!-- /.header -->
(20行目)と<div class="footer">
(置き換え前の186行目)から</div><!-- /.footer -->
(置き換え前の188行目)を削除します。
任意の親ボックスに対して横幅100%で表示させる場合は、<div class="frame">
(12行目)から</div><!-- /.header -->
(20行目)と<div class="footer">
(置き換え前の186行目)から</div><!-- /.frame -->
(置き換え前の189行目)を削除します。
公開する
コードを貼る
編集が完了したら、ブログサービス等の投稿の編集画面で<div class=“message”> ~ </div><!-- /.message -->
の部分をコピーして貼り付けます。
WordPressでは「テキスト」タブで貼り付けて下さい。「テキスト」タブは他のCMS等では「HTML」だったりしますね。
併せてアップロードするCSSファイルとJavaScriptファイルへのリンク要素を記述します。
ここでは上述の通り、サーバーのルートに作成した「upload」フォルダ内の「anytrans」フォルダにアップロードすることにしているのでパスを下記の赤線部のように変更しました。
<link rel="stylesheet" href="/upload/anytrans/message.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script type="text/javascript" src="/upload/anytrans/jquery.remold.js"></script>
となりますね。
既にjQueryを利用している場合は、2行目は必要ありません。
ただ、気をつけるのは、WordPressの場合「テキスト」タブと「ビジュアル」タブを行き来すると、このリンク要素が消えてしまったりするということ。😭
「テキスト」タブでのみで編集するか、それがいやならテーマファイルのhead要素内に記述しましょう。
あるいは、使用しているテーマによっては、記事ごとにhead要素内を編集できる機能があるかもしれません。
私が利用しているテーマ「WING(AFFINGER5)」の場合は下図のように「投稿の編集」画面で、headに出力するコードを設定できるのでそこに記述しました。
スタイルシートは全部をコピペして既存のCSSの一番最後に貼り付けるかインポート(@import)する方法もありますが、その際はスタイルシート内で利用する画像データの url を修正してください。
データのアップロード
アップロードするデータを確認します。
「img」フォルダのファイルのうち、使用する添付写真以外は必要ないので削除しましょう。
「●●●●.html」と「template.html」はもう必要ないので、それ以外をアップロードします。
WordPress の場合、ここまでやったらプレビューなり、非公開にして更新なりして表示を確認してみましょう。
表示がおかしい場合は、以下の点を確認して見てください。
- スタイルシートが既存のスタイルシートと競合している。
→セレクタの詳細度をあげることを検討してみてください。
(参考→詳細度[MDN web docs]) - CMS(WordPress等)の仕様で意図しないスペースや改行がp要素やbr要素等に出力されている。
→不要なスペースや改行を削除。コメントも削除したほうがいいかも。
WordPressでは自動整形機能の働きで、テキストタブとビジュアルタブを行き来すると、ソースコードの改行が増えたりスペースが減ったりすることがあるので、それが原因となっていることがあるかもしれません。確認してみてください。
表示が正常なことを確認できたら投稿を公開しましょう。
以上で完成です。
どなたかのお役に立てば。