20190816のCSSに関する記事は5件です。

Vue.jsでチェス盤を作ってみたら8行だった。

チェス盤はなぜ白黒なのか

あの違い互いの白黒盤のせいでちょっと苦戦した話です。

一応チェスを後々作る前提でボードを作ってみました。

今回のゴール

1.見た目的にチェス盤と認識できるものを作る
2.今後チェスを作る前提の構造になっていないとダメ

†考察†

実際チェスを作るとなると必須となるのが、
64マスそれぞれに座標が備わっていること。

つまりこういうこと。

[1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8, 
 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8, 
 3-1, 3-2, 3-3, 3-4, 3-5, 3-6, 3-7, 3-8, 
 4-1, 4-2, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 
 5-1, 5-2, 5-3, 5-4, 5-5, 5-6, 5-7, 5-8, 
 6-1, 6-2, 6-3, 6-4, 6-5, 6-6, 6-7, 6-8,
 7-1, 7-2, 7-3, 7-4, 7-5, 7-6, 7-7, 7-8,
 8-1, 8-2, 8-3, 8-4, 8-5, 8-6, 8-7, 8-8]

X軸とY軸の数値を合わせてるような感じ。

この配列を作るだけであれば簡単。

    let board = [];
    for(let x = 1; x < 9; x++) {
      for(let y = 1; y < 9; y++) {
        board.push(x + "-" + y)
      }
    }

8×8のループを行えば一瞬でできてしまうので、
Vue.jsでレンダリングするとしても、v-for="n in 8"を二回やればいいだけ。

将棋であればここで完成。
だがしかし、チェス盤となると少しやっかい。


ときて、
今度は

まあ冒頭でも言ってますが、
つまり、1行目と2行目だと、1列目の色が反転しているということです。

えらいこっちゃ~~~となっていろいろ考えて
しばらくしてやっとこちらの文系エンジニアも気づきました。

「奇数行と偶数行で出し分けすればいいんだ」

つまりはこういうこと。

  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div>
        <div class="square-white" :id='`${x}-${y}`' v-else></div>
      </div>
    </div>
  </div>

FireShot Capture 010 - chess_board - localhost.png

おぉ~~~できた!

ちゃんとそれぞれidも1-1から8-8まで振れている。
そしてなによりコードがかなり短く収まった!!

一応解説

8回ループを二回するまでは同じ、
そしてそこからは、一回目のループxと二回目のループyそれぞれの値でv-if使って出し分け。

xの一回目とyの一回目であれば1と1になるので、
合計が2偶数なので黒スタート。

xの二回目とyの一回目であれば2と1になるので、
合計が3奇数なので白スタート。

最後に

座標もしっかり入っているので、
チェス作りの道も開けたといった感じですね。

筆者はこういう閃きみたいなのが圧倒的に欠如している
文系エンジニアなので時間はかかったものの、
法則を見つけて何かをスッキリ書くのはよだれが出てくるぐらい好きです。

いつになるかわからないですが、
次はチェスの動きの部分を投稿したいです。

スタイルも含めたコードを載せておきます。

Board.vue
<template>
  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div>
        <div class="square-white" :id='`${x}-${y}`' v-else></div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.board {
  width: 640px;
  height: 640px;
  border: 4px solid black;
}

.square-black {
  width: 80px;
  height: 80px;
  background-color: black;
  float: left;
}

.square-white {
  width: 80px;
  height: 80px;
  background-color: white;
  float: left;
}
</style>

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsでチェス盤を作ってみたら7行だった。

チェス盤はなぜ白黒なのか

あの違い互いの白黒盤のせいでちょっと苦戦した話です。

一応チェスを後々作る前提でボードを作ってみました。

今回のゴール

1.見た目的にチェス盤と認識できるものを作る
2.今後チェスを作る前提の構造になっていないとダメ

†考察†

実際チェスを作るとなると必須となるのが、
64マスそれぞれに座標が備わっていること。

