コロナに関する呼びかけを簡単にする、Webサービス「Yobikake」の見た目を作る技術と工夫


こんにちはー!東京都在住のため、がっつり外出自粛をしている人間です。「ぴえん🥺」よりも「display: flex;」を愛用しているJKです。(これが言いたいだけで女子高生という属性を乱用してしまいました。申し訳ございません。)

友だち(@nztm)と2人で「Yobikake ~あなたの呼びかけからはじめよう~」というWebサービスをつくったので、今回は自分が主に実装した部分の技術的解説・デザイン的解説をします。なお、Nuxt.js (Vue.js)を使用しています。

※今回初めて触ったので、間違った知識など記載していましたら、コメント等でご指摘いただけますと嬉しいですm(_ _)m

この記事の想定読者

  • 自分でちょっとしたWebサイトを作りたい人
  • HTML/CSS から一歩踏み出した技術をつかってWebサイトを作ってみたい人
  • Webデザインに興味がある人

何を作ったのか

今回開発した「Yobikake ~あなたの呼びかけからはじめよう~」は、OGP画像を活用した、新型コロナウイルスに関連する呼びかけができるWebサイトです。#StayHome や #うちで過ごそう といったハッシュタグを見たことはないでしょうか。現在、様々な人が世界中、各SNSで呼びかけを行っています。
「その『呼びかけ』を、ワンクリックで気軽にできるようになれば、世界を少しでも救えるのではないか」という発想で、このサービスは作られました。

仕組みは以下の図のようになっています。

開発の流れ

4/10, 金曜日午前に「今日とか明日って忙しいですか?」と、@nztm さんから一通のメッセージが。話を聞いてみると、OGP画像を利用して、新型コロナウイルスに関するムーブメントを促すという、シンプルなWebサービスを作りたいとのこと。「面白そう!やりたい!」と、協力させていただきました。

役割の分担についてですが、コンテンツ、仕組みの実装、デザインの方向性決定は @nztm さん、見た目に関する実装は私が担当しています。コンテンツを @nztm さんが作り、それをもとに私が見た目を整えていき、それに @nztm さんがフィードバックを返し、という流れを繰り返しました。

なお、コンセプトや仕組みについての記事は以下で @nztm さんが書いています。
https://qiita.com/nztm/items/2de55be97ac1de9a435b

サービスの概念と方向性の共有は、初日にZoomを利用して行いました。ディレクトリはGitHubで管理し、コンテンツ及びデザインに関する議論はissueまたはTwitterDMで行っています。

工夫した点・語りたい点

共有ボタンの実装

まずは、このサービスの重要な機能ともいえる「共有ボタン」の実装についてです。
共有ボタンは共通で使いまわしたいので、コンポーネント化しました。

1. 共有するテキストを動的に変更できるようにする

「よびかけ」ごとに共有したい文章とURLが異なります。文章とURLのデータを受け取って、aタグのhrefが変わるようにしました。

コンポーネント化・読み込み

毎回ボタン3つ分を記述するとメンテナンス性が下がってしまうので、コンポーネント1つをそれぞれ読み込むようにしました。なにか変更を加えたいときも、一つのファイルをいじるだけで良いので、とてもスッキリとした設計になりました。
いくつか略していますが、共有ボタン3つのコンポーネントは以下のようになっています。

shareButtons.vue
<template>
  <div class="share-buttons">
    <a
      :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      "
      target="_blank"
      class="share-link share-link-twitter"
      ><i class="fab fa-twitter"></i> ツイートする
    </a>
    <a
      :href="
        'https://www.facebook.com/dialog/share?app_id=640540216785473&display=popup&href=https://yobikake.com/' +
          url
      "
      target="_blank"
      class="share-link share-link-fb"
      ><i class="fab fa-facebook"></i> シェアする
    </a></div>
</template>

<script>
export default {
  props: ['url', 'text'],
  
}
</script>

<style lang="scss" scoped>

</style>

これを、以下のように呼び出すことで表示できます。

index.vue
<template>
  <div>
    <shareButtons
      url="stayhome"
      text="うちで過ごそう!みんなのために🏠
 #うちで過ごそう #stayhome #Yobikake"
    ></shareButtons>
  </div>
</template>

<script>
import shareButtons from '~/components/shareButtons.vue'

export default {
  components: {
    shareButtons
  }
}
</script>

このように表示されます。

もう少し細かく説明します。

URLの設定について

