[scss]毎回面倒な吹き出しをmixin化

なんでもっと早くやらなかったのか不思議で仕方ない。
毎回普通にcss書いてたので、流石にめんどくさくてmixin作りました。
単色の吹き出しに使えます。

// mixin
@mixin balloon-arrow($direction, $duration, $color) {
    position: absolute;
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-style: solid;
    @if $direction == top {
        top: -$duration;
        left: 50%;
        margin-left: -$duration;
        border-width: 0 $duration $duration $duration;
        border-color: transparent transparent $color transparent;
    }
    @if $direction == right {
        right: -$duration;
        top: 50%;
        margin-top: -$duration;
        border-width: $duration 0 $duration $duration;
        border-color: transparent transparent transparent $color;
    }
    @if $direction == bottom {
        bottom: -$duration;
        left: 50%;
        margin-left: -$duration;
        border-width: $duration $duration 0 $duration;
        border-color: $color transparent transparent transparent;
    }
    @if $direction == left {
        left: -$duration;
        top: 50%;
        margin-top: -$duration;
        border-width: $duration $duration $duration 0 ;
        border-color: transparent $color transparent transparent;
    }
}

引数はそれぞれ
$direction 吹き出しの方向、top, right, bottom, leftで指定 bottomだったらボックスの下にくっつく
$duration 吹き出しの大きさ pxで指定
$color 吹き出しの色 hexでもrgbでもrgbaでもok

