Posts Tagged ‘css’

クリッカブルなボタンとWAI-ARIAのrole="button"について

前提知識として以下が必要です。

clickイベントに使うためだけに<a href=”#”>text</a>とか(下の例の1,2番目)やるのが嫌いで、どうやるのがスマートorシンプルなんだろと思って書き出したもの。input、button 要素がでてこないのはスタイルシート考えるのが面倒で何となくです。button要素をCSSでリンクのようなデザインにできるならそれでもいいじゃないでしょうか。

1番目は今時ない気がするし、1,2番目は状態が遷移しないのにhref指定してると、ミドルクリックなどで別のページとして開けたりしちゃうのでそれを抑制するコードも必要になるのが何か嫌で、3番目当たりが個人的には好きだった。(4番目は何か気持ちわるい)

<div><a href="javascript:void 0;">javscript:ボタン</a></div>
<div><a href="#">#なボタン</a></div>
<div><a role="button">hrefがないroleボタン</a></div>
<div><span role="button">リンクじゃないspanボタン</span></div>
動作的には問題ない気がするけど、ここで、A要素は元々nativeとして持っているroleがrole=”link”で、それをrole=”button”で上書きできるのかが気になった。
そもそも、role=”link”とrole=”button”の違いは何かというとlinkの項を見るとわかるように、押したことによりブラウザのフォーカスやlocationが変わらないなら、それはrole=”button”を使うべきだと書いてある。

Note: If pressing the link triggers an action but does not change browser focus or page location, authors are advised to consider using the button role instead of the link role.
The Roles Model | Accessible Rich Internet Applications (WAI-ARIA) 1.0

そして、A要素のroleはnativeでlinkですが3.2.5 Content models — HTML Standardを見ると、 link, button, checkbox, menuitem, menuitemcheckbox, menuitemradio, tab, treeitem のいずれかのroleであれば上書きすることができると書いてあります。(そう読み取れたんだけどあってるのかね)

image
なので、role=”button”なA要素は仕様に反していないはず。
<a role="button">hrefがないroleボタン</a>
WAI-ARIAの方にもいろいろ書いてあるんだけど、英語力不足で読み取れない…
日本語版は一個古い感じなので、内容も結構違う感じする。

何で、上書きできるかが気になったかというとjavascript scheme でボタンを作るのは ? | ヨモツネットのコメント欄で、できないかのように読み取れる内容があったため。多分多分、strong native semanticsというのはa要素が本来持っているのはlinkというroleの事で、<a role=”button” />のようにそれぞれのa要素におけるroleは上書きできるけど、a要素本来のlink(strong native semantics)というroleは上書きできないよって話なのかなーとか思った。(仕様読んでないので自信ない)

ちなみに、jQuery UIの$.button()は<button role=”button”>という感じでbutton要素を使用している。

他のUIライブラリも見てるみると、Extjs,Google Web Toolkit,Yahoo! User Interface Library (YUI)もbutton要素を使っていた。(role=”button”は省略してる感じのが多い)
UIライブラリはスタイルとかとセットなので、roleも意味がはっきりしたものとって後はスタイルやった方が良さそうだしね

WAI-ARIA対応のライブラリはこの辺を見た

というわけで、ここに書かれている内容はあまり自信がありません。以上

Firefox4でcan’t wrap XML objectsというエラーが出る件について

Firefox4にしてから主にGreasemonkeyのGM_addStyleメソッドで

TypeError: can’t wrap XML objects

というエラーが出たりすることがあります。
これはBug 609143 – E4X XML objects cannot be passed to sandboxのsandbox内でのE4X(XML)の挙動が変わった(意図的に)のが原因らしいです。(あまり詳しくないので…)

GM_addStyle(<><![CDATA[ 
/* 適当なCSSのコード*/
    .clearfix:after {
        content: ".";  /* 新しい要素を作る */
        display: block;  /* ブロックレベル要素に */
        clear: both;
        height: 0;
        visibility: hidden;/*表示はしない*/
    }
 ]]></>)

のような感じでE4X(XML)を直接GM_addStyleに渡しているときなどに起きています。
これを回避するためには、E4X(XML)を明示的に文字列化して渡せばよい見たいです。

GM_addStyle(String(<><![CDATA[
/* CSSコード */
]]></>));

