20200104のCSSに関する記事は7件です。

herokuデプロイ 背景画像表示させる

記事投稿の理由

初めてherokuでデプロイした際に画像が表示されなくて苦しんだので
復習兼ねて記事書かせていただきます。
環境によって違う場合もある。参考程度にみてくださると幸いです。

今回のテーマと環境

rails 5.0.7.2

herokuでデプロイはできていて
画像のみが表示されないと仮定します。

変更箇所

assetファイルは事前にコンパイルしておきます。
しかしassetファイルが見つから無い場合にtrueにしておくとサーバー側でコンパイルしてくれるそうです。
ただし、コンパイルによりサーバー側の負荷も上がるのでここは環境によって変わると思います。

今回私の場合はconfig.assets.compile = falseのところをtrueに変更して対応しました。

production.rb
# Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = true

config.assets.css_compressor = :sassのコメントアウトを外して
私の場合scssファイルで色付けなど行なっていたため
config.assets.css_compressor = :scssに変更

production.rb
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :scss

背景画の設定しているところを
background-image: url("china.jpg");から下記に変更

index.scss
.contact{
  background-image: image-url("china.jpg");

asset_pathの追加
<img src="freemarket.png" alt="制作事例1" width=500px height=280px>を下記に変更

index.html.erb
<li class="portfolio">
        <a href="http://18.177.66.99/" class="portfolio-image">
          <img src="<%= asset_path "freemarket.png" %>" alt="制作事例1" width=500px height=280px >
        </a>
      </li>

あとherokuにファイル送付する前に開発環境のコンソールにて下記忘れないように。。

$ rake assets:precompile RAILS_ENV=production

最後に

僕はこのような方法でデプロイした際にうまく画像が表示されるようになりました。
環境によっても違うと思いますが参考になれば・・・・

参考にさしていただいたサイト

Rails4 asset pipeline関連設定まとめ
Rails4ではbackground:url("assets/hoge.png")の書き方は動かない話
Rails初学者がつまずきやすい「アセットパイプライン」
HerokuにRubyのデータをデプロイ後、画像が見れない

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

HTML

本日が初投稿です。
学習したことをメモ書き程度に書く場にしようと考えております。
多めに見てやってくださいm(__)m

HTMLとは

静的なwebサイト作成に使用される「マークアップ言語」の一つです。タグを使いテキストを囲むことで、「見出し」や「リンク」を作成することができます。

タグの例

<開始タグ>こんにちは</終了タグ>

このように入力すると画面上に「こんにちは」と表示される。

タグの種類
|タグ|意味|
|:--|--:|
|h1~h6|見出し|

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

HTML学習

本日が初投稿です。
学習したことをメモ書き程度に書く場にしようと考えております。
多めに見てやってくださいm(__)m

HTMLとは

静的なwebサイト作成に使用される「マークアップ言語」の一つです。タグを使いテキストを囲むことで、「見出し」や「リンク」を作成することができます。

タグの例

<開始タグ>こんにちは</終了タグ>

このように入力すると画面上に「こんにちは」と表示される。
終了タグの前には必ず「/」を入力する。

主なタグ

h1~h6→見出し
a→リンク
p→段落

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

HTML&CSS学習

本日が初投稿です。
学習したことをメモ書き程度に書く場にしようと考えております。
多めに見てやってくださいm(__)m

HTMLとは

静的なwebサイト作成に使用される「マークアップ言語」の一つです。タグを使いテキストを囲むことで、「見出し」や「リンク」を作成することができます。

タグの例

<開始タグ>こんにちは</終了タグ>

このように入力すると画面上に「こんにちは」と表示される。
終了タグの前には必ず「/」を入力する。

主なタグ

h1~h6→見出し
a→リンク
p→段落

CSSとは

HTMLで作成したファイルをデザインするためのファイルのこと。画面上で反映させるために、「link ren="stylesheet" href="cssファイル名"」をHTMLファイルのheadタグ内に記述している必要がある。

書き方

例;
h1{
(場所)
color : #ff0000
何を:どうする;
(色を:赤色にする)

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

グラデーションの上に画像と文字を表示

グラデーションの上に画像と文字を表示

学習した内容のアウトプットをしてこなかったので、
まずはメモ程度の内容からの投稿です。

やりたいこと

以下のような画像があるとして、矢印で示した要素で表現したい。
(SAMPLEの部分もテキストでいいのでは?というのもあるが、
本来の画像ではこのSAMPLEの部分がロゴマークだったので。。。)
sample.png

どのように書いたか

sample.html
<div class="header-banner">
  <p class="title-en">subtitle</p>
  <p class="title-jp">メインタイトル</p>
</div>
style.css
.header-banner {
  position: relative;
  max-width: 800px;
  width: 100%;
  height: 75%;
  margin: auto;
  margin-bottom: 8px;
  padding: 50px 0 50px 0;
  z-index: 0;
  background: url(logo.png), linear-gradient(45deg, #edbdc5, #872434);
  background-repeat: no-repeat;
  background-position: 5% 10%;
  background-size: contain; 
}
  .header-banner:before {
    content: "";
    display: block; 
}
  .header-banner p {
    text-align: center;
    color: white;
    transform: translate(-50%, -50%);
    text-shadow: 4px 4px 5px #000000;
    z-index: 2;
    width: 100%; 
}
  .header-banner p.title-en {
    font-size: 2.5vmin;
    position: absolute;
    top: 25%;
    left: 50%;
    margin: 0;
    padding: 0; 
}
  .header-banner p.title-jp {
    font-weight: bold;
    font-size: 6vmin;
    position: absolute;
    top: 65%;
    left: 50%;
    margin: 0;
    padding: 0; 
}

今回のポイント

グラデーションの前面に画像を配置するには工夫が必要です。

gradationAndPic.css
background: url(表示対象画像), linear-gradient(グラデーション方向, 開始色, 終了色);

まずはここまで。

参考

CSSのグラデーション(linear-gradient)の使い方を総まとめ!
MDN

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

初心者によるプログラミング学習ログ 203日目

100日チャレンジの203日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

203日目は

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

R qgraphでspring-embeddedレイアウトのグラフを描く

Rqgraphを使って、下図のようなspring-embeddedレイアウトのネットワーク図を書く方法の備忘録です。
qgraph-spearman_sample_w400.png
題材は、自分がこれまでコーディングしたCSSファイルをanalyze-cssで解析したメトリクスデータを集めたもの。メトリクスの相関の強さをqgraphで表してみました。

動作環境および必要なソフトウェア
バージョンは本記事執筆時点で使用しているもの

第1章 分析用のデータを集める

analyze-cssは、CSSファイルを解析してルール記述やセレクタの個数などの情報を出力してくれるコマンドラインツールです。ver.0.12.7現在、37種類のメトリクスがサポートされています。

analyze-cssの使い方

npmでインストールします。

$ npm install --global analyze-css

計測したいCSSファイルのパス名を引数に指定してanalyze-cssを実行すると、解析結果がJSON形式で標準出力に書き出されるので、リダイレクトして適当なファイルに保存します。引数--prettyを指定すると、項目ごとに改行とインデントが付いて読みやすい形式になります。

$ analyze-css --pretty --file examples/style.css > style.json

JSONをCSV形式に変換

Rで処理しやすくするため、ファイルのフォーマットをJSON形式からCSV形式に変換します。pythonを使うと簡単です。抽出する項目はキー"metrics"が保持するデータだけです。

css-metrics.py
import json
import sys

args = sys.argv
if len(args) < 2:
    sys.exit('usage: python %s json_file' % args[0])

with open(args[1], 'r') as f:
    jsn = json.load(f)
    for key in jsn['metrics']:
        print(key + ',' + str(jsn['metrics'][key]))

jsonファイルを1つのフォルダに集め、一括してCSV形式に変換します。

$ ls json/
project1.json   project2.json   project3.json

以下のシェルスクリプトを実行すると、同じフォルダに拡張子.csvのファイルが出来ます。

mkcsv.sh
#!/bin/bash

for i in $(find json -name '*.json' -print)
do
  echo $i
  outf=${i%.*}.csv
  echo "metrics,value" > $outf
  python css-metrics.py $i | sort >> $outf
done
$ ls -p
css-metrics.py  json/       mkcsv.sh
$ ./mkcsv.sh 
$ ls json
project1.csv    project2.csv    project3.csv
project1.json   project2.json   project3.json

バラバラのCSVファイルを1個のCSVファイルに統合します。その際、1行目に列見出し、2行目以降にデータ行が追加されるようにしたいので、Pythonを使って元のデータ(metrics,valueの2列構成)の行と列を転置して出力します。また、1列目には、ファイル名から抽出したプロジェクト名を挿入し、見出しをprojectに書き換えます。

csv-transpose.py
import csv
import sys
import os

hdr = False
args = sys.argv
usage = 'usage: python %s csv_file [ H ]' % args[0]
if len(args) < 2:
    sys.exit(usage)
if len(args) > 2:
    if args[2] == 'H':
        hdr = True
    else:
        sys.exit(usage)

basename = os.path.basename(args[1])
tpl = os.path.splitext(basename)
projname = tpl[0]
key_list = []
val_list = []

with open(args[1], 'r') as f:
    reader = csv.reader(f)
    header = next(reader)
    key_list.append('project')
    val_list.append(projname);
    for row in reader:
        key_list.append(row[0])
        val_list.append(row[1])
    if hdr == True:
        print(','.join(key_list))
    print(','.join(val_list))

以下のシェルスクリプトを走らせてフォルダ内のCSVファイルを一括して変換し、結果の標準出力をファイルに保存します。

merge-list.sh
#!/bin/bash

hdr=H
for i in $(find json -name '*.csv' -print)
do
  python csv-transpose.py $i $hdr
  hdr=
done
$ ls -p
css-metrics.py      json/           mkcsv.sh
csv-transpose.py    merge-list.sh
$ ./merge-list.sh > css-metrics-data.csv

保存したCSVファイルを表計算アプリで開いて、正しく変換できたか確認します。これでRに読み込ませるデータが準備できました!
csv-convert_w1000.png

第2章 Rにデータを読み込んでqgraphでグラフを描く

以下、[R]で始まる見出しは「RのTips」、[qgraph]で始まる見出しは「qgraphのTips」のつもりで書いてあります。Tipsとして読めるよう、分析の詳細については(退屈ですし)端折ってます。

[R] データフレームの作成: CSVファイルの読み込み

Rを起動し、Rコンソールから以下のコマンドを入力して、前節で作ったCSVファイルをデータフレームに読み込ませます。

df <- read.table("css-metrics-data.csv", header=T, sep=",")

[R] データフレームから列を削除(その1)

データの相関関係の分析にはスピアマンの順位相関係数を使います。dfには、相関係数の算出に向かない列も含まれているため、事前に取り除いておきます。たとえば以下のような列は不要なので削除します。

  1. 1列目の見出し(プロジェクト名)
  2. 値が全部ゼロ
  3. 値が全部同じ(ゼロ以外)
  4. 値が0と1しかない(値のばらつきがほとんどない)

項目1〜3については以下のコマンドで対応します。df[,-1]は1列目を除く列、colSums(df) != 0は列の和が0でない(オール0でない※)列のみTRUE、apply(df, 2, var) != 0は分散が0でない(値が均一でない)列のみTRUEになることを利用して、dfの該当列のみ抽出しています。
※測定値が0以上であることが前提

df <- df[,-1]
df <- df[colSums(df) != 0]
df <- df[apply(df, 2, var) != 0]

項目4については、以下のコードのように関数is.bin()を定義し、引数に与えたベクトルxの要素の集合(重複なし)が{0, 1}に等しいかどうかを判定します。データフレーム dfからis.bin()がTRUEになる列を除外して、dfを置き換えます。

is.bin <- function(x) {
   return(setequal(unique(x), c(0,1)))
}
df <- df[!apply(df, 2, is.bin)]

[R] スピアマンの順位相関係数の算出

相関係数の算出には関数cor()を使います。dfのすべての列の組み合わせに対して、スピアマンの順位相関係数を計算した結果を変数vに保存します。

v <- cor(df, method="spearman")

[qgraph] springレイアウトのグラフ作成

ここまでの状態で一旦グラフを描いてみましょう。まずqgraphパッケージをインストールします。依存するパッケージが芋づる式に多数インストールされるため少々時間がかかります。

install.packages("qgraph")

qgraphパッケージをロードしてみて、正しくインストールできたことを確認します。

> library(qgraph)
Registered S3 methods overwritten by 'huge':
  method    from   
  plot.sim  BDgraph
  print.sim BDgraph

qgraphパッケージをロードした後、関数qgraph()に順位相関係数のベクトルvを渡して、springレイアウトでグラフを描かせます(下図)。

qgraph(v, minimum=0.7, layout="spring")

qgraph-spearman_01_w1000.png
グラフの各ノードが、変数vの各要素つまりメトリクスを表します。ノードのラベルはメトリクス名を3文字に省略した文字列です。
例:sBC = selectorsByClass
ラベル名と元のメトリクス名をグラフの凡例に表示する方法は後述します。

ノードどうしを結ぶ辺は相関の強さを表します。線が太く・色が濃いほど相関が強いことを示しています。qgraph()は、デフォルトでは全ノードのすべての組み合わせに対する相関関係の辺を描画しますが、変数が多くビジーすぎるので、qgraph()に引数minimum=0.7を指定することにより、相関係数が0.7以上の辺のみをグラフに表示させました。

[R] データフレームから列を範囲で抽出

sBT (selectorsByTag) とsTT (specificityTagTotal) など、CSSセレクタの詳細度に関するメトリクスを表すノードと、セレクタの個数を表すノードはどちらも同じ要素を計数しているため、両者の増減が連動し相関が強く出るのは当然なので、両方をグラフに入れると冗長だと判りました。そこで、データフレームから詳細度に関するメトリクスspecificity* の列を削除します。

データフレームの列名を確認するには関数colnames()を使います。

> colnames(df)
 [1] "colors"                       "comments"                     "commentsLength"                   
 .....    
[19] "selectorsById"                "selectorsByPseudo"            "selectorsByTag"              
[22] "specificityClassAvg"          "specificityClassTotal"        "specificityIdAvg"            
[25] "specificityIdTotal"           "specificityTagAvg"            "specificityTagTotal"     

specificity* の列はインデックス22以降に集まってますので、列1〜21までを抽出してdfを書き換えます。

df <- df[1:21]

[R] データフレームから列を削除(その2)

このほか、ノードimp (imports) と emR (emptyRules) から出ている辺も、元のデータの偏りから生じたノイズだと判ったため(CSSの作りからして本来無関係)、これらもデータフレームから削除することにします。

データフレームから列を名指しで除外するには、列名の集合に対して関数setdiff()を利用します。

df <- df[setdiff(colnames(df), c("emptyRules", "imports"))]

[qgraph] グラフの書式を調整

グラフに凡例を追加し、ノード間の辺に相関係数の値を表示し、文字の大きさを調整します。

v <- cor(df, method="spearman")
qgraph(v, minimum=0.7, layout="spring", repulsion=0.6,
    legend=T, nodeNames=names(v[,1]), legend.cex=0.5,
    edge.labels=T, edge.label.cex=0.5,
    label.cex=0.8)

qgraph-spearman_04_final_w1000.png

qgraph()の引数に追加した項目は以下のとおりです。

repulsion=0.6
1より小さくすると、ノードの“島”どうしの間隔が近くなり、個々の島の占める領域が広がります。ノードが密集している部分のノード間の辺が長く表示されて、結合状態がよく見えるようになります。

legend=T, nodeNames=names(v[,1]), legend.cex=0.5
グラフの右側に凡例を表示します。nodeNamesは、ノードのラベルに対するフルネームのベクトルを指定します。この例では、関数cor()の戻り値を保存した変数vに入っている列名のリストをv[,1]により取り出しています。凡例の文字列の拡大率を0.5に設定します。

edge.labels=T, edge.label.cex=0.5
辺にラベル(相関係数の値)を表示し、ラベル文字列の拡大率を0.5に設定します。

label.cex=0.8
ノードのラベル文字列の拡大率を0.8に設定します。

[qgraph] ノードをグループ化して色分けする

グラフのノードを以下の4つのグループに分けて、それぞれノードに色をつけてみましょう。

グループ 意味 ノード
A #FF4081 CSSの保守性に関わる指標 lng, sLA
B #A1887F CSSの構成要素の計数 clr, dcl, mdQ, rls, slc, sBC, sBI, sBP, sBT
C #2196F3 複雑な構造の計数 cmS, dpP, dpS, mcS, qlS, rCN
D #BDBDBD その他 cmm, cmL

まず、qgraph()の引数に渡すデータを準備します。ノードのラベルに対応する列名をcolnames(df)から調べ、そのインデックスをノード番号としてc()を使ってグループごとのベクタを作成します。4個のグループに対するベクタを要素とするリストをlist()を使って作成し、変数groupsに保存します。

グループの配色は、RGB値#...や色名の配列で指定し、変数colorに保存します。配列の要素1がgroupsリストの要素1に対応します。

groups <- list(c(8,14), c(1,5,9,13,15,16,17,18,19), c(4,6,7,10,11,12), c(2,3))
color <- c("#FF4081", "#A1887F", "#2196F3", "#BDBDBD")

qgraph()に引数groups=groupscolor=colorを渡すとグラフのノードが塗り分けられます。以下のコードではlabel.colorでラベルの文字列の色を指定し、borders=Fでノードの境界線を非表示にしました。ただし、凡例左側の小さな円の境界線はborders=Fでは消えません。対策として、border.color="white"も指定して凡例側の円を若干見やすくしました。

qgraph(v, minimum=0.7, layout="spring", repulsion=0.6,
       legend=T, nodeNames=names(v[,1]), legend.cex=0.5,
       edge.labels=T, edge.label.cex=0.5, label.cex=0.8,
       groups=groups, color=color,
       label.color="white", borders=F, border.color="white")

qgraph-spearman_05_groups_w1000.png
これでグラフが完成しました!

#FF4081のノードと#2196F3のノードの関係を見て、私が書いていたCSSはセレクタの指定が複雑になる傾向にあることが判りました。確かに、analyze-cssの出力jsonファイルには、.foo .bar .baz pみたいにdivの階層辿るようなセレクタを使ってる箇所が多く報告されていました1。このようなセレクタは詳細度が無駄に上がってしまい、media queryの中などでCSSプロパティを上書きしたい時、セレクタを元と同じ形式かそれ以上の詳細度で指定しなければならず、メンテナンスしにくいCSSになる要因ですね。

[R] 箱ひげ図が付いた散布図の描き方

おまけとして、散布図のX軸とY軸の外側に箱ひげ図が付いた下図のようなグラフをRで描く方法です。このグラフは、CSSのlng (length) と sLA (selectorLengthAvg) のデータの分布をプロットしたものです。2本の赤い線はそれぞれlngとsLAの中央値を示します。
scatterplot_06_w450.png

箱ひげ図が付いた散布図は、carパッケージの関数scatterplot()で簡単に描けます。

install.packages("car")

以下のコードではcarパッケージをロード後、par()でグラフィックスパラメータを退避・更新してから、scatterplot()を呼び出します。さらに、関数abline()でX, Y軸に平行な直線を引き、最後にグラフィックパラメータを元に戻しています。グラフィックスパラメータを更新した理由は、箱ひげ図の外側に余白を入れたいので、par(oma=...)を呼んで作図領域の底辺と左辺にマージンを設定するためです。

library(car)

oldpar <- par(no.readonly=T)
oma <- c(2,2,0,0)
par(oma=oma)

scatterplot(df$length, df$selectorLengthAvg,
    smooth=F, regLine=F, grid=F,
    xlab="length", ylab="selectorLengthAvg",
    pch=16, cex=1.5, reset.par=F)

abline(v=median(df$length), col="red")
abline(h=median(df$selectorLengthAvg), col="red")

par(oldpar)

lngとsLAが共に大きいグループ=赤い線で区切られた右上の領域=にプロットされたプロジェクトは、ページ制作当時、ハマりまくったものばかりなので、生産性の悪さ加減がグラフに現れてるなと納得しました(苦笑)


  1. コーディングを始めた頃、既存サイトに下層ページを追加する案件を担当していて、手本にした既存のCSSが#product .foo ul.bar li {...}みたいに冗長なセレクタを多数使用していたのに倣ったのがいけなかった。 

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