つまりこういうこと。

[1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8, 
 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8, 
 3-1, 3-2, 3-3, 3-4, 3-5, 3-6, 3-7, 3-8, 
 4-1, 4-2, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 
 5-1, 5-2, 5-3, 5-4, 5-5, 5-6, 5-7, 5-8, 
 6-1, 6-2, 6-3, 6-4, 6-5, 6-6, 6-7, 6-8,
 7-1, 7-2, 7-3, 7-4, 7-5, 7-6, 7-7, 7-8,
 8-1, 8-2, 8-3, 8-4, 8-5, 8-6, 8-7, 8-8]

X軸とY軸の数値を合わせてるような感じ。

この配列を作るだけであれば簡単。

    let board = [];
    for(let x = 1; x < 9; x++) {
      for(let y = 1; y < 9; y++) {
        board.push(x + "-" + y)
      }
    }

8×8のループを行えば一瞬でできてしまうので、
Vue.jsでレンダリングするとしても、v-for="n in 8"を二回やればいいだけ。

将棋であればここで完成。
だがしかし、チェス盤となると少しやっかい。


ときて、
今度は

まあ冒頭でも言ってますが、
つまり、1行目と2行目だと、1列目の色が反転しているということです。

えらいこっちゃ~~~となっていろいろ考えて
しばらくしてやっとこちらの文系エンジニアも気づきました。

「奇数行と偶数行で出し分けすればいいんだ」

つまりはこういうこと。

  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div 
         v-bind:class="(x + y) % 2 == 0 ? 'square-black' : 'square-white'" 
         :id='`${x}-${y}`'
        >
        </div>
      </div>
    </div>
  </div>

FireShot Capture 010 - chess_board - localhost.png

おぉ~~~できた!

ちゃんとそれぞれidも1-1から8-8まで振れている。
そしてなによりコードがかなり短く収まった!!

一応解説

8回ループを二回するまでは同じ、
そしてそこからは、一回目のループxと二回目のループyそれぞれの値でv-if使って出し分け。

xの一回目とyの一回目であれば1と1になるので、
合計が2偶数なので黒スタート。

xの二回目とyの一回目であれば2と1になるので、
合計が3奇数なので白スタート。

最後に

座標もしっかり入っているので、
チェス作りの道も開けたといった感じですね。

筆者はこういう閃きみたいなのが圧倒的に欠如している
文系エンジニアなので時間はかかったものの、
法則を見つけて何かをスッキリ書くのはよだれが出てくるぐらい好きです。

いつになるかわからないですが、
次はチェスの動きの部分を投稿したいです。

スタイルも含めたコードを載せておきます。

Board.vue
<template>
  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div 
         v-bind:class="(x + y) % 2 == 0 ? 'square-black' : 'square-white'" 
         :id='`${x}-${y}`'
        >
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.board {
  width: 640px;
  height: 640px;
  border: 4px solid black;
}

.square-black {
  width: 80px;
  height: 80px;
  background-color: black;
  float: left;
}

.square-white {
  width: 80px;
  height: 80px;
  background-color: white;
  float: left;
}
</style>

追記:
もともと、v-ifとv-else使ってdomを出し分けしようと書いていたのですが、v-bind:classを使えばDOMが一つにまとまると思い、修正しました。
なので、

\8行から7行に変わりました/

そもそも、出し分けするとはいえ、全く同じidを両方に振っていたのもなんだが危なっかしいので、
classの切り替え処理のほうが正しい気がします。

元のコード:

<template>
  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div>
        <div class="square-white" :id='`${x}-${y}`' v-else></div>
      </div>
    </div>
  </div>
</div>
</template>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

俺的CSSの便利なProperty・Value・Selector 50連発!

最近すごくHTMLやCSSを書いている気がするので、ここらでCSSのよく使うプロパティや知っていると便利なプロパティをまとめてみることにしました。早速行ってみましょう!