のようにString(E4X)するか、E4X全体をtoString()、”"+E4X のような感じで文字列化すればいい。
もしくはGreasemonkeyにはメタ情報に// @resource CSS example.css という感じで、CSSファイルをロードできるので、そのファイルをGM_addStyle(GM_getResourceText(‘CSS’));して使うなどでもいいと思います。

もしくは下のようにGM_addStyleを書き換えてしまう事でも回避できそうです。(あんまり推奨しないけど)

function GM_addStyle(css) {
    if (!GM_addStyle.style) {
        var head = document.getElementsByTagName("head")[0] ||
                document.documentElement;
        if (!head) {
            return;
        }
        GM_addStyle.style = document.createElement('style');
        GM_addStyle.style.type = 'text/css';
        head.insertBefore(GM_addStyle.style, head.firstChild);
    }
    GM_addStyle.style.appendChild(document.createTextNode(css) + '\n');
}

書き換えの参考

Constellation’s gist: 803115 — GistのようにTomblooパッチでGM_addStyleの挙動を変えてしまおうと思ったけどよく分からなくなってあきらめました。

参考

Google検索でのuserContent.cssの設定やGreasemonkeyなど

Google検索は最も使うサービスの一つだと思うので、できる限り快適にしたいです。いろいろいじってたのがやっと落ち着いたので設定のメモです。

まずはGreasemonkeyから

と、このぐらいで思ったより、Greasemonkeyは入れてない感じします。
Google検索自体が結構高機能なので、そこまで機能を付け加える必要が無いのかもしれないです。(期間指定をもっと簡単にやりたいけど)
後はアドオンでGoogle Date :: Add-ons for Firefoxを入れているぐらいです。
入れている理由は最終更新日を知るためなのでちょっと関係ないかもしれないです。

次にuserContent.cssの設定。
Stylishは入れてないので直接userContent.cssに書いています。(デバッグにはuserMenu.uc.jsのCSSリロードが便利)

/* Google検索ページ
+結果欄の幅拡張
+検索バーを固定
+サイトの背景色を奇数で色分
+広告は犠牲になった
*/
@-moz-document url-prefix("http://www.google.co.jp/search"),
                 url-prefix("http://www.google.com/search"){
    /* 「もっと見る」を押さなくても、最初から全部表示 */
    .nojsb {
        display: block !important;
    }
    #tads{
        display: none !important;
    }
    #showmodes {
        display: none !important;
    }
    #mbEnd{
        display:none !important;
    }
    /* fixedSearchbar */
    #nr_container {
        margin-top: 115px;
    }
    #sfcnt {
        -moz-box-shadow:0 1px 5px #000000;
        box-shadow:0 1px 5px #000000;
        left:0;
        padding:18px 0;
        top:25px;
        width:100%;
        z-index:10;
    }
    #gog {
        left:0;
        top: 0;
        width:100%;
        z-index:11;
    }
    #gog, #sfcnt, #subform_ctrl{
        background:none repeat scroll 0 0 rgba(255, 255, 255, 0.9)!important;
        position:fixed;
    }
    #sfcnt {
        height:70px !important;
        padding-top:0 !important;
    }
    #subform_ctrl {
      text-align:right;
      z-index: 10;
      right: 0;
      top: 88px;
      min-height: 0;
      background:none repeat scroll 0 0 transparent!important;
    }
    #guser, #gbar{
          padding: 1px 0;
    }
    #gbar nobr, #guser nobr {
        line-height: 22px;
    }
    /* oddには色をつける */
    li.g:nth-child(odd){
        background:#F7F7F7;
    }
    /* 説明文を横に延長 */
    .g{
        min-width:800px;
        padding:5px!important;
        -moz-border-radius : 5px;
        border-radius : 5px;
    }
    .s {
        min-width: 800px !important;
    }

    /* RealTimeの場合横幅に必要 */
    #center_col{
        min-width:820px!important;
    }
    /*右側のbox*/
    #rtro{
        width: 800px!important;
    }
    /* 普段は隠しておいて、マウスオーバーで表示させる */
    #rhs{
        -moz-box-shadow:-3px 3px 3px #000000;
        white-space: nowrap;
        background:#fff!important;
        right: 0!important;
        top: 0!important;
        width: 15px!important;
        overflow:hidden;
    }
    #rhs:hover{
        background:#fff!important;
        right: 0!important;
        top: 0!important;
        width: 800px!important;
    }
}

Googleの設定 — Gist