// scss
.balloon {
    background: #000;
    border-radius: 20px;
    position: relative;
        
    &:after {
        @include balloon-arrow(bottom, 20px, #000);
    }
}

[concrete5 サイト制作] 社会福祉法人 恩賜財団 東京都同胞援護会

社会福祉法人 恩賜財団 東京都同胞援護会のサイトを10年ぶりにリニューアルしました
http://doen.jp/

昔MTで作ったせいで更新がすごく大変だったものをconcrete5にしてクライアントの更新作業が楽になるように設計。
もうずっとリニューアルしたかったんですよ

Screen Shot 2017-04-03 at 16.15.24-fullpage

Screen Shot 2017-04-03 at 16.15.39-fullpage

Screen Shot 2017-04-03 at 16.16.09-fullpage

Screen Shot 2017-04-03 at 16.16.03-fullpage

やったこと

  • デザイン
  • HTML/CSS/JSコーディング
  • レスポンシブ
  • concrete5組み込み
  • フォーム作成(concrete5外)
  • 承認フロー
  • 運用マニュアル作成

つらかったこと

  • 同じフォーマットにひたすら住所やら電話番号やら座標やらを入力していく作業
    →xmlかcsvでインポーター使えばよかったと反省。あるいはデータ投稿だけしてもらうバイトを雇えばよかった。
  • 承認フローがなかなかうまく機能してくれなくてどハマり
    →参考文献がなかったのと、フォーラムに質問するということを考えなかったので反省。次からはググってもわからない問題はフォーラムに質問しよう。
  • さくらサーバーで通知メールが飛ばない問題
    →もうどうしようもなくてフォーラムに相談して解決してもらった。

更新性が高い設計にするために汎用性をもたせつつ、デザインを両立させるという作業に対して、非常にモチベーションが高く保てたかな、と。
今回制作ページは160ページほどで、concrete5で作らなかったらおそらく3倍くらいの作業時間が必要だったのではないかなーと思います。

リリースしたおかげで今月は暇になったからゆっくり療養します。もう体がバキバキ。

MacのFirefoxでimgのhoverにtransitionとopacityを書くとバグる

表題の通りです。
Firefox(バージョン52で確認)で、画像にマウスを乗せた時にフェードでちょっとだけ透明度を上げるような動き、よくあるじゃないですか。

画像に直接transitionとopacityを指定したら、途中までは想定通りフェードで透明になるんですが、最後にopacity:1に戻ってしまうという事象が発生しました。

追記
どうやらwindowsのfirefoxだと想定通りに動くらしいので、macのfirefoxだけの事象のようです。
タイトルを変更させていただきました。
Firefoxでimgのhoverにtransitionとopacityを書くとバグる

MacのFirefoxでimgのhoverにtransitionとopacityを書くとバグる

想定の動き(Chromeでの表示)

Firefoxでの動き(Firefoxでの表示)

ソースコードは以下です。

<html>
<head>
<style>
.box {
  display: inline-block;
  }
a {
    display: block;
}
img {
    transition: opacity 0.3s ease;
}
a:hover img {
    opacity:0.8;
}
</style>
</head>
<body>
<div class="box">
<a href="#">
  <picture>
    <img src="1.jpg"> // ←こいつにtransitionとopacityを付与しているとバグる
  </picture>
</a>
</div>
</body></html>

原因がつかめなくて四苦八苦してしまったのですが、img自体にtransitionとopacityを付与するのではなく、imgの親にtransitionとopacityを付与することで解決しました。

<html>
<head>
<style>
.box {
  display: inline-block;
  }
a {
    display: block;
}
picture {
    transition: opacity 0.3s ease;
}
a:hover picture {
    opacity:0.8;
}
</style>
</head>
<body>
<div class="box">
<a href="#">
  <picture>// ←こいつにtransitionとopacityを付与して解決
    <img src="1.jpg"> 
  </picture>
</a>
</div>
</body></html>

[CSS]ブロックを上下左右中央に配置したい

ECサイトなんかだと、よくあるパターンなんですが、商品画像のトリミングが縦長だったり、横長だったりして、余白が気になるってお客さんに言われます。
トリミングが正方形だったらなんの問題もないんですが、ウェブに関わる全ての人が画像を正方形にトリミングできるはずもないので、それがどんなトリミングであっても美しく表示させるのがウェブデザイナーの仕事だと思います。

左右のセンタリングは簡単

text-align: centerを使って、左右中央は簡単にできます

<style>
div.LRbox {
  text-align: center;
  border: 1px solid #cacaca;
  width: 200px;
  height: 200px;
}
</style>

<div class="LRbox">
<img src="http://wordpress.go-designing.com/wp-content/uploads/2015/02/LR1.gif" alt="縦長の画像" width="150" height="200" />
</div>

縦長の画像

上下のセンタリングがめんどい

ダメな例

<style>
div.TBbox {
  vertical-align: middle;
  border: 1px solid #cacaca;
  width: 200px;
  height: 200px;
}
</style>
<div class="TBbox">
<img src="http://wordpress.go-designing.com/wp-content/uploads/2015/02/TB.gif" alt="横長の画像" width="200" height="150" />
</div>

横長の画像

上下の場合、vertical-align:middleを使っても中央によってはくれませんね。
要素名のせいで勘違いしやすいのですがvertical-alignは、ボックス内のインライン要素の高さ位置を揃えるのであって、ボックスの内部の位置を中央にするわけではないのです。

解決策

<style>
div.TBboxTrue {
  border: 1px solid #cacaca;
  width: 200px;
  height: 200px;
  position: relative; /* 親のボックスのpositionをrelativeに */
}
div.TBboxTrue img {
  position: absolute;  /* 上下中央にしたい要素のpositionをabsoluteに */
  top: 0; /* top位置を0 */
  bottom: 0; /* bottom位置も0 */
  margin: auto; /* marginをautoに */
}
</style>
<div class="TBboxTrue">
<img src="http://wordpress.go-designing.com/wp-content/uploads/2015/02/TB.gif" alt="横長の画像" width="200" height="150" />
</div>

横長の画像

応用

これを応用して、上下左右中央に指定しておくことができます。
たとえば、ボックスより大きい画像の場合は、max-widthやmax-heightを100%にしておくことで、ボックスから画像がはみ出てしまうことを回避できますが、そもそもボックスより画像が小さい場合は、上下左右中央に寄せることで対応するといいでしょう。

<style>
div.TBLRbox {
  border: 1px solid #cacaca;
  width: 200px;
  height: 200px;
  position: relative;
margin-bottom: 20px;
}
div.TBLRbox img {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
}
</style>
<div class="TBLRbox">
<img src="http://wordpress.go-designing.com/wp-content/uploads/2015/02/TBLR.gif" alt="ボックスより小さい画像" width="150" height="150" />
</div>

ボックスより小さい画像

[CSS] 〜戒め〜 display: inline-blockのブロック直下に、floatが掛かっているブロックを置いてはいけない

今週ずっと徹夜が続いておりまして、体力的にも精神的にも限界でした。
そのおかげで脳みそが全く働いていない状態でハマってしまった、いや、これは完全に油断ですね。
きっともうちょっと気を引き締めよとのお告げなのです。

デザイン的にタイトルにinline-blockを使いたかったんです。
で、その直下に画像と説明文をfloatしたかったんです。

下記の画像をごらんください。

赤のブロック、これがタイトルで、その下に左右のfloatブロックがある。
タイトルの幅は100%ではなくて、中途半端な感じにしたかったんですよ。デザイン的事情で。

そしたら、float: leftをかけたブロックがinline-blockの左に回り込むという事態に。
多分これは仕様通りの動きなんだろうけど、ちょっと納得いかないすね。

安易にinline-blockを使うなという戒めである。

ちなみにソースコードは以下。

<style>
body {
	background: #ededed;
	font-size: 14px;
}
div#column {
	width: 600px;
	margin: 0 auto;
	padding: 10px;
	background: #fff;
}