よく使うもの

1. ::before, ::after

これを指定した要素の子要素として挿入される疑似要素。子要素を持てない要素(img, inputなど)には指定不可能。contentプロパティを指定しない限り挿入されない。なにも入れるcontentがない場合はcontent: ""を指定する。

2. min-height, min-width

高さや幅の最小値を指定する。mainコンテナのように、必ずある大きさ以上の大きさが必要な要素に指定すると、コンテンツの大きさにかかわらず設定した大きさより小さくならない。

3. max-height, max-width

上のmin-系とは逆に、高さや幅の最大値を設定する。指定すると、コンテンツの大きさにかかわらず、設定した大きさより大きくならない。

4. order

HTMLの要素の兄弟順をオーバーライドする。これを指定すると、強制的に兄弟要素の中でその順番になるように表示される。nth-系には影響しない。

5. visibility

display: noneと違って、表示したくないけれど領域は確保したいという場合に使える。

6. z-index

要素の描画順を設定するプロパティ。position: fixed;と使うことが多い。

7. clip-path

要素の見かけの外形を設定するプロパティ。うまく使えばCSSだけでいろんな表現が可能に。

8. will-change

要素のCSSプロパティがアニメーションで変化することをあらかじめブラウザに知らせる。パフォーマンス爆上がり。

9. transform

要素を移動、回転、拡縮、変形させるプロパティ。ちょっと場所がずれるときとか、アニメーションで動かしたいときに便利。

10. :root

root疑似クラス。document.documentElementを指し示すセレクタ。カスタムプロパティと組み合わせると応用範囲は無限大。メディアクエリと組み合わせるとモバイルビュー判定にも使える。

@media screen and (max-width: 960px) {
    :root {
        --is-mobile: yes;
    }
}
@media screen and (min-width: 961px) {
    :root {
        --is-mobile: no;
    }
}

11. transform-origin

transformプロパティの基準になる点を指定するプロパティ。ローディング画面のスピナなどを作るときなど、意外と使える場面が多い。

12. position: relative

position: absoluteが親要素を基準とした位置取りにならない!?って思ったときは大概こいつの設定忘れが原因。これが設定された要素の子要素にposition: absoluteが指定された場合、これが設定された要素を基準とした位置取りになる。

13. appearance: none

デフォルトの見た目をなくすプロパティ。input要素に独自のスタイルを当てたいときなど、これを設定するとうまくいくことが多い。

14. box-shadow

要素が落とす影を設定するプロパティ。背景が設定されていない要素につけると違和感マシマシ。そういうインラインなテキスト要素に影をつけたい場合は、text-shadowプロパティを使うこと。

15. background-clip

きれいなタイトル文字の修飾をしたいときに。ヘッディング要素のbackground-imageプロパティに適当な画像を設定して、このプロパティの値をtextにすると、背景が文字の形で切り抜かれる。

16. background-attachment: fixed

要素内のコンテンツが動いても、背景を動かしたくない場合に使う。サイトの背景に設定するといい感じになるかも。

17. border-radius

要素を角丸にできる。もはや説明不要。

18. :not

セレクタにマッチしない要素にマッチする。例えば、:not(.not-select)というセレクタは、not-selectクラスを持たない要素にマッチする。

19. :first-child, :last-child, :nth-child, :nth-last-child

指定された順番にある兄弟要素にマッチする疑似クラス。

20. :first-of-type, :last-of-type, :nth-of-type, nth-last-of-type

指定された順番にある同じタグ(spanどうし、divどうしなど)の兄弟要素にマッチする疑似クラス。

21. :required

required属性のあるformパーツにマッチする。

22. :invalid

入力された値が要求された形式に従っていないformパーツにマッチする。

23. outline

borderの外側に描画されるborderみたいなやつ。borderと違って、それ専用に場所が確保されない。

24. attr()