今はこんな感じで、結果欄の横幅拡張、検索バーを固定、サイトの背景色を奇数で色分けなどを行っています。
スクリーンショットで見ると以下のような感じになります。

また、先ほどGoogleのTwitter検索である”Google Realtime Search”のSITEINFOをwedataに書いておいたのでかなり快適になりました。
(各種AutopagerizeでSITEINFOの更新を行えば適応されると思います)

思ったより地味ですが、こんな感じで使っています。
Google++ for Greasemonkeyを結構参考にしました。

Greasemonkeyでサイト既存CSSの影響を受けないポップアップパネルを作る方法

Greasemonkeyは各サイトでユーザースクリプトを実行できて便利ですが、ある要素を挿入したときにそれがサイトに元々書いてあるCSSの影響を受けてしまうことがあります。
一つのサイトならまだしもhttp*で動くようなものだと対応仕切れないのでiframeを使いサイトに書いてあるCSSの影響を受けないパネルを作る。
iframeの中はそのサイトにあるCSSの影響を受けないので、iframe内にGreasemonkeyで表示したいものを置けば影響を受けないものが作成できる。
makeFrameというのが今回の主題。

makeFrame(gotFrame1);
makeFrame(gotFrame2);

function gotFrame1(iframe, win, doc) {
  iframe.height = "350";
  iframe.width = "500";
  iframe.style.position = "fixed";
  iframe.style.bottom = iframe.style.left = "0";
  doc.body.innerHTML += "Frame1ですね。"
}
function gotFrame2(iframe, win, doc) {
  iframe.height = "350";
  iframe.width = "500";
  iframe.style.position = "fixed";
  iframe.style.bottom = iframe.style.right = "0";
  iframe.style.backgroundColor = "#ddd";
  doc.body.innerHTML += "Frame2ですよ。"
}
// Creates a new iframe and attaches it to the DOM, waits for it to load, tests
// that we did not hit https://bugzilla.mozilla.org/show_bug.cgi?id=295813 nor
// https://bugzilla.mozilla.org/show_bug.cgi?id=388714 (and retries otherwise),
// to finally call the provided done callback, passing the iframe, its window
// and document. (The optional name parameter, if provided, will be used to name
// the iframe in window.frames, or be created as "pane-1" onwards, otherwise.)
/*
    var cacllback = function(iframe, win, doc){

    }
    makeFrame(cacllback);
    makeFrame(cacllback , "frameName");
    makeFrame(cacllback , "frameName" , true);// debug mode
*/
function makeFrame(callback/*(iframeTag, window, document)*/, name, debug) {
    function testInvasion() {
        iframe.removeEventListener("load", done, true);
        var message = ((new Date) - load.start) + "ms passed, ";
        try { // probe for security violation error, in case mozilla struck a bug
            var url = unsafeWindow.frames[framename].location.href;
            message += url == "about:blank" ? "but we got the right document." : "and we incorrectly loaded " + url;
            if (debug) console.log(message);
            done();
        }
        catch(e) {
            if (console && console.error && console.trace) {
                console.error(e);
                console.trace();
            }
            if (debug) console.log(message + "and our iframe was invaded. Trying again!");
            document.body.removeChild(iframe);
            makeFrame(callback, name);
        }
    }
    function done() {
        clearTimeout(load.timeout);
        if (debug) console.log("IFrame %x load event after %d ms", framename, (new Date) - load.start);
        var win = unsafeWindow.frames[framename];
        var doc = iframe.contentWindow.document;
        // 苦し紛れのエスケープ
        var esframeName = "'"+framename+"'";
        // 自分自身のiframeを閉じるボタン
        var xImg = doc.createElement("img");
        xImg.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAATElEQVQoka2RSQ4AIAgD+f+jp96M0aq49AgdUiB0qZCkONQ/EBAwDOrrU7A1uZqN2hodtNwRqNdz0VOg62+jzuDUcVzkf+/I6h28UQHjW25Gob5AIAAAAABJRU5ErkJggg=="
        xImg.setAttribute("onclick", "parent.document.getElementsByName("+esframeName+")[0].style.display='none';");
        xImg.setAttribute("style","background-color:red;border:3px;position:fixed;top:0px;right:0px");
        doc.body.appendChild(xImg);
        callback(iframe, win, doc);
    }
    var iframe = document.createElement("iframe");
    var framename = iframe.name = typeof name != "undefined" ? name : ("pane" + (makeFrame.id = (makeFrame.id || 0) - 1));
    iframe.setAttribute("style", "overflow:auto;z-index:18999; border:0; margin:0; padding:0;top:auto; right:auto; bottom:auto; left:auto;background-color:#fff");
    iframe.src = "about:blank";
    iframe.addEventListener("load", done, true);
    var frames = makeFrame.data || {};
    var load = frames[framename] || {
        start: new Date,
        sleepFor: 400
    };
    load.timeout = setTimeout(testInvasion, load.sleepFor);
    load.sleepFor *= 1.5;
    frames[framename] = load;
    makeFrame.data = frames;
    document.body.appendChild(iframe);
}