div#column h2.inline-block {
	display: inline-block;
	width: 300px;
	background: #FFBCBD;
	margin: 0 0 10px;
	font-size: 14px;
}

div#column h2.block {
	display: block;
	width: 300px;
	background: #FFBCBD;
	margin: 0 0 10px;
	font-size: 14px;
}

div#column h2.block span {
	font-weight: normal;
	font-size: 12px;
}

section {
	clear: both;

}

p {
	margin: 0;
}

div.boxL {
	display: block;
	width: 240px;
	float: left;
	background: #AFECFF;
}

div.boxR {
	display: block;
	width: 240px;
	float: left;
	background: #BFFFBD;
}

.clear {
	clear: both;
}

</style>


<div id="column">

<section>
<h1>想像していた表示</h1>
<h2 class="block">inline-blockでタイトル
<pre>
div#column h2.inline-block {
	display: inline-block;
	width: 300px;
	background: #FFBCBD;
	margin: 0 0 15px;
}
</pre>
<span>※表示のために、実際はdisplay: blockと書いています。</span>
</h2>

<div class="boxL">floatLボックス
<pre>
div.boxL {
	display: block;
	width: 240px;
	float: left;
	background: #AFECFF;
}
</pre>
</div>


<div class="boxR">floatRボックス
<pre>
div.boxR {
	display: block;
	width: 240px;
	float: left;
	background: #BFFFBD;
}
</pre>
</div>

</section>

<p class="clear">↓</p>


<section>
<h1>実際の表示</h1>
<h2 class="inline-block">inline-blockでタイトル
<pre>
div#column h2.inline-block {
	display: inline-block;
	width: 300px;
	background: #FFBCBD;
	margin: 0 0 15px;
}
</pre>
</h2>

<div class="boxL">floatLボックス
<pre>
div.boxL {
	display: block;
	width: 240px;
	float: left;
	background: #AFECFF;
}
</pre>
</div>


<div class="boxR">floatRボックス
<pre>
div.boxR {
	display: block;
	width: 240px;
	float: left;
	background: #BFFFBD;
}
</pre>
</div>
</section>


</div>

解決策は?

ちょっとあんまり良い方法ではないんだけれど、inline-blockがかかってる要素か、floatの要素どちらかを別のボックスで囲ってやればおk。
下記の例だとdivを余計にひとつ追加してます。

<section>
<h1>解決策1</h1>

<h2 class="inline-block">inline-blockでタイトル
<pre>
div#column h2.inline-block {
	display: inline-block;
	width: 300px;
	background: #FFBCBD;
	margin: 0 0 15px;
}
</pre>
</h2>

<div>
<div class="boxL">floatLボックス
<pre>
div.boxL {
	display: block;
	width: 240px;
	float: left;
	background: #AFECFF;
}
</pre>
</div>


<div class="boxR">floatRボックス
<pre>
div.boxR {
	display: block;
	width: 240px;
	float: right;
	background: #BFFFBD;
}
</pre>
</div>
</div>

</section>

 
 <section>
<h1>解決策2</h1>

<div>
<h2 class="inline-block">inline-blockでタイトル
<pre>
div#column h2.inline-block {
	display: inline-block;
	width: 300px;
	background: #FFBCBD;
	margin: 0 0 15px;
}
</pre>
</h2>
</div>

<div class="boxL">floatLボックス
<pre>
div.boxL {
	display: block;
	width: 240px;
	float: left;
	background: #AFECFF;
}
</pre>
</div>


<div class="boxR">floatRボックス
<pre>
div.boxR {
	display: block;
	width: 240px;
	float: right;
	background: #BFFFBD;
}
</pre>
</div>


</section>

[jQuery]$(document).readyと$(window).loadの違い[自分メモ]

今までずっとjqueryの実行タイミングをデフォで$(document).readyで書いてました。
今更こんな事書いたら、いろんなお客さんから怒られそうですが、今まで作ってきたjsアニメーションの実行のタイミングは何かをクリックしたら動かすといったような、必ずトリガーが何かしらあるものでした。

で、ちょうど今ページ読み込みと同時に動くアニメーション作っているのですが、PC環境だと問題なくてもスマホで問題があるんすよ。
wifiならまだしも、3G環境でただでさえ読み込みに時間がかかる状態で実行のタイミングが$(document).readyだと、スマホでデータの読み込みが終わった時点でアニメーションが終了しているという本末転倒な事態になる事が判明。

$(document).readyってなんぞ

DOMが読み込まれた時点で実行します。
htmlの構造が読まれた時って事だもんで、画像ファイルの読み込みを待たずにスクリプトの処理を開始します。

じゃあ$(window).loadってなにさ

