かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Microsoft Edge リスト要素の記号が消えないバグ(list-style: none が効かない)にハマる。

Microsoft EdgeCSSlist-style: noneが指定されているにも関わらず、1. というリスト(ul, ol)の記号が消えないバグに遭遇しました。

調べているとIEでもこの問題はあったようで

問題の発生条件
概ね次のような条件で発生するようです。

  1. ul / ol / li 要素が何かしらの CSS の設定によって不可視の状態のまま描画される。
  2. 該当する要素が JavaScript や hover などのイベントによって可視化されるとき、記号が描画されたままになる。
  3. 該当する要素が一度可視化された後に、イベントやアクションによって再描画が発生すると、記号は描画されなくなる(適切に処理される)。

出典: IE で li 要素の記号が消えない問題 / list-style-type: none – カラクリ.jp

今回遭遇したものは、
リストをflex-boxにして、flex-direction: row;flex-wrap: wrap;でli要素を横並びにしたもので、IE11では問題がなく、Edgeのみlist-style:none;が効かずリストの記号が表示されてしまうというものでした。(※ 複合的な理由である可能性が高いので必ずしもflexの指定が原因だとは限りません)

解決方法として、

1. ul { list-style-image: url(data:0); }
2. ul { list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); }
3. ul { list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=); }

list-style-image に無効や空画像を当てはめるようなハックがありましたが、私の遭遇したものでは残念ながらこれらの方法では解決せず...
💩ブラウザのためにHTML構造を変更するのは少し癪でしたが、IE・Edge対応が必要な案件だったので ul li をdivに変更することで回避しました。