makeFrame関数は(callback ,[フレームのname , debugモード])という引数なので、gotFrame1という関数(callback)を引数にしてmakeFrameを読んでいる。 callbackには(iframe, iframeのwindow, iframeのdocument)が入ってるいるので、iframeのstyleをいじればパネルの色やサイズ、表示する場所などを指定できる。 上記のソースだと左下にframe1、右下にframe2が表示できる。

表示例

元ネタからの改良点

  • パネルを閉じるボタンの追加

それぞれのパネル右上に表示されているxボタンは、パネルを閉じるボタンとして機能している。 innerHTMLが+になってるのはiframe内にxボタンを追加しているため。

  • Flashより上部に表示

パネルなのでFlashがあってもその上に表示できるようにした方が動作的にはいいと思うのでCSSを少し修正した。
要素をFlashより上部する方法は以前書いたFlashよりも前面にポップアップを表示するFirefox 3.6でFlashの上に position: fixed; な要素を表示できなくなった件 – なんとなく目記を見るといい。
Firefox3.6では挙動が変わったので注意。
Flashより上に表示するには”position: fixed; overflow: auto;”とした要素であり、以下の条件を満たす必要がある。

  1. 透過でない(Opacityを使わない or 背景色を無指定にしない)
  2. CSS3?(-moz-)系のstyleを使わない。(-moz-box-shadowなどは陰の部分だけFlashより後ろに表示されてしまう
    角丸border-radiusなどは要素に適応されるので要素全体がFlashより後ろに表示される。)

このmakeFrameを使ったサンプルGreasemonkeyとして
ニコニコ動画再生ページからその動画のマイリストコメントをパネル上で参照できる

Nico MylistComments for Greasemonkey
http://userscripts.org/scripts/show/72319

を作ってみた。

元ネタ(元ネタのサンプルはtypoがあるので、そのままだと動かない)

HTML Injection Tips – greasemonkey – GitHub
http://wiki.github.com/Martii/greasemonkey/html-injection-tips
makeFrame

TwitterのWebページをサイドバーで使うためのまとめ

Twitterのウェブサイトをクライアントとして使うのに役立つGreasemonkeyとCSS | Web scratch
http://efcl.info/2009/0317/res613/

以前書いたような記事と似たような記事を書きましたが、今回はシンプルにサイドバーでTwitterのWebページを表示する方法です。
Greasemonkeyがサイドバーでも動作するようになったので、かなり快適になり、またWebページを表示するだけなのでAPIを使わないのが特徴です。


最終的な似た目

最終的な似た目


まずはCSSでサイドバーに合わせた形にする必要があります。

nukumori wiki – Firefoxのサイドバーでtwitter.comするCSS
http://nukumori.org/hiki/?TwitterSidebarCSS

