ホームページ > 記事 > ウェブフロントエンド > スタートアップ向けのモバイル Web エクスペリエンスの強化
このチュートリアルは、Envato Tuts の「Build Your Startup with PHP」シリーズの一部です。このシリーズでは、私のミーティング プランナー アプリを実際の例として使用して、スタートアップの立ち上げをコンセプトから現実に至るまでガイドします。あらゆる段階で、Meeting Planner コードをオープンソースのサンプルとしてリリースし、そこから学ぶことができます。また、スタートアップ関連で発生するビジネス上の問題にも対処します。
戦略的には、iOS と Android で Meeting Planner 用のモバイル アプリを構築するのは理にかなっていますが、財務上の観点からは、そのためのリソースをまだ調達していません。マシュー・イングラムは最近フォーチュン誌に、モバイル ユーザーをターゲットにした製品が非常に多いため、「少なくとも統計的に言えば、あなたのアプリをダウンロードする人は誰もいないでしょう」と書いています。リソースを考えると、それを採用する可能性はすぐには意味がありませんでした。
ただし、Meeting Planner がモバイル デバイス上で優れた Web エクスペリエンスを提供することが重要です。
今日のショーでは、これを行うために行った変更を確認し、説明します。つまり、基本的に Web アプリケーションを、モバイル デバイスやタブレットで簡単に使用できる応答性の高い Web サイトに近づけることです。結果を(携帯電話またはタブレットで)確認してください。
今日のエピソードのコーディング上の課題の 1 つは、私がデザイナーでも CSS コーダーでもないことです。時々、自分でコーディングする必要すらないと感じることがあります。マイクロソフトでは、私はチーム プロジェクト マネージャーを務めています。つまり、グラフィック デザイナーがおり、スタッフが常駐するユーザビリティ ラボがあり、CSS は存在しません。
この仕事を始める前は、メディア クエリ、ブレークポイント、特殊な CSS を学習することに怖気づいていました。これは私の得意分野ではなく、非常に時間がかかり、詳細を重視するものです。ただし、48 時間以内にすべてが迅速かつ完璧に完了しました。ストーリーの最後まで参照すると、すべての変更に必要な CSS 行は最終的にわずかであることがわかります。突然、携帯電話で Meeting Planner を閲覧し始めたとき、新しい応答性の高い Web エクスペリエンスがどれほどうまく機能するかに本当に興奮しました。
率直に言って、現時点では専用のモバイルアプリは必要ないと思います。現在、特に今後の重要なアルファおよびベータ段階では、モバイル Web エクスペリエンスを通じて視聴者を引き付けることができます。
一方、Meeting Planner をまだ試していない場合は、携帯電話またはタブレットから最初の会議をスケジュールしてください。私は以下のコメント スレッドに参加していますので、あなたの経験について教えてください。 Twitter @reifman でもご連絡いただけます。私は常に新しい機能のリクエストや推奨されるチュートリアル トピックに興味を持っています。
注意事項として、Meeting Planner のコードはすべて PHP の Yii2 フレームワークを使用して書かれています。 Yii2 についてさらに詳しく知りたい場合は、並行シリーズ「Yii2 によるプログラミング」を参照してください。
まず、iOS スマートフォンを使用して Meeting Planner サービスの現在のステータスを参照し、初期アプリケーションのスクリーンショットを撮りました。ひどくはありませんが、素晴らしいものでもありません。私が見つけたものを見直してみましょう。
ホームページは見栄えがしますが、美的には「スケジュールを簡単にする」というタイトルのテキストが少し異なる、つまりほぼ同じ長さの 3 行であることが望ましいと思います。ただし、Bootstrap はドロップダウン メニューを適切に管理し、ページの残りの部分は正常に動作します。
登録ページ企画会議
トピックに関する新しい会議出席依頼など、他のページは正常に動作しています。ただし、モバイル ユーザーは、会議を紹介する長いメッセージを入力するためのテキスト エリア フィールドを提供したくない場合があります:
私たちが使用しているブートストラップ拡張機能では、アクターの追加も少し機能しなくなります:
場所と時間の計画ビューがクラッシュし始めます。同様に、デスクトップのデザインでは、モバイル デバイス向けに詳細とオプションが多すぎます:
############その他の地域###
「場所」ページは正常に機能しますが、ボタンのレイアウトを改善する必要があります。おそらくモバイル ユーザーにはこの機能は必要ありません。
同様に、モバイル デバイスでもデスクトップのタブと写真のレイアウトに問題があります。まだ再考する必要があります:
開発ソリューション
もちろん、Web サイトには改善の余地がたくさんあります。モバイルデバイス向けに再検討する必要がある領域もあれば、最小限に抑える必要がある領域もあれば、見た目の調整が必要な領域もあります。仕事に取り掛かりましょう。
さまざまな方法リーリー
冗談は頭の中の氷を解くのに役立ちます。 Envato の編集の神様はいつでも私を見てくれています。
簡素化された機能、特に会議計画プロセス
モバイルデバイスに表示する重要な情報を決定する
メディアからの問い合わせウォームアップ
###ドロップダウンメニュー###
CSS を詳しく調べることへの躊躇を克服するのに、少し努力が必要でした。準備を整えるために、ドロップダウン メニューを最小化し、モバイル機能の範囲を簡素化することに取り組み始めました。今のところ、小型デバイス用の基本的なメディア クエリを作成し、Web サイト全体で使用することにしました。これはfrontend/site.cssです:
menuhide
のような CSS プロパティを追加するだけです。これは、/frontend/views/layouts/main.php に追加された
menuHide
属性です:
リーリー
突然、ドロップダウン メニューが複雑ではなくなりました:
徐々に、モバイル Web の機能を簡素化し、削減することが最高のエクスペリエンスを生み出すことに気づきました。少なくとも現時点では、いつでもデスクトップに戻って他の機能にアクセスできます。これは、アルファおよびベータ段階で人々からフィードバックを収集する機会でもあります。
Yii のデフォルト レイアウトにはブレッドクラム ウィジェットが含まれていますが、これは Composer を通じて読み込まれるため、カスタマイズが困難です。最初の要素と最初の「/」区切り文字を非表示にする CSS を追加してみました:
これには時間がかかりましたが、n 番目の子要素など、CSS をさらに深く掘り下げることができ、自信がつきました。 リーリー
CSS でコンテンツを変更できるとは知りませんでした。指先ボタンの間隔を広げる
次に、CSS を追加して、モバイル デバイスのボタンに追加のパディングを提供し、指先で押すときにエラーが発生する可能性を減らしました。たとえば、デスクトップ上の送信ボタンとキャンセル ボタンは次のとおりです:
これは私が使用し、サイト内のさまざまなボタンやクリック可能なアイコンに追加し始めた CSS です: リーリー
モバイルでフォームがどのように表示されるかは次のとおりです。Cancel
の間の新しいパディングに注目してください:レスポンシブ テキストの折り返し
ホームページのタイトルを「Scheduling Made Easy」にするのには、実際にはもっと時間がかかります。最終的に、テキストに
タグを追加し、モバイル デバイス以外ではデフォルトで非表示にしました。ただし、
itemHide<h1> <?php echo Yii::t('frontend','Scheduling'); ?> <br class="rwd-break" /> <span class="itemHide"> </span> <?php echo Yii::t('frontend','Made Easy') ?> </h1>
这是 .rwd-break
的 CSS。默认情况下它是隐藏的,并且仅出现在响应式显示中,从而按照我想要的方式破坏标题文本。
.rwd-break { display:none; } /* ----------- mobile displays ----------- */ @media only screen and (min-device-width: 320px) and (max-device-width: 667px) and (-webkit-min-device-pixel-ratio: 2) { ... .rwd-break { display:block; } }
如果没有 span 标记空间,文本将在没有正确居中的情况下中断。
随着我越来越认为“移动优先”,我意识到基于手机的用户并不需要我页面上的所有功能。他们不需要所有选项卡,不需要有关会议的数据表,也不需要所有图标按钮选项。事实上,对于会议页面,他们只需要能够打开会议(他们可以从会议视图页面本身取消会议)。
我将主题和参与者列合并为一个垂直列,结果看起来好多了。
在 /frontend/views/meeting/index.php 中,我将 .tabHide
添加到两个四个选项卡中的:
<!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist"> <li class="active"><a href="#planning" role="tab" data-toggle="tab">Planning</a></li> <li ><a href="#upcoming" role="tab" data-toggle="tab">Confirmed</a></li> <li class="tabHide"><a href="#past" role="tab" data-toggle="tab" >Past</a></li> <li class="tabHide"><a href="#canceled" role="tab" data-toggle="tab">Canceled</a></li> </ul>
并且,在 /frontend/views/meeting/_grid.php 中,我重组了该列以合并主题和参与者:
if ($mode =='upcoming' || $mode =='past') { echo GridView::widget([ 'dataProvider' => $dataProvider, //'filterModel' => $searchModel, 'columns' => [ [ 'label'=>'Details', 'attribute' => 'meeting_type', 'format' => 'raw', 'value' => function ($model) { // to do - remove legacy code when subject didn't exist if ($model->subject=='') { return '<div><a href="'.Url::to(['meeting/view', 'id' => $model->id]).'">'.$model->getMeetingHeader().'</a><br /><span class="index-participant">'.$model->getMeetingParticipants($model->id).'</span></div>'; } else { return '<div><a href="'.Url::to(['meeting/view', 'id' => $model->id]).'">'.$model->subject.'</a><br /><span class="index-participant">'.$model->getMeetingParticipants($model->id).'</span></div>'; } }, ],
隐藏 ActionColumn
需要进行一些研究,但看起来像这样:
['class' => 'yii\grid\ActionColumn','header'=>'Options','template'=>'{view} {decline} {cancel}', 'headerOptions' => ['class' => 'itemHide'], 'contentOptions' => ['class' => 'itemHide'], 'buttons'=>[ 'view' => function ($url, $model) { return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', $url, [ 'title' => Yii::t('frontend', 'view'), 'class' => 'icon-pad', ]); }, 'decline' => function ($url, $model) { return ($model->status==$model::STATUS_SENT ) ? Html::a('<span class="glyphicon glyphicon-thumbs-down"></span>', $url, [ 'title' => Yii::t('frontend', 'decline'), 'class' => 'icon-pad', ]) : ''; }, 'cancel' => function ($url, $model) { return ($model->status==$model::STATUS_SENT || $model->status==$model::STATUS_CONFIRMED ) ? Html::a('<span class="glyphicon glyphicon-remove-circle"></span>', $url, [ 'title' => Yii::t('frontend', 'cancel'), 'data-confirm' => Yii::t('frontend', 'Are you sure you want to cancel this meeting?'), 'class' => 'icon-pad', ]) : ''; }, ] ],
最终,这些更改在改进移动设备的过程中简化了桌面界面。
到目前为止,对我来说最具挑战性的任务是针对移动设备调整上面的会议安排页面。手机上的情况一团糟,我很害怕。另外,我一直担心将来如何为多个参与者采用这个界面 - 响应性要求可能只会让这变得更加困难。
我对 Yii 的 Kartik Bootstrap Switch Widget 扩展的使用在修改布局方面有其自身的局限性。将这些元素放置在表格列中效果很好,但使表格列响应式对于媒体查询来说并不那么简单。
当然,正如我在上面的会议列表页面中所示,隐藏列很容易,但修改位置就不那么容易了。
我首先从显示时间和地点选项的水平表格设计转向垂直的纵向风格。而且,显然,表和列有自己的能力,可以在没有媒体查询的情况下使用 HTML5 和 CSS 进行包装。
您可以在此处查看改进后的空白会议计划页面:
每个部分视图都需要额外的 css 列才能使预定义的 Bootstrap 网格布局正常工作,例如左 col-xs4 和右 col-xs-8。这是一个例子:
<div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading"> <div class="row"> <div class="col-lg-4 col-md-4 col-xs-4"><h4>What</h4></div> <div class="col-lg-8 col-md-8 col-xs-8"><div style="float:right;"> <?php if ($isOwner) { echo Html::a('', ['update', 'id' => $model->id], ['class' => 'btn btn-primary glyphicon glyphicon-pencil','title'=>'Edit']); } ?> </div> </div> </div> </div>
使地点和时间安排表格具有响应性是最困难的。我进行了实验并最终成功地使用了随着内容窗口(或设备)缩小而自然换行的表列。
我还消除了在其自己的列中显示参与者状态并禁用开关的情况 - 您无法更改它们,那么为什么将它们显示为开关呢?相反,我创建了参与者在地点和时间的状态的文本摘要。以下是 getWhenStatus()
的代码:
public static function getWhenStatus($meeting,$viewer_id) { // get an array of textual status of meeting times for $viewer_id // Acceptable / Rejected / No response: $whenStatus['text'] = []; $whenStatus['style'] = []; foreach ($meeting->meetingTimes as $mt) { // build status for each time $acceptableChoice=[]; $rejectedChoice=[]; $unknownChoice=[]; // to do - add meeting_id to MeetingTimeChoice for sortable queries foreach ($mt->meetingTimeChoices as $mtc) { if ($mtc->user_id == $viewer_id) continue; switch ($mtc->status) { case MeetingTimeChoice::STATUS_UNKNOWN: $unknownChoice[]=$mtc->user_id; break; case MeetingTimeChoice::STATUS_YES: $acceptableChoice[]=$mtc->user_id; break; case MeetingTimeChoice::STATUS_NO: $rejectedChoice[]=$mtc->user_id; break; } } $temp =''; // to do - update for multiple participants // to do - integrate current setting for this user in style setting if (count($acceptableChoice)>0) { $temp.='Acceptable to '.MiscHelpers::getDisplayName($acceptableChoice[0]); $whenStatus['style'][$mt->id]='success'; } else if (count($rejectedChoice)>0) { $temp.='Rejected by '.MiscHelpers::getDisplayName($rejectedChoice[0]); $whenStatus['style'][$mt->id]='danger'; } else if (count($unknownChoice)>0) { $temp.='No response from '.MiscHelpers::getDisplayName($unknownChoice[0]); $whenStatus['style'][$mt->id]='warning'; } $whenStatus['text'][$mt->id]=$temp; } return $whenStatus; }
这是它在桌面上的样子 - 注意文本行和开关的横向布局:
这是移动版本,更加纵向且堆叠,无需媒体查询:
作为示例,以下是我在“时间”面板上对表格列进行编码的 CSS: p>
table.table-list { width:100%; } table.table-list td.table-list-first { float: left; display: inline; width: auto; } table.table-list td.table-switches { width: auto; float: right; display: inline; padding-top: 10px; } .switch-pad { padding-left:7px; } .smallStatus { font-size:90%; color: grey; font-style: italic; }
这是来自 /frontend/views/meeting-time/_list.php 的部分表单的代码:
<?php use yii\helpers\Html; use frontend\models\Meeting; use \kartik\switchinput\SwitchInput; ?> <tr > <!-- panel row --> <td > <table class="table-list"> <!-- list of times --> <tr> <td class="table-list-first"> <!-- time & status --> <?= Meeting::friendlyDateFromTimestamp($model->start,$timezone) ?> <?php if ($whenStatus['text'][$model->id]<>'') { ?> <br /><span class="smallStatus"> <?php echo $whenStatus['text'][$model->id]; ?> </span><br /> <?php } ?> </td> <td class="table-switches"> <!-- col of switches to float right --> <table > <tr> <td > <?php if ($isOwner) { showTimeOwnerStatus($model,$isOwner); } else { showTimeParticipantStatus($model,$isOwner); } ?> </td> <td class="switch-pad"> <?php if ($timeCount>1) { if ($model->status == $model::STATUS_SELECTED) { $value = $model->id; } else { $value = 0; } if ($isOwner || $participant_choose_date_time) { // value has to match for switch to be on echo SwitchInput::widget([ 'type' => SwitchInput::RADIO, 'name' => 'time-chooser', 'items' => [ [ 'value' => $model->id], ], 'value' => $value, 'pluginOptions' => [ 'size' => 'mini','handleWidth'=>60,'onText' => '<i class="glyphicon glyphicon-ok"></i> choose','onColor' => 'success','offText'=>'<i class="glyphicon glyphicon-remove"></i>'], // $whenStatus['style'][$model->id], 'labelOptions' => ['style' => 'font-size: 12px'], ]); } } ?> </td> </tr> </table> </td> <!-- end col with table of switches --> </tr> </table> <!-- end table list of times --> </td> </tr> <!-- end panel row -->
这些会议视图变化的最大好处是,它们将简化未来有许多参与者的会议的用户体验设计挑战。无论参加会议的人数有多少,观点都会与上述基本相同。从本质上讲,这解决了我扩展到多人会议的最大障碍——用户体验设计。
我希望您喜欢跟随我研究响应式网页设计的细节。当网站的代码和视觉变化结合在一起时,我感到非常满意,并且对 CSS 的需要之少印象深刻。综合起来,您可以在这里看到:
.rwd-break { display:none; } table.table-list { width:100%; } table.table-list td.table-list-first { float: left; display: inline; width: auto; } table.table-list td.table-switches { width: auto; float: right; display: inline; padding-top: 10px; } .switch-pad { padding-left:7px; } .smallStatus { font-size:90%; color: grey; font-style: italic; } .setting-label label, #preferences label { font-weight:normal; } /* ----------- mobile displays ----------- */ @media only screen and (min-device-width: 320px) and (max-device-width: 667px) and (-webkit-min-device-pixel-ratio: 2) { /* hides drop down menu items and footer items */ .itemHide,li.menuHide { display:none; visible:false; } /* removes home and / from breadcrumb */ ul.breadcrumb li:first-child, li.tabHide { display:none; visible:false; } ul.breadcrumb li:nth-child(2)::before { content:''; } /* fingertip spacing for buttons */ a.icon-pad { padding: 0 5px 0 2px; } .button-pad { padding-left:7px; } .rwd-break { display:block; } }
我未来的设计工作将从“这在移动设备上看起来应该是什么样子?”
如前所述,我目前正在积极准备 Meeting Planner 的 alpha 版本。我主要关注使 alpha 版本顺利发布的关键改进和功能。
我现在正在跟踪 Asana 中的所有内容,我将在另一个教程中对此进行介绍;这非常有帮助。还有一些有趣的新功能仍在开发中。
また、Meeting Planner を通じた今後の投資回収活動にもより注意を払うようになりました。 SEC の新しいクラウドファンディング ルールの実装に伴い、WeFunder を試し始めたところです。プロフィールのフォローをご検討ください。これについては、今後のチュートリアルでも詳しく説明します。
繰り返しますが、さらなるエピソードを待っている間に、最初のミーティングを (電話で!) スケジュールしてください。また、以下のコメント欄であなたの経験を共有していただければ幸いです。私は常にあなたの提案に興味を持っています。 Twitter @reifman で直接私にご連絡いただくこともできます。ミーティング プランナー サポート Web サイトに投稿することもできます。
「Build Your Startup with PHP」シリーズの今後のチュートリアルをご覧ください。
###関連リンク###以上がスタートアップ向けのモバイル Web エクスペリエンスの強化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。