• LESSでCSSを書いてみた

    CSSのメンテナンス性の悪さは広く知られて居るとは思いますが、その解決策として、SASSとかSCSSなどがあります。今回はその仲間のLESSの導入記録です。

    公式サイト:LESS « The Dynamic Stylesheet language

    LESSというのは、CSSのメタ言語で、コレをコンパイルすると、CSSが出力されます。
    LESSを使うとこんなことが出来ます。

    LESSを使うと出来ること

    • ルールのネスト
    • 変数
    • Mixin
    • 四則演算などちょっとした関数

    また、普通のCSSの記法も使えますので、リセット用のCSS等そのままコピペも可能です。

    ルールのネスト(階層化)

    CSSのルールをネスト出来ます。いちいちセレクタをコピペしなくていいし、コードの視認性や、構造が非常にわかりやすくなります。親のセレクタを再利用するには、”&”を用います。

    less
    [css]
    #header {
    h1 {
    font-size: 26px;
    font-weight: bold;
    }
    p { font-size: 12px;
    a { text-decoration: none;
    &:hover { border-width: 1px }
    }
    }
    }
    [/css]

    css
    [css]
    #header h1 {
    font-size: 26px;
    font-weight: bold;
    }
    #header p {
    font-size: 12px;
    }
    #header p a {
    text-decoration: none;
    }
    #header p a:hover {
    border-width: 1px;
    }

    [/css]

    変数

    css内で変数が使えます。色などの一括管理などにはかなり便利です。

    less
    [css]
    @color: #4D926F;

    #header {
    color: @color;
    }
    h2 {
    color: @color;
    }
    [/css]

    css
    [css]
    #header {
    color: #4D926F;
    }
    h2 {
    color: #4D926F;
    }
    [/css]

    Mixin

    Mixinっていうと難しく聞こえますが、他のプロパティ内で、読み込んで使えるプロパティのまとまりを作る事ができるということです。

    [css]
    .hoge(){
    color: #FFF;
    background-color: #000;
    }
    [/css]
    でMixin用のプロパティを作成できます。このプロパティ自体はCSSに出力されません。また変数なども入れることも出来ます。

    less
    [css]
    .rounded-corners (@radius: 5px) {
    border-radius: @radius;
    -webkit-border-radius: @radius;
    -moz-border-radius: @radius;
    }

    #header {
    .rounded-corners;
    }
    #footer {
    .rounded-corners(10px);
    }
    [/css]

    css
    [css]
    #header {
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    }
    #footer {
    border-radius: 10px;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    }
    [/css]

    clearfixとかをMixinすると便利だったりします。

    ちょっとした計算など

    四則演算や、色を10%明るくするだとか、地味に便利な関数が用意されています。

    less
    [css]
    @the-border: 1px;
    @base-color: #111;
    @red: #842210;

    #header {
    color: @base-color * 3;
    border-left: @the-border;
    border-right: @the-border * 2;
    }
    #footer {
    color: @base-color + #003300;
    border-color: desaturate(@red, 10%);
    }
    [/css]

    css
    [css]
    #header {
    color: #333;
    border-left: 1px;
    border-right: 2px;
    }
    #footer {
    color: #114411;
    border-color: #7d2717;
    }
    [/css]

    他のLESSファイルのインポート

    [css]
    @import "reset.less";
    @import "reset";
    [/css]
    とすることで、reset.lessが展開されます。lessファイルの場合、拡張子を省いても大丈夫です。

    結構ざっくりとした説明ですので、詳細は:lesscss.orgの方を参照して下さい。英語ですがコードを眺めていればだいたいつかめると思います。

    導入について

    公式サイトでは、less.jsで、ブラウザでコンパイルをさせています。
    [html]
    <link rel="stylesheet/less" type="text/css" href="styles.less">
    <script src="less.js" type="text/javascript"></script>
    [/html]
    こんな感じです。ソースのhead内にcssを展開します。
    簡単にできますが、かなりブラウザに負荷がかかるので、おススメできません。制作中等限定で使用したほうが良いかと思います。

    なので、Macの場合、公式アプリのless.appを活用しましょう。コレは、登録されたlessファイルが更新されたときに自動的にcssファイルを作成してくれるソフトです。特定のディレクトリ内lessファイルを検索もしてくれるので、開発用のディレクトリを指定しておくとかなり簡単です。自分の場合はコレをログイン時に起動するようにしています。

    windowsの場合はmach3さんがlessniumというアプリケーションを作成していますので、それが便利だと思います。>>TitaniumデスクトップでLESS.jsのフロントエンドをこさえてみた
    なお、Lessniumには、Titaniumが必須です。

    また、Node.jsなどでも動作しますので、そちらは公式サイトを参照して下さい。

    LESSを使うと、CSSの管理等が、非常に楽になりますし、効率良くCSSを書いていく事ができます。SASSとかSCSSとか多機能なものもありますが、LESSは学習コストが低いのとコンパイルの手間が少ないので、試してみてはどうでしょうか。

    LESS « The Dynamic Stylesheet language

  • Add New Category Post 0.5.1をリリースしました。

    Add New Category Post 0.5.1をリリースしました。
    ダウンロード:add-new-category-post-0.5.1

    @Toro_Unit 「投稿編集」「クイック編集」から更新した際にカテゴリのチェックが外れてしまします。チェックを入れて更新しても全て解除された状態となります。ご検証よろしくお願いします。less than a minute ago via web Favorite Retweet Reply

    どいさんから、報告をいただいていた、クイック投稿時にカテゴリー指定が無効になってしまうというバグを修正したものです。いつもありがとうございます。

  • Add New Category Post をアップデートしました。

    先日リリースした、Add New Category Postをアップデートしました。
    主にJavaScript周りの修正をしています。

    @Toro_Unit Add New Category Postプラグインですが、「新規投稿を追加」ページ以外だとCurrent Menu表示部分でスクリプトエラーが出るようですのでご検証頂けますでしょうか。less than a minute ago via web Favorite Retweet Reply

    という報告をいただいていましたが、修正されていると思います。一応Mac OS X 10.6 Firefox5 とChromeで確認しています。

    @show_webさんありがとうございました。

    ダウンロード:Add New Category Post Ver.0.5

  • WordPressのサイドメニューに『カテゴリ別の新規追加』を追加をするプラグインを作りました。

    2011-11-15追記:最新情報はこちらからご確認ください。Category Post

    WordPress案件でカスタム投稿にしようかカテゴリでやっつけようかって悩む時が有るのですが、
    カテゴリの方が、投稿一覧とかで全部見れたり、WP_Queryやquery_posts()とかで持ってくるとき、楽だったりしますよね。
    ただ、お客さんに『このカテゴリーにチェックしてください』とかいろいろ運用マニュアル的な解決も結構面倒だったりします。

    カテゴリーを指定して投稿画面ができたら便利かなと思って作りました。

    とりあえず、開発はWordPress3.2.1+Firefox5+MacOS X 10.6でやっています。WordPress3以降で動作はすると思います。あとでちゃんとチェックします。

    Add New Category Post

    という名前のプラグインです。
    ダウンロード:add-new-category-post

    インストール・アンインストール

    wp-content>pluginsの中に展開したファイルをアップロードしてください。アンインストールするときは、特にデーターベース等を触りませんので、無効にしてサーバーから削除するか、WordPressの管理画面から削除してください。

    機能

    管理画面のサイドメニューの投稿の“新規追加”を削除し、カテゴリーごとの新規追加を追加します。『未分類を追加』みたいな感じになります。記事の最初のスクリーンショットみたいな感じです。
    また、カテゴリ別投稿のときは、投稿画面のカテゴリー一覧も非表示にしています。

    もとからある新規追加を消したくない場合は、プラグインファイルを開いて、
    [php]
    remove_submenu_page( "edit.php", "post-new.php" );
    [/php]
    をコメントアウトしてください。

    ツッコミとかあれば頂ければ嬉しいです&助かります。

  • さくらのレンタルサーバーでディレクトリの中身を見せないようにする

    さくらのレンタルサーバーでは、デフォルトでは、indexesが有効になっています。

    しかし、htaccessにoptionsが記述できません。
    [plain]
    Options -Indexes
    [/plain]
    なんて記述をすると、500 Internal Server Errorになってしまいます。

    それを回避しつつ、ディレクトリの中身を見せないようにするには、

    さくらのレンタルサーバ非公式FAQによると、

    [plain]
    DirectoryIndex index.html .ht
    [/plain]

    としてやると良いらしいです。index.phpも欲しい時は、

    [plain]
    DirectoryIndex index.php index.html .ht
    [/plain]

    とします。DirectoryIndexは左に書いてあるものを順番に探して、見つかったものを表示しますので、

    [plain]
    DirectoryIndex index.php index.shtml index.cgi index.pl index.html .ht
    [/plain]

    としてやれば問題ないようです。

  • ユーザーエージェントでブラウザの判別をするPHPとかjQueryを書いてみた。

    自分でコピペできるように、browser判別のTipsを貼っておきます。

    PHPで判別

    [php]
    function browser_class(){
    $classes = "";
    $agent = getenv( "HTTP_USER_AGENT" );

    if(strstr($agent,"MSIE")){
    $classes .= "msie ";
    if(strstr($agent,"MSIE 6.0")) $classes .= "ie6 lt7 lt8 lt9";
    if(strstr($agent,"MSIE 7.0")) $classes .= "gt6 ie7 lt8 lt9";
    if(strstr($agent,"MSIE 8.0")) $classes .= "gt6 gt7 ie8 lt9";
    if(strstr($agent,"MSIE 9.0")) $classes .= "gt6 gt7 gt8 ie9";
    }
    else {
    $classes .= "noie ";
    if( strstr($agent,"Firefox")) {
    $classes .= "firefox gecko";
    }
    elseif( strstr($agent,"Safari")) {
    $classes .= "safari webkit";
    }
    elseif( strstr($agent,"Chrome")) {
    $classes .= "Chrome webkit";
    }
    elseif( strstr($agent,"Opera")) {
    $classes .= "opera presto";
    }
    //ここからは気休め。
    //AppleWebKit/534.30 (KHTML, like Gecko) なので先に記述
    elseif( stristr($agent,"WebKit")) {
    $classes .= "webkit";
    }
    //AppleWebKit/534.30 (KHTML, like Gecko) なので先に記述
    elseif( stristr($agent,"KHTML")) {
    $classes .= "khtml";
    }
    elseif(stristr($agent,"Gecko")) {
    $classes .= "gecko";
    }else {
    $classes .= "other";
    }
    }
    return $classes;
    }
    [/php]

    ついでにwordpressのbody_classに追加するなら、
    [php]
    function add_browser_class($classes){
    $classArr = explode(" ",browser_class());
    $return = array_merge($classes,$classArr);
    return $return
    }

    add_filter("body_class","add_browser_class");
    [/php]

    とかやればうまく行ける気がします。

    jQueryで判別

    参考:
    jQuery.supportでのブラウザ判別
    http://w3g.jp/blog/tools/jquery_browser_sniffing

    [js]
    jQuery(function($){

    $html = $("html");

    if(!$.support.checkOn && $.support.checkClone){
    $html.addClass("webkit noie");
    }else if($.support.checkOn && $.support.noCloneEvent && window.globalStorage){
    $html.addClass("firefox noie");
    }else if($.support.checkOn && $.support.noCloneEvente && !window.globalStorage){
    $html.addClass("opera noie");
    }else if(!$.support.noCloneEvent && $.support.opacity){
    $html.addClass("gt6 gt7 gt8 ie9 msie");
    }else if(!$.support.opacity){
    if(!$.support.style){
    if (typeof document.documentElement.style.maxHeight != "undefined") {
    $html.addClass("gt6 ie7 lt8 lt9 msie");
    } else {
    $html.addClass("ie6 lt7 lt8 lt9 msie");
    }
    }else{
    $html.addClass("gt6 gt7 ie8 lt9 msie");
    }
    }else{
    $html.addClass("other");
    }
    });
    [/js]

  • jQueryのキュー(queue)って何なんですか・・・?

    jQueryで、CSSを操作して、アニメーションをしたい時があると思います。
    そんなときはたいてい、

    [js]
    $("#box1").css({color:"#F00"}).animate({left:"300px"},4000);
    [/js]
    の様なscriptを書くと思います。

    また、
    “アニメーションしてから、文字色変えたい!!”
    なんてことはよくあると思います。
    そして、きっと僕みたいな人は、こんなコードを想像するわけです。
    [js]
    $("#box2").animate({left:"300px"},4000).css({color:"#F00"});
    [/js]

    しかし、現実は、こちらのデモのように、CSSが操作されてから、アニメーションをしてしまうのです。一番最初の例と全く変わらない動作をしてしまいます。

    現実というのは時に残酷ですね。

    実は、jQueryのanimateというメソッドは「アニメーションをしなさい」という命令ではなく、
    「アニメーションをキューに登録しなさい!」
    という意味なのです。
    キュー、queueは平たく行ってしまうと、アニメーション等の台本みたいなもので、キューに溜まっている処理は上から順番に処理されます。

    jQueryにはたくさんのメソッドがありますが、大きく分けると、css()等のCSS操作、append()等のDOM操作その他、キューを使わないメソッドと、animate()やfadeIn()、fadeOut()、fadeTo()、等キューを使うメソッドに分かれます。ついでに言うなら、stop()はキュー上の処理の停止をするメソッドなのです。

    キューを使うメソッドは基本的にはアニメーション等の処理に時間を設定するものがほとんどだと思います。ちゃんと本家のリファレンスを隅まで熟読したわけではないのでちょっとあれですが・・・

    こんな時、一つは、callbackを使えば解決できます。

    animate等のcallbackを使う

    [js]
    $("#box3").animate({left:"300px"},4000,function(){
    $(this).css({color:"#F00"});
    })
    [/js]
    しかし、いまいちスマートじゃないですし、メソッドチェーンをここからつないでいくのは可読性的に宜しくない気がします。昔これでネストさせすぎてよく分からないコードになってしまったことがあったりなかったり・・・

    そこで、queue(callback)を使います。

    queue(callback)を使う

    [js]
    $("#box4").animate({left:"300px"},4000).queue(function(){
    $(this).css({color:"#F00"}).dequeue();
    });
    [/js]

    としてあげると、これもちゃんと動作します。
    これを使う一番のメリットとしては、delay()等のメソッドが使えるということです。

    dequeue()について

    また、ここでdequeue()という見慣れないメソッドが出てきました。dequeue()はキューに溜まっている先頭の処理を実行するというメソッドです。
    通常、キューを使わないメソッドには、次の処理を実行する機能がありません。
    こちらのデモを見てもらうとわかると思いますが、dequeueしていない#box1の方は最後のanimate()が実行されずに停止しています。

    animate()などは、dequeue()を勝手にやっているのですが、css()等はそういうわけにもいかないので、最後には必ず、
    [js]
    $(this).dequeue();
    [/js]
    を追加しておきましょう。お行儀みたいなものですね。

    これでみんなも立派なjQueryアニメーター、デビュー!

    jQueryはとても手軽で便利でハードルが低いですが、ちょっと突っ込んだことをして躓くと逆にjQuery流で解決しないといけない気がするものなのでちょっと面倒ですね。
    まぁフレームワークなど、高度に抽象化されたものにはどうしても付いて回るものなのだとは思いますが、ちゃんと一度はソースを読んで理解しておきたいですね。僕は全くやれていないですが・・・

  • ie9.jsを使うと出来ること、出来なくなること。

    最近ie9.jsを活用することが少々あるので、
    いまさらながらまとめです。

    配布場所

    ie7-js
    http://code.google.com/p/ie7-js/で配布されています。

    デモはhttp://ie7-js.googlecode.com/svn/test/index.htmlで見れます。

    使い方

    head内に
    [html]
    <!–[if lt IE 9]>
    <script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
    <![endif]–>
    [/html]
    と貼り付けるだけです。フッターに貼ると誤作動起こす場合がたまに合ったような気がします。

    できるようになること

    E > F
    子セレクタ。直下の子要素にのみ適応するやつ。
    E + F
    隣接兄弟セレクタ。Eのすぐ下隣に居る弟要素。
    E ~ F
    間接セレクタ。E以降の弟要素全て。
    .class1.class2
    クラスの重複指定
    :hoverの修正
    a以外にも効くようになります。
    [attr],[attr=”value”],[attr~=”value”],[attr|=”value”],[attr^=”value”][attr$=”value”],[attr*=”value”]
    属性セレクタ全般
    :before,:after
    擬似要素。
    :checked,:disabled,:empty,:enabled,:indeterminate,:first-of-type,:last-child,:last-of-type,:not(),:nth-child(),:nth-last-child(),:nth-last-of-type(),:nth-of-type(),:only-child,:only-of-type,:root,:target
    CSS3の擬似クラス
    opacity
    透明度がfilter要らずで効くようになります。もちろん内部的にはfilterを使っているのですが。
    article, aside, audio, canvas, details, figcaption, figure, footer, header, hgroup, mark, menu, meter, nav, output, progress, section, summary, time, video
    HTML5で追加された要素にCSSが当たるようになる。html5.jsとかhtml5shiv.jsを同時に読み込む必要はありません。
    透過PNGへの対応
    ファイル名をhoge-trans.pngにすると動作します。
    もしくは、
    [js]
    var IE7_PNG_SUFFIX = ".png";
    [/js]
    とすると全てのPNGに対して有効になります。

    出来なくなること。注意すべきこと。

    まぁ便利なのですが、そうそう美味いだけの話というのはなかなか無いもので。

    CSSハックが一部使えなくなる。

    個人的にはこれが一番大きいような気がします。

    • * html
    • *:first-child+html

    等のセレクタを使うようなハックは動作しなくなりました。まぁセレクタの挙動とかをFixするものなので当然なのでしょうけれど。。。
    なので、ただ読み込んだだけで全てがうまくいくようなものではないようです。

    重くなる

    ただでさえ、IE6等は重いのに、さらに重くなります。いまどきIE6が動いてるPCは古いですしね。
    特に、
    [js]
    var IE7_PNG_SUFFIX = ".png";
    [/js]
    等は全てのPNGが対象になるので、PNGをたくさん使うような場合はこの記述は避けたほうが懸命かと思います。

    :before,:after

    擬似要素を使うとき、どうやらここに1行分の高さを持った要素が生成されるようです。
    なのでclearfix等を擦るときはしっかりheight:0にしないとデザインがおかしくなることがあります。
    また、擬似要素を生成するとき、
    [html]
    <! class="ie7_class1">
    [/html]
    のような要素を生成するので、このクラスを指定してスタイルを当てることもたまには使えるかもしれません。

    新たに生成された要素にHTML5のタグがある場合

    Ajaxなどを使っている場合に起こるのですが、
    新しく生成されたHTML5要素には、やっぱりCSSが当たりません。
    この場合は、
    HTML 5 innerShiv
    http://jdbartlett.github.com/innershiv/
    などでやっつけるか、html5要素にcssを当てないだとか、html5要素をそこだけ避けるといったことが必要です。

    ザーッと書き並べてみましたけど、どうでしょう。
    自分が痛い目に合った記録みたいになってますね。

    Google AppsもIE7のサポート打ち切りを決めたようなので、早くIE8,IE9等に移行して頂ければ幸いです。切に願っています。
    Internet Explorer 8
    http://www.microsoft.com/ja-jp/windows/products/winfamily/ie/function/default.aspx

    Internet Explorer 9 のダウンロード
    http://windows.microsoft.com/ja-JP/internet-explorer/downloads/ie-9/worldwide-languages

  • Drupal7でのパブリックディレクトリのURLの取得

    Drupalでカスタムフィールドからアップロードしたもののパスをとろうとすると

    [plain]
    public://example.jpg
    [/plain]

    となってしまっていてどうにもこれが扱いづらい。

    しかし変換する方法も特に見つけられないので、

    [php]
    variable_get(‘file_public_path’, conf_path() . ‘/files/’).$node->field_hoge["ja"][0]["filename"];
    [/php]

    としてあげるとちゃんと通るファイルパスになります。

    ソースを読むのはやっぱりDrupal大変ですね。

  • Drupalでカスタムフィールドの値を表示する

    Drupalでカスタムフィールドの設定は簡単に出来ますが、表示するときは、フォーマットされて、$contentに格納されてしまいます。
    しかし、カスタムフィールドの値だけが欲しいときが結構あると思います。

    node.tpl.php等の中で、Drupal6ならば、
    [php]
    <?php echo $node->field_hoge[0]["value"];?>
    [/php]

    Drupal7なら
    [php]
    <?php echo $node->field_hoge["ja"][0]["value"];?>
    [/php]

    とすると、カスタムフィールドの値だけを取得することが可能です。
    また、$nodeは投稿の内容が格納されているオブジェクトなので、ここからいろいろな値を持ってくることが出来ます。

  • jQueryに独自の関数を追加

    jQueryを使っているとやっぱり独自の関数を作りたくなってきますよね。

    hoge()とhogehoge()というjQueryで使える関数を作ります。

    [js]
    jQuery.fn.extend({
    hoge:function(vars){
    jQuery(this).addClass("hoge").css({color:"#FFF"});
    return this;
    },
    hogehoge:function(){
    var $this = jQuery(this);
    $this.html("hogehoge");
    return this;
    }
    });
    [/js]

    こんな感じで独自の関数を定義できます。コードの再利用が簡単になるので、覚えておいて損はないです。
    return thisを返しておくと、メソッドチェーンができるようになるので、忘れずに入れましょう。

  • 学び処 立志塾様のサイトを制作させて頂きました。

    学び処 立志塾 | 長野県松本市 完全1対1個別指導の学習塾です

    この度、学び処 立志塾様のウェブサイトの新規立ち上げさせて頂きました。
    細かい気遣いが売りだということだったので、サイトの方もいろいろと細かい事をしています。

    技術的なことを言うと、
    jquery hashchange eventでページ遷移は実現しています。
    サイドバーはcss3のtransitionです。やっぱり軽快ですね。
    またブログなんかはカスタム投稿やカスタム分類使ってみたり。

    松本市在住で中高生のお子さんが居らっしゃる方は是非一度ご覧くださいm(_ _)m