print画面でだけ::after疑似要素にurlを表示したいときなど、CSSのプロパティに特定のHTML属性を設定したいときに使用する。

25. user-select

ユーザーが要素を選択可能かどうかを設定する。spanにclickイベントを設定したときなど、選択されるのが鬱陶しかったり、要素を選択してほしくないときに使う。

26. pointer-events

要素のどこがマウスイベントをキャプチャするか指定するプロパティ。オーバーレイなど、ほかの要素より前に出るがマウスイベントをキャプチャしたくない要素にはnoneを設定すると吉。

27. cursor

要素の上に乗ったカーソルの表示の種類を設定する。ユーザビリティが上がるらしい。

28. :checked

チェックが入っているチェックボックスにマッチする。うまく活用するとHTML/CSSだけで開閉するメニューなどの2つの状態を持つUIが記述できる。

29. display: flex

要素をflexboxにする。子要素の数によって、自動でいい感じに配置を決めてくれる。すごく便利。ついつい多用しがち。

30. justify-content

要素の配置を決めるプロパティ。上のdisplay: flexと組み合わせて使うことが多い。

31. flex-flow

flexboxで、要素を配置する向きを決める。

32. flex

flexboxの子要素に指定するプロパティ。flex-grow、flex-shrink、flex-basisの3つを一気に指定できる。flex-growは要素がコンテナより小さいときにどれくらい大きくするか、flex-shrinkは逆に要素がコンテナより大きいときにどれくらい小さくするか、flex-basisは要素がコンテナの中でどれくらいの初期サイズを持っているのかを指定する。

そこまで使うわけでもないけど知っていたら便利なもの

33. position: sticky

これを設定された要素が親要素の中でrelative + fixedのような振る舞いをするようになる。Qiitaのいいねボタンやストックボタンのスマホ版みたいな振る舞いがこれ(とtop, bottom, right, leftプロパティのどれか1つ以上)だけで記述可能。

34. text-indent

行頭字下げをするプロパティ。パラグラフの先頭で字下げしたいときに有効。

35. ::first-letter

ある要素の中で、最初の文字にマッチする疑似要素。パラグラフの最初の文字だけ大きくするような表現に使える。

36. ::select

ある要素の中で、現在選択されているものにマッチする疑似要素。選択部分の強調などに使える。

37. ::target

urlのターゲットになっている要素にマッチする。ページ内リンクで飛んだ先の要素を強調するのに使える。

38. perspective

transformと組み合わせて使う。遠近法をどの程度かけるか指定するプロパティ。

39. transform-style: preserve-3d

これを三次元の移動回転変形を指定したtransformプロパティを持つ要素の親に指定することで、3次元的な描写を可能にすることができる。

40. filter

要素に指定したSVGフィルタをかける。::beforeに指定して背景をぼかしたり、グレイスケール化したり、いろいろな視覚効果を追加することができる。

41. ::marker

::marker
リストのマーカーにマッチする疑似要素。

  • ←これがリストのマーカー。

42. ::placeholder

formパーツ要素のplaceholderにマッチする。placeholderの色やフォントなどを変えたいときに便利。

43. :defined

任意のCustomElementにマッチする。

44. quotes

<q>~</q>のタグを使ったときに表示される引用符を制御できる。それ以外のタグの場合も、以下のようにして利用できる。

blockquote {
    quotes: "「" "」";
}
blockquote::before {
    content: open-quote;
}
blockquote::after {
    content: close-quote;
}

より正確な動作の説明としては「open-quoteclose-quoteの値を制御する」ということになる。

45. text-overflow

文字がコンテナのサイズを超過したときの処理を設定する。...のような記号で省略したり、それ以外の文字で省略したり、あるいはそれ以上を表示しなかったりするような表現が可能。

46. writing-mode

文字を縦書きにするか横書きにするか設定できる。サイトの種類によっては多用することもあるかも。

47. text-orientation