スクロールが効かない問題でIEとEdgeを調べたら同じ会社の製品で動くタグが違っていたり、本当にマイクロソフトの作るブラウザはクソなので、マイクロソフトはブラウザ作るの辞めて欲しいです...
WEBサイト作る(PCを使う)人は、たぶん腐った牛乳ことIE6時代からマイクロソフトに対して凄いHATEが溜まってると思うので、この💩ブラウザがあると事業的にも逆効果な気がしてるのですが… (僕はHATEが溜まりすぎてて既にMS office製品も使用しない主義者ですがw


参考

Gulp 実行コマンドに独自のオプションを付けて便利にしてみる例

前回minimistを使ってコマンドから実行するjsに変数を渡せるようにしました。 今回は、実際にコマンドのオプションで便利にgulpを使えるようにしてみた実例のメモです。

一つのgulp下に複数のhtmlサイトをディレクトリを区切って置いているイメージで、次のような感じのオプションを作成したいと思います。

オプション 設定値 効果
-o Boolean このオプションがある時、新しくwebserverを起動する
--dev Boolean このオプションがある時、pugを開発用でコンパイルする
--dir Strings 対象とするディレクトリ(サイト)を指定

gulp

const gulp        = require("gulp"),
      pug         = require("gulp-pug"),
      runSequence = require('run-sequence'),
      minimist    = require('minimist'),
      webserver   = require('gulp-webserver');

// options
const defaultOptions = {
  default: {
    o:   false,
    dev: false,
    dir: 'kenboku'
  }
};
const options = minimist(process.argv.slice(2), defaultOption);

// directory
const destDir  = 'websites/' + options.dir,
      devDir   = 'dev/' + options.dir;

// --------------------------------
// server
// --------------------------------
gulp.task('webserver', function() {
  gulp.src(destDir)
    .pipe(webserver({
      livereload: true,
      port: 3000,
      // -o オプションがあれば新規ウィンドウを開く
      open: !!options.o
    }));
});

// --------------------------------
// HTML
// --------------------------------
gulp.task('pug', function(cb) {
  let files    = devDir + '/pug/*.pug',
      destPath = destDir,
      pugOption  = {
        pretty: true,
        // pugのグローバル変数として渡す値を設定できる
        locals: {
          lang: 'ja',
          // --dev オプションの値をpugに渡す
          devMode: !!options.dev
        }
      };
  
  // コンパイルするhtmlをmin化
  if( options.dev === false ) {
    pugOption.pretty = false
  }

  return gulp.src( files )
    .pipe( plumber() )
    .pipe( pug(pugOption) )
    .pipe( gulp.dest(destPath) );
});

// --------------------------------
// TASK
// --------------------------------
gulp.task('build', function(cb) {
  // build で実行した場合はオプションを無視して開発者用にしない
  options.dev = false;
  return runSequence('html', cb);
});

// --------------------------------
// WATCH
// --------------------------------
gulp.task('default', ['webserver'], function() {
  gulp.watch([
    devDir + '/pug/**/*.pug',
  ], ['html']);
});

cssjavascriptのタスクは割愛しています

pug

block Variable
  -// lang, devMode は gulp から渡される変数
  - var siteName = "かもメモ"
  - var cssVer = '2018-04-01'
doctype html
html(lang= lang)
head
  meta( charset="utf-8")
  meta( name="viewport" content="width=device-width,initial-scale=1.0" )
  meta( name="description" content=`${siteName} 自分の落ちた落とし穴に何度も落ちる人のメモ帳` )
  title= siteName
  - if( devMode )
    link(href="/assets/css/main.css?v="+cssVer, rel="stylesheet")
  - else
    link(href="/assets/css/main.min.css?v="+cssVer, rel="stylesheet")

gulpの実行

kamomeディレクトリのサイトを開発モードで新しくwebサーバを立ち上げてファイル監視を開始

$ gulp -o --dev --dir kamome

yrukyanディレクトリのサイトを本番用にコンパイル

$ gulp build --dir yrukyan

 
minimistモジュール本当ぉぉぉぉおおおおおにッ 便利です!!!!!!
gulp-ifモジュールを利用すればpipe中にオプションによって処理を変えるとかも可能なので、設計を考えればかなり複雑なことまでできそうだなと思いました。
ただ自分で作ったオプションを忘れてしまっても大丈夫なようにREADMEとかちゃんとドキュメントに残しておくのが良いと思います。(ドキュメントを書かないのは悪い文化!)


[参考]

Webデザイナーの仕事を楽にする!  gulpではじめるWeb制作ワークフロー入門

Webデザイナーの仕事を楽にする! gulpではじめるWeb制作ワークフロー入門

Gulp node.js 実行時に変数を渡して処理を分岐させたい

以前 Gulpでタスクを指定して実行することで無理やり処理を分岐させる方法を書いていました。

今回同じような需要が合って調べているとgulp実行時コマンドに直接キーと引数を渡せる素晴らしい方法があったのでメモ。

minimistを使ってコマンドラインから変数を渡す

minimistというコマンドラインの引数をパースできるモジュールがあるようです。

var parseArgs = require('minimist')
var argv = parseArgs(args, opts={})

EX: コマンドラインの引数

// example.js
const options = require('minimist')(process.argv.slice(2));
console.log(options);

例えば上記のようなjsがあり、コンソールから次のようにコマンドを実行してみます。

$ node example.js do -v -x 3 -y=4 -z5 -ab -cd hoge -n6m10 -rx78v2 --env develop --beep=beep foo bar baz

👇パース結果

{ _: [ 'do', 'foo', 'bar', 'baz' ],
  v: true,
  x: 3,
  y: 4,
  z: 5,
  a: true,
  b: true,
  c: true,
  d: 'hoge',
  n: '6m10',
  r: 'x78v2',
  env: 'develop',
  beep: 'beep' }

- の挙動が少し複雑ですが、ざっくりこんな感じかなと思います。

  • - で始まる引数: 1文字のキーになり、キーの後ろにスペースまたは=を置いて値があれば、そのキーの値になる。値が無ければtrue
    キーが2文字以上になっている場合
    • 2文字目以降に数字が含まれる場合 => 2文字目以降がキーの値になる
    • 2文字目以降が文字列のみの場合 => 1文字づづキーに分解され、その後にスペースが有り値があれば、最後の文字にその値が設定される
  • -- で始まる引数: 文字列がキーになり、キーの後ろにスペースまたは=を置いて値があれば、キーに値が設定される。値が無ければtrue
  • それ以外の値は、_をキーにした配列の値になる。

 
キーが重複した場合は、-でも--でも明示的に値をtrueとしていない場合は置き換えられ、それ以外は値が配列になるようです

$ node example.js -s -n true -m -l -x 3 -y 4 -s false -n false -x 10 -y foo -m null -l undefined

👇

{ _: [],
  s: 'false',
  n: [ 'true', 'false' ],
  m: 'null',
  l: 'undefined',
  x: [ 3, 10 ],
  y: [ 4, 'foo' ] }

 

$ node example.js --flg --foo true --bar true --baz true --arg --flg false --foo false --bar null --baz undefined --arg false --arg null --arg undefined

👇

{ _: [],
  flg: 'false',
  foo: [ 'true', 'false' ],
  bar: [ 'true', 'null' ],
  baz: [ 'true', 'undefined' ],
  arg: [ 'false', 'null', 'undefined' ] }

オプションのデフォルト値を作成できる

minimistの第二引数に配列(オブジェクト)を与えると、コマンドラインから渡された引数の配列でマージすることができます。
コマンドラインで引数が指定されていない場合のデフォルト値を作ったりするのに便利です。

// gulpfile.js
const defaultOption = {
  // コマンドから渡される値のデフォルト値は default キーの中に設定する
  default: {
    env: 'develop',
    dir: 'root'
  }
}
const options = require('minimist')(process.argv.slice(2), defaultOption);
console.log(options);

// gulp task
gulp.task('compile', function() {
  console.log('do compile!');
});

コマンド

$ gulp compile --dir dev/test

👇

{ _: [ 'compile' ], dir: 'dev/test', env: 'develop' }
[21:32:45] Using gulpfile ~/Documents/local/example/gulpfile.js
[21:32:45] Starting 'compile'...
do compile!

gulpでもコマンドでタスクを指定して引数を渡すことも問題なくできました!

後はgulpfile.jsの中で、飛鳥に応じて取得されたオプションで対象のディレクトリを切り替えるとか、gulp-ifモジュールをつかってgulp.pipe内で処理を変更するとかすればイイ感じになりそうです。
minimist モジュール結構昔からあったみたいなので、今まで検索して見つけることができなかった事が悔やまれます...


[参考]

「宇宙よりと遠い場所」ってアニメすごく良かった。

WACOM Mac ペンタブレットIntuosのペンが反応しなくなった

このAI?が描いた絵を認識して当ててくれるゲームのようなサービスで遊ぼうと思いWacomのペンタブ(Intuos)を繋いだのですが、マッピングが画面の全画面なのに端の方だけになっていたり、ペンを認識してるのにマウスカーソルが動かない(反応しない)状態になってしまっていて、ペンタブの接続を切って再接続したり、ワコムのデスクトップセンターを再起動させたりしても症状は治らず解決に少しハマってしまったのでメモ。

私の症状としてはタブレット側でペンを認識はしている状態でした。
ペンが故障しているかどうかはWacomの「よくあるご質問と回答」から確認することができるようです。(このページになかなか辿り着かなくて大変でした...)

Intuosの場合はこれでした👇
ペンタブレットの動作で困ったときは、こちらを確認ください。 | Wacom
症状を確認しながら当てはまるものをチェックすると解決策が表示されます。

ペンが反応しない場合の解決方法

1. アクセス権の修復

Macでトラブルが合った時の鉄板。
アプリケーション > ユーティリティ > ディスクユーティリティ.app でディスクのアクセス権を修復するやつです。

2. タブレット設定ファイルの初期化 (削除)

Wacomのドライバをインストールした時?だと思うのですが、「ワコムタブレットユーティリティ.app」というアプリケーションがインストールされていたのですね。今日まで全く知りませんでした...

Macの場合は

  1. アプリケーション > ワコム タブレット > ワコムタブレットユーティリティ.app を起動
    f:id:kikiki-kiki:20180327020815p:plain
  2. 設定ファイル「削除」を選択して設定ファイルを削除する。(私は削除する前に一度バックアップを選択して設定ファイルのバックアップを作成しました)
    f:id:kikiki-kiki:20180327020833p:plain
  3. システム環境にあるワコムタブレットの設定は再起動しないと反映されないので、PCを再起動
    f:id:kikiki-kiki:20180327020849p:plain
    👆OSのバージョンが古いのがバレる...
  4. ペンタブレットの設定ファイルが初期化されました
    f:id:kikiki-kiki:20180327020902p:plain

今回の場合はこの設定ファイルの初期化でマッピングも正常になりペンが反応するようになりました。
設定ファイルを初期化してもペンが反応しないような場合はドライバを削除して再インストールする必要があるようです。
今回私は試してないのですがその方法のリンクだけメモとして貼っておきます。

3. ペンタブのドライバを削除して再インストールする

タブレットドライバをアンインストール(削除)する方法 | Wacom

 
旅行から帰ってきてMacを起動してペンタブを繋いだらペンが反応しない症状に初めて遭遇して、もしかして壊れた?とかなり焦ってしまいました。
おかげでワコムタブレットユーティリティというアプリケーションの存在を知ることができたのですが、デスクトップセンターとかのアプリからわかりやすくFAQに飛べるような導線があると良かったかな〜思いました。(解決方法のわかるFAQに辿り着くのが難しかったので...)


👆これ持ち運びにも良さそうなので欲しぃ

WordPress WP_Query 複数のカスタムフィールドを条件に投稿を取得したい。

WordPressでカスタムフィールドをたくさん作ったサイトとかでは、カスタムフィールドの値を条件にして投稿を取得したいケースが多々あります。
複数のカスタムフィールドの値を条件に投稿を取得する時のメモ。

条件にするカスタムフィールドが1つのとき

おさらい。
例えば product 投稿のカスタムフィールド pickuponのものを取得したい場合。
meta_key キーワードを使って指定する方法

<?php
$arg = [
  'post_type'    => 'product',
  'meta_key'     => 'pickup',
  'meta_value'   => 'on',
  'meta_compare' => '=', // "=" はデフォルトなので省略可
];
$the_query = new WP_Query($arg);

meta_query で指定する場合

<?php
$arg = [
  'post_type'  => 'product',
  'meta_query' => [
    [
      'key'     => 'pickup',
      'value'   => 'on',
      'compare' => '=',  // "=" はデフォルトなので省略可
    ],
  ],
];
$the_query = new WP_Query($arg);

複数のカスタムフィールドを条件にするとき

カスタムフィールド pickuponで、カスタムフィールドsale_end_atの日付が今日より大きい product (post_type)を取得した場合。
複数のカスタムフィールドを条件にしたい場合はmeta_queryの配列に条件を追加すればOK

<?php
$arg = [
  'post_type'  => 'product',
  'meta_query' => [
    [
      'key'     => 'pickup',
      'value'   => 'on',
    ],
    [
      'key'     => 'sale_end_at',
      'value'   => date( "Y-m-d" ),
      'compare' => '>',
    ],
  ],
];
$the_query = new WP_Query($arg);

複数のカスタムフィールドの値を AND で取得することができます。

複数のカスタムフィールドの条件をORで取得したいとき

meta_queryのカスタムフィールドの条件がある階層にrelationで指定することができます。(relationの指定がないとANDになります。)

カスタムフィールドsale_end_atの日付が今日より大きい または sale_end_atが指定されていない(未登録) で取得したい場合。

<?php
$arg = [
  'post_type'  => 'product',
  'meta_query' => [
    'relation' => 'OR',
    [
      'key'     => 'sale_end_at',
      'value'   => date( "Y-m-d" ),
      'compare' => '>',
    ],
    [
      'key'     => 'sale_end_at',
      'compare' => 'NOT EXISTS',
    ],
  ],
];
$the_query = new WP_Query($arg);

複数のカスタムフィールドでの複雑な条件での取得

カスタムフィールド pickuponで、
カスタムフィールドsale_end_atの日付が今日より大きい または sale_end_atが指定されていない(未登録) で取得したいような場合... 日本語で書くとややこしい...

pickup = "on" && ( sale_end_at > TODAY || NOT EXISTS (sale_end_at)  )

こんな感じの条件にしたいイメージです。

どうやら、meta_queryの配列内に配列を入れ子にして条件を作成することができるようです。

<?php
$arg = [
  'post_type'  => 'product',
  'meta_query' => [
    'relation' => 'AND',
    [
      'key'     => 'pickup',
      'value'   => 'on',
      'compare' => '=',
    ],
    [
      'relation' => 'OR',
      [
        'key'     => 'sale_end_at',
        'value'   => date( "Y-m-d" ),
        'compare' => '>',
      ],
      [
        'key'     => 'sale_end_at',
        'compare' => 'NOT EXISTS',
      ],
    ],
  ],
];
$the_query = new WP_Query($arg);

 
WP_Query すごい!!

ただ、カスタムフィールドの値でORDER_BYの条件にしたい時はmeta_keyに条件にするカスタムフィールドを指定しなければならないっぽいので、上記の条件でsale_end_atで並び替えようとするとsale_end_atが存在しない(NOT EXISTS)な投稿は取得されなくなってしまうのでORDER_BYと併用する場合は注意が必要です。(存在しない値のものがあるとどう並び替えるねん!ってなるから当然といえば当然ですが...

<?php
$arg = [
  'post_type'  => 'product',
  'meta_query' => [
    'relation' => 'AND',
    [
      'key'     => 'pickup',
      'value'   => 'on',
      'compare' => '=',
    ],
    [
      'relation' => 'OR',
      [
        'key'     => 'sale_end_at',
        'value'   => date( "Y-m-d" ),
        'compare' => '>',
      ],
      [
        'key'     => 'sale_end_at',
        'compare' => 'NOT EXISTS',
      ],
    ],
  ],
  'meta_key' => 'sale_end_at',
  'orderby'  => [
    'date'       => 'DESC',
    'meta_value' => 'ASC',
  ],
];
$the_query = new WP_Query($arg);

👆sale_end_atNOT EXISTS の投稿は取得されない。
並び替えが必要なら素直に2回 WP_Queryを発行するか、WP_Queryで取得した値をループさせて手動で並び替えを行うかで対処することになります。(DB問い合わせが少ないほうが良さそうかも!?

改めてWP_Queryって色々できるんだなーと知りました。


イタリア商事 ホットサンドメーカー ニュー・バウルー ダブル BW02

イタリア商事 ホットサンドメーカー ニュー・バウルー ダブル BW02


👆これ買ったので早く使いに行きたい。