DOM内に含まれる全ての要素の読み込みが完了した時点で実行します。
なので、今回の懸念である「3G回線」で画像の読み込み待ってる間にアニメーション終わっとるがな、という事態を解消するにはうってつけだったわけで。

ただ、調べている間に見つけたサイトには$(document).readyの方が良い的な事書いてあったので、$(window).loadはあまり推奨はされていないみたいですね。
うーん、もうちょっと勉強が必要だなぁ。

今気づいたけどもう2ヶ月もconcrete5に関する記事書いてないや…。

[CSSクイズ]構造を変えずにCSSだけでボックスの上下の順番を入れ替えられるのかッ!?

<div id="content">
  <div id="firstBox">
    <p>テキストテキストテキストテキスト</p>
  </div>
  <div id="secondBox">
    <p>テキストテキストテキストテキスト</p>
  </div>
  <div id="thirdBox">
    <p>テキストテキストテキストテキスト</p>
  </div>
</div>

例えば上記のHTMLがあったとして。
下記の図のように、#secondBoxと#thirdBoxの位置を入れ替えたいんですよ。

で、条件としては以下。

  • 各div内のテキスト量は不定。つまり高さは可変
  • HTML構造を変えてはダメ
  • CSSはいくらでもいじっても良し

なんだかんだでね、これ結構難しい問題だと思うんですよ。
解決策がない。
CSSクイズとか表題にしてるくせにさ、答えがないんですよ。

position: absolute使うにしても、ボックスの高さが不定だからtopもしくはbottomの値が定まらないし、同様にネガティブマージン使うにしても値が決まらない。
もう#thirdBoxにheight決め打ちしちゃってoverflow: hiddenかscrollでって事も考えた。

なんかどれもこれもスマートじゃない。スマートフォン向けに作ってるのに、全然スマートじゃない!!
あ、このフレーズいいな。今度から打ち合わせとかで使おう。「それ全然スマートじゃないですよね?スマートフォン向けなのに、全然スマートじゃないですよね?」って。

閑話休題。
で、結論としては、もうCSSだけじゃ解決できないよ私。
助けてjavascript〜!

こうすることにした。※cssの部分は結構省略して書いてます。

CSS

div#content {
  position: relative;
}
div#content div#secondBox {
  position: absolute;
}
div#content div#thirdBox {
  position: relative;
}

javascript

[javascript]
var fitstHeight =$(‘#firstBox’).height(); //高さを取得
var secondHeight =$(‘#secondBox’).height(); //高さを取得
var thirdHeight =$(‘#thirdBox’).height(); //高さを取得

$(‘#content’).css(‘height’, fitstHeight + secondHeight + thirdHeight); //#contentに中身のボックスの高さを合計した値を与える。
$(‘#secondBox).css(‘top’, fitstHeight + thirdHeight); //#secondBoxのtopからの位置を#firstBoxと#thirdBoxの合計した値を与える。
[/javascript]

でも、結局javascriptで解決するのも、なんだかちっともスマートじゃないですね。
この部分の解決策は多分、html原理主義者か、js信徒か、css教徒の三つどもえの論争が終わらないんじゃないかなぁと思います。

「君のやり方は間違っている!俺の解決方法はこれだッ!!」って思う人はご遠慮なさらずコメント欄へどうぞ。

疑似要素で種類の違うボーダーを引く

↑のh1見出しとか、サイドバーのh3に使ってるボーダーですが、今まで色の異なるボーダーの引き方がわからなくて、いつも背景画像を使っていました。

背景画像を使わずにCSSだけでなんとかしたかった。

で、天から聞こえて来た声が「:after使えばいいじゃない」。

#content article h1 {
    font-weight: bold;
    font-size: 150%;
    text-shadow: 0 0 2px rgba(6, 45, 124, 0.8);
    color: #fff;
    padding: 0 0 10px 0;
    border-bottom: 1px solid #aec5e1;
    margin: 0 0 10px 0;
}

#content article h1:after {
    border-bottom: 1px solid #5e8ec5;
    content: "";
    display: block;
    height: 1px;
    margin: 0 0 -10px;
}

:afterの時に、「content=””」と「height:1px」を入れないとそもそもレンダリングされなかったので、仕方なく入れました。
「margin: 0 0 -10px」は位置の調整用です。

wordpressのテーマをつくります。

予備知識ゼロでこれからwordpressのテーマをつくっていきます。

ちょっと触ってみた感想。

とりあえず新しいテーマを作ろうと思って、デフォルトで入ってたテーマをコピペしていじってみようと思ったら、テーマの説明文やら、作成者やらを記述したファイルが無かった。
こりゃいったいどういう事だと思って、全文検索掛けたらthemesの中のstyle.cssに書いてあった。

なんでテーマの説明文をcssに書かなきゃいけないのか全く持って理解不能。
これどういう理屈なのかなー。