にあるCSSを使ってサイドバーに合わせたものにしていきます。
使い方は書いてあるのでそれをよく読んでCSSを反映させます。
(ブックマークするのはhttp://twitter.com/?sidebar という適当なクリエを付けたURLです。
http://twitter.com/だと通常見るときと混ざってしまうため。)

ブックマークではなくCustom Buttonsを使ってtwitterをサイドバーに表示するボタンを作成する方法もあります。
Twitterをサイドバーに表示するボタンを作成しておきました。

  • userChrome.css
    少し自分向けに修正したCSS(通常のTwitterページ向けも混ざってる)

次により使い易くするためのGreasemonkeyを入れていく。

Ctrl+Enterでポストする。

自分の投稿や、特定のワードが入ってる投稿を色分けする
tyoro.exe: 投稿内容からマッチングしてスタイル変えるグリモン書いたよ!

自動更新の差分を自動で取得
Twitter webの自動差分更新Greasemonkeyスクリプトを書いてみた « H.LOG


自分は入れてませんが基本的にはTwitterのWebページと同じなので、

など入れるのもありかもしれない。


Twitterのウェブサイトをクライアントとして使うのに役立つGreasemonkeyとCSS

TwitterのHomeであるhttps://twitter.com/homeをクライアントして使うのに役立つGreasemonkeyとuserContent.cssのメモ書き
Twitterを利用するのにTweenなどのクライアントソフトを使っている方も多いと思いますが、自分でいじれる範囲が限定されるため、
Twitterのホームページを積極的に使っていこう的な内容です。

自分の使い方としては、メインPCの横にLOOX Uを縦にした状態での使いやすさなので、縦長の画面での使いやすさを考慮してます。

    まずスペースを確保するためにCSSで余計なものを消していきます。
    Firefoxではusercontent.cssやstylishでCSSをいじれるので、自分なりに省スペースにしたものを置いておきます。(userContent.cssとは)

    usercontent.css

    次に、画面サイズによって文字の大きさなどのバランスがくずれるのでNoSquint:を使って文字サイズなどのバランスを調節しておきます。

    デザインを調節した状態

    デザインを調節した状態


    送信ボタンが消えてますが、後でショートカットで行えるようにするのであんまり問題ないです。

    • Greasemonkeyの導入

    Greasemonkeyでより使いやすくしていきます。

    Auto-reload Twitter
    http://gist.github.com/80361

    自動でリロードする。
    差分を追加していくタイプもありますが、連携が取りにくいのが難点です。
    TwitterCliantGreaseMonkey

    Twitter Change Style
    http://gist.github.com/80364

    動作していなかったので勝手に修正したものを置いておきます。 AutoPagerizeにも対応しています。

    機能概要 ・自分の名前の含まれる発言の色変更 ・自分の発言の色変更 ・送信者マッチングによるスタイルの変更 ・受信者マッチングによるスタイルの変更 ・本文マッチングによるスタイルの変更(正規表現可

    tyoro.exe: 投稿内容からマッチングしてスタイル変えるグリモン書いたよ!

    Nested Twitter Replies
    http://userscripts.org/scripts/show/30598

    replyの発言をネスト表示してくれるのでとても便利です。
    httpsの時にアイコン画像が表示できてなかったので修正したものを置いておきます。
    http://gist.github.com/79915

    Twitter Filter
    http://userscripts.org/scripts/show/36522

    Twitterの発言にブラックリストとホワイトリストを設定してフィルタリング

    Twitter Enhancements: Press Ctrl + Enter to Send Update
    http://gist.github.com/79789

    Ctrl + Enterでつぶやきを投稿できるようにします。

    twitter friend name helper
    http://userscripts.org/scripts/show/8518

    @やDの時に名前を補完してくれます。

    unzipLinker
    http://bulkya.blogdb.jp/share/browser/lang/javascript/userscripts/unziplinker.user.js?rev=18867

    TinyURLをマウスオーバーで展開してくれます。

    こんな感じです。
    ではよいTwitter生活を。

    タブをグループ管理する拡張機能「タブグループマネージャー 」

    タブグループマネージャーは複数のタブをグループに分類し、そのグループに名前を付けて管理する事ができるアドオンです。
    タブを多数開いても管理しやすくなるので、積極的に多数のタブを開いて活用できるようになります。
    グループ名もほぼ自動で決められるので、タブを開きまくる人には便利です。
    Tab mix plus + ツリー型タブを併用していますが、問題なく動いてる。
    前回のセッションを使った再起動時の挙動が少し変だけど、普段使うわけではないので問題ない。

    そのままだと少し幅を取っていたのでstylishでタブグループマネージャー を普段非表示にして、
    メニューバーやナビゲーションバーにマウスオーバーしたときにポップアップするようにするcssを書いた。

    タブグループマネージャー | userstyles.org
    http://userstyles.org/styles/13520

    タブを簡単にグループ移動させるなど出来たら面白そうな気がした。

    タブグループマネージャー :: Firefox Add-ons
    https://addons.mozilla.org/ja/firefox/addon/10254
    プロフィール: azu(アズ)
    Firefoxの事やソフトウェアの紹介や使い道、Greasemonkeyの作成
    • OS:Windows Vista, 7
    • ブラウザ:Firefox
    • Twitterのアカウントはこちら
    • azu_re
    • メールアドレス(Twitterの方が確実)
    • info@ドメイン名
    リンク