writing-modevertical-rlまたはvertical-lrにしたときに、文字をどの向きで配置するか設定する。

48. clear

浮動要素のまわりの固定要素の配置(回り込み)を指定する。浮動要素しか含まないような要素の高さを維持するために使うこともできる。

.float-only::after {
    content: "";
    display: block;
    clear: both;
}

49. all

すべてのプロパティを一気に設定できる。親要素からすべてのスタイルを継承したいときや、逆に継承したくないとき、デフォルトの見た目にしたいときに使える。

50. touch-action

要素に対して可能なタッチアクションの種類を制限できる。たとえば、ズームしてほしくないとか、縦方向のスクロールを制限したいとかそういう場合に便利。Cookie Clickerのタッチ領域にこれを指定してほしいと何度思ったことか。

まとめ

CSS難しい……。MDNの解説ってプロパティごとに内容の質にけっこうばらつきが大きいんですね。

参考

Happy Hacking!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【CSS】改行コードを含む文字列をCSSだけで改行させる。(ばいばいBR)

メモとして残します。

■やり方

white-space属性で、値がpre-wrap

ELEMENT_selector{
    white-space: pre-wrap;
}

今まで、バックエンドで渡すとき、もしくはフロントでデータ受け取り後に改行コードを<br />に置換してたので、面倒でしたが、これで、無駄なコードを書かなくて済みます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【日記】DjangoでImageFieldを実装したり、object-fitで画像表示したりした。

Django公式チュートリアルで作るpollsアプリケーションの発展型のようなものを作っています。詳しくはまだないしょです。

今日は各投稿の詳細画面をある程度実装しました。デザインはまだ何もいじっていないので見た目カッコ悪いですが……。あとからやります。

スクリーンショット 2019-08-15 18.29.34.png

ImageField

今日実装したのは画像を扱うフィールド、ImageFieldです。公式チュートリアルでは触れられておらず、ドキュメントでも詳しく触れられていなかったので困りました。ググったところ、Django BrothersのチュートリアルがImageFieldについて扱っていて、非常にわかりやすかったのでこれに沿って実装しました。

ImageFieldを使ってみよう

僕の場合、default値を設定したかったのですが、ファイルを指定するパスが良くわからずだいぶ四苦八苦しました。結果的にこうなりました。

models.py
choice_image = models.ImageField(upload_to='polls', default=os.path.join(BASE_DIR, '/polls/default_icon.jpg'))

詳しくはDjango Brothersチュートリアルを読んでほしいのですが、settings.pyでMEDIA_ROOTを指定したところからのパスで良いようです。

settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

つまり、ImageFieldのデフォルト画像のパスは以下のようになります。
/media/polls/default_icon.jpg

object-fit

画像を表示できたは良いものの、画像サイズがそのままなので表示が整いません。縦横比を維持しつつ正方形で表示したかったので調べてみたところ、CSSのobject-fitというものを使えばうまくいきそうです。

1行追加でOK!CSSだけで画像をトリミングできる「object-fit」プロパティー|Webクリエイターボックス

実際に書いたコードはこちら

/polls/static/polls/style.css
.choice_image {
    width: 100px;
    height: 100px;
    object-fit: cover;
}

画像にはchoice_imageクラスを指定しました。

細かい話

スーパーリロードというものについて知りました。キャッシュを消してリロードできるので、CSSを変更したのに反映されない!ってときに使うといいです。

Django開発中にクロームでcssが反映されない場合の対処方法 - 知的好奇心

円グラフを表示したかったがうまくいかない

投票された割合を表示する手段として、円グラフを実装したいのですがこれがうまくいかなかったので持ち越しです。Chart.jsというJSライブラリを使おうと思ったのですが、Pythonのfor文とどのように共存させればよいかわからないのです。もしかしたらviews.pyで作成したほうが良いのかもしれないですね。

Chart.jsでグラフを描画してみた

今後の課題です。がんばろう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む