共有するURLの前半は共通なので、urlhttps://yobikake.com/ に続くパスを入れることにしました。また、text は、メンテナンス性・可読性を考えて、UTF-8に変換する前の状態で管理できるようにしました。意外とシンプルに、encodeURIComponent() でさくっと変換できています。
(下記Twitter用のリンクの例を参照)

<a :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      " >
href ではなく :hrefとなっている理由

href他、HTML属性の内部では文字列の連結等操作ができません。そこで活躍するのがVue.jsさんのv-bindです。v-bindはプロパティや属性と、式を結びつけてくれるものです。便利ですねぇ。
例えば、<a v-bind:href="式"> のように書くことができます。ここでは省略記法で、v-bind:hrefではなく:hrefと記述しています。

Vue.js ガイドで、構文について書いてあるので、詳しくはそちらを読んでいただけるとわかりやすいと思います。

2. コピーボタン

できるだけ多くの方に使っていただけることが一番なのですが、Twitter, Facebook以外のサービス全てに対応することは難しいです。そこで、どんなプラットフォームでもペーストで呼びかけられるよう、簡単にURLをコピーできるボタンを設けました。

このボタンは、クリック時にcopy()というメソッドを呼び出します。ラベルはcopyLabelという変数に入っている文字列を表示します。

<span
  class="share-link share-link-copy copy"
  @click="copy('https://yobikake.com/' + url)"
  ><i class="far fa-copy fa-fw"></i>{{ copyLabel }}
</span>

copy()では、引数をクリップボードにコピーして、copyLabelを変更しています。

<script>
export default {
  props: ['url', 'text'],
  data: () => ({
    copyLabel: 'コピーする'
  }),
  methods: {
    copy(msg) {
      const copyText = msg
      navigator.clipboard.writeText(copyText)
      this.copyLabel = 'コピーしました!'
      setTimeout(
        function() {
          this.copyLabel = 'コピーする'
        }.bind(this),
        2000
      )
    }
  }
}
</script>

もう少し余裕があれば、それぞれの「呼びかけ」もコンポーネント化して管理したいところですね。ですが、まずは2日後のリリースまでに使える状態にすることが最優先だったので、このような形になりました。

きれいに魅せる工夫

さて、機能が正常に動くことも大事ですが、その配置・表示も重要です。
いくつかこだわった点をまとめます。

ヘッダーのキャッチコピー表示

ヘッダーのキャッチコピーですが、文字を表示するだけではない、小さなこだわりがあります。単なる表示だと、このように変な改行が入ってしまいます。まるで「今すぐダウンロー ⏎ド」のようですね。


そこで、文を分解(ダジャレ)して、それぞれにdisplay: inline-block;を設定します。そうすることで、自然な部分で改行されるようになります。

<span>あなたの呼びかけから</span><span>はじめよう</span>
span {
  display: inline-block;
}

一覧のレスポンシブ対応


この部分は、いろいろやりました。項目は4つなので、並べ方は2,2か4か1,1,1,1にすることで、仲間はずれがなくきれいに並べられます。
そのため、コンテンツそれぞれは基本固定幅に設定して、親要素の幅を画面幅に応じて変えるようにしました。技術的にはなにも難しくないのですが、細かなこだわりでぐっと見栄えが良くなります。

絵文字/色

最後に、絵文字と色についてです。絵文字はTwitterのオープンソースな絵文字、「twemoji」を使っています。絵文字の見た目が端末に依存しないという利点があります。また、フラットなデザインなので最近の流行りと相性が良いです。

色は、基本的に @nztm さんのデザインラフをメインに設定しています。背景色、フッターの色、影の色は、青〜水色で統一させています。

コンプレックスカラーといって、フッターよりも背景色を青寄りに設定しました。すこし意外性のある配色ですが、見ていて楽しいですよね。これ以上語ると話がそれてしまうので、以上にしたいと思います。

最後に

読んでいただきありがとうございました!
技術的な話より、考え方の話の紹介になってしまいましたが、WebサイトデザインやWebサービスづくりをやってみようかな、と考えている人の力になれていたら幸いです…!

ちなみに、ここから実際に動いているサービスを見られます👀
https://yobikake.com/

この「Yobikake」はGitHubで公開しています。PRやIssueお待ちしておりますm(_ _)m

追伸: 今回のサービスは3日間で作ったのですが、爆速開発をしてみようかな、と考えている方には「睡眠は大事ですよ」とだけお伝えしておきます。