IEでみるとスクロールバーと画面のコンテンツが重なっている

参考:IE でスクロールバーがコンテンツに重なる問題を解決する

viewportが原因だそうです。今viewportの設定は、となってますが、IE11とかは、device-widthが入ってるとスクロールバーも含めてしまうらしい。CSSに下記のように書けばいいらしい。

@-ms-viewport
{
    width: auto;
    initial-scale: 1;
}
@viewport
{
    width: device-width;
    initial-scale: 1;
}

おーできた。

cordova + onsen ui + reactの開発環境

cordova + onsen ui + reactの開発環境を作成してみます。cordovaのテンプレートにして、メンテしていければと思います。環境は、windows10、npm3.10.8です。エディタは、visual studio code1.6.1を使ってます。

プロジェクトを作る

npmはインストール済みです。

$ cd どこか
$ mkdir cordova
$ cd cordova 
$ npm i -g cordova
$ cordova create hoge
$ cd hoge

必要なものをnpm install

下記のpackage.jsonを配置して、npm installを実行。

{
  "name": "hoge",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "onsenui": "^2.0.1",
    "react": "^15.3.2",
    "react-dom": "^15.3.2",
    "react-onsenui": "^1.0.1"
  },
  "devDependencies": {
    "autoprefixer": "^6.5.1",
    "babel": "^6.5.2",
    "babel-core": "^6.17.0",
    "babel-loader": "^6.2.5",
    "babel-preset-es2015": "^6.16.0",
    "babel-preset-react": "^6.16.0",
    "css-loader": "^0.25.0",
    "eslint": "^3.7.1",
    "eslint-config-airbnb": "^12.0.0",
    "eslint-loader": "^1.5.0",
    "eslint-plugin-import": "^2.0.1",
    "eslint-plugin-jsx-a11y": "^2.2.3",
    "eslint-plugin-react": "^6.4.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "postcss-loader": "^1.0.0",
    "precss": "^1.4.0",
    "style-loader": "^0.13.1",
    "stylus": "^0.54.5",
    "stylus-loader": "^2.3.1",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.16.2"
  }
}
$ npm i

git

$ git init
$ code .gitignore

.gitignoreを編集

node_modules
.vscode
platforms
plugins

cordovaにプラットフォーム追加

$ cordova platform add ios --save
$ cordova platform add android --save

babelの設定

$ code .babelrc

.babelrcを編集

{
  "presets": ["es2015", "react"]
}

eslintの設定

$ code .eslintrc

.eslintrcの編集

{
    "extends": "airbnb",
    "plugins": [
        "react",
        "jsx-a11y",
        "import"
    ],
    "rules": {
        "import/no-extraneous-dependencies": 0,
        "class-methods-use-this": 0,
        "import/no-unresolved": 0
    },
    "env": {
        "browser": true,
        "node": true
    }
}

.eslintignoreの設定

node_modules
webpack.config.js

webpackの設定

元となるjsを入れるフォルダを作る

$ mkdir src
$ code webpack.config.js

webpack.config.jsの編集

var path = require('path');
var ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
var precss = require('precss');
var autoprefixer = require('autoprefixer');

module.exports = {
  devtool: 'eval-source-map',
  entry: [
    './src/main'
  ],
  output: {
    path: './www',
    filename: 'bundle.js',
  },
  devServer: {
    contentBase: './www',
    port: 8080,
  },
  module: {
    preLoaders: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'eslint',
      },
    ],
    loaders: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel',
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        loader: 'file?name=assets/[name].[hash].[ext]'
      },
      {
        test: /\.styl$/,
        loader: 'style!css!postcss!stylus'
      },
      {
        test: /\.css$/,
        exclude: path.join(__dirname, 'src'),
        loader: ExtractTextWebpackPlugin.extract('style', 'css?sourceMap')
      },
      {
        test: /\.css$/,
        include: path.join(__dirname, 'src'),
        loader: 'raw'
      },
    ],
  },
  resolve: {
    root: [
      path.join(__dirname, 'src'),
      path.join(__dirname, 'node_modules'),
    ],
    extensions: ['', '.js', '.jsx', '.json', '.css', '.html', '.styl'],
    unsafeCache: true,
  },
  postcss: function() {
    return [precss, autoprefixer];
  },
  plugins: [
    new ExtractTextWebpackPlugin('[name].css'),
  ],
};

index.htmlの作成

www/index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
  <link href="./main.css" rel="stylesheet">
</head>
<body>
  <div id="app"></div>
  <script type="text/javascript" src="./bundle.js"></script>
</body>
</html>

Javascriptの作成

onsen ui + reactを使った簡単なjavascriptを作成してみる。

src/App.jsx

import React from 'react';
import { Page, Button } from 'react-onsenui';
import { notification } from 'onsenui';

export default class App extends React.Component {
  alertPopup() {
    notification.alert('こんにちは');
  }

  render() {
    return (
      <Page>
        <div>Hello World!</div>
        <Button onClick={this.alertPopup}>クリック</Button>
      </Page>
    );
  }
}

src/main.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

require('onsenui/stylus/blue-basic-theme.styl');
require('onsenui/css/onsenui.css');

ReactDOM.render(
  <App />,
  document.getElementById('app')
);

webpackする

webpackすると、www内に、assetsと、bundle.jsと、main.cssが出力される。

$ webpack

webpack-dev-serverを使う

webpack-dev-serverを使っていると、ウォッチしてくれて、対象ファイルに変更があると、webpackしなおして表示してくれる。
webpackした結果は、メモリに保存されるので、www内への展開はされない。

$ npm run start

screen

Androidの実機で確認する

$ cordova run android

画面の高さに画像サイズを合わせる

トップページのでっかい画像を画面の高さに合わせることで、スマホでもPCでも最初の表示は画面全体に画像が表示されるようにしたい。

画面の高さは、$(window).height()なんじゃないかと思っている。だから最初に、$(‘#top_img’).height($(window).height())みたいにすればいいだけなのではないかと思っております。しかし、画面リサイズ時の画像サイズ調整も考えた方がいいかもしれない。画像を入れるdivと、画像自体のサイズを変更しないといけないかもしれない。

HTML

<div class="top_box_before">
	<div class="top_box_content"></div>
</div>
<div class="top_box"></div>

CSS

.top_box, .top_box_before{
    height:600px;
}
.top_box{
    position: relative;
    width:100%;
    background-color: #fff ;
    background:no-repeat center center;
    background-size:cover;
    z-index: 0;
}
.top_box_before{
    position: absolute;
    background: rgba(33, 33, 33, 0.3);
    z-index: 1;
    width:100%;
    top:40px;
    display:table;
}

.top_boxの背景画像は、別のところで設定している。

Javascript

var h = $(window).height();
$('.top_box').height( h + 'px');
$('.top_box_before').height( h + 'px');

これだけ。画像リサイズは考慮しなくていいと思った。

スマホでfixedをサポートするのはめんどくさい

参考:
iPhone、Android position:fixed 対応状況と対応方法
Fixed固定ナビゲーションを設置するときに気をつけたい4つのこと
user-scalable=noを使う理由と弊害(スマホのviewportを見直す)

スマホではfixedがサポートされていないのがある。ios5から対応していて、Android 4.1は対応しているらしい。Android 2.3は、viewport で、content=”user-scalable=no” にすると対応されるらしい。あら、自分のAndroidは、4.1.2となってるが、fixedには対応されていないな。user-scalable=noを設定してもうまくうごかない。

今時点では確かにfixed使うと問題が多いなあ。解決は、jQuery Mobileとか、iScrollとかいうのを使う必要があるらしい。Bootstrapは大丈夫だった気がするが、あれは上記のようなツールと同じように、javascript含めて色々な調整がされているのかもしれない。

とりあえず、スマホでfixed使うのやめることにしよう。画面狭くなるしな。

いい感じにくっつけたフッターとヘッダーの間にあるコンテンツの背景を白く塗りつぶしたい

ヘッダーとフッターの間にあるコンテンツ空間はコンテンツ量によって高さが変動しますので、普通にbackgroundの背景色を設定しても、コンテンツ量が少ない場合、余白が出来てしまいます。この余白をださずに背景色で埋めたいです。

display: flexってやつが使えないだろうかと思いましたが、flexでコンテンツかこっちゃうというのは今更現実的でないので、結局javascript使っちゃうことにしました。

$(document).ready(function(){
    var f = 94;
    var height = $('#wrap').height();
    var h = $('#header').height();
    $('#contents').height(height - h - f);
});

f = 94というのは、コンテンツのfooterと重ならないようにするためのpadding-bottomの値になります。jqueryのheight関数は、paddingを除いた高さのことみたいです。

Androidで背景画像が固定できない!!

これでPCだと問題なく固定できますし、iPhoneでも問題なく固定されます。しかしながらAndroidだと固定されません!!!

body{
    background:url('../img/img.jpg') no-repeat center center fixed;
    background-size:cover;
}

PC/スマートフォンで背景画像を固定するここに書いてある方法(下記)をやってみたら、Androidだと固定されますが、今度はiPhoneで今までのAndroidと同じように固定されなくなって笑いました。残念です。

.background-hack {
    z-index                 : -1;
    background-color        : #cccccc;
    background-image        : url('images/background.jpg');
    background-repeat       : no-repeat;
    background-size         : 100% auto;
    position                : fixed;
    top                     : 0;
    left                    : 0;
    right                   : 0;
    bottom                  : 0;
}

仕方ないので、UserAgentでAndroidのときだけ、上記を適用するようにしました。

フッターをいい感じに下にくっつける

今まで僕はフッターをいい感じに下にくっつけたことがありませんでした。本日ついにいい感じに下にくっつけることが出来るようになりました。height:auto !importantというのはIE対策だそうですのでIE考えないなら不要です。wrapにcontentsとfooterを入れて、html,bodyをheight100%にして、wrapもmin-height100%にして、footerをposition:absoluteにしつつ、bottom:0にすると下にくっつきますし、コンテンツが多ければちゃんとコンテンツの最後に表示されます。基本のきだとは思いますが嬉しかったです。

#wrap{
    width:100%;
    height: auto !important;
    height: 100%;
    min-height: 100%;
    position: relative;
}
#contents{
    padding-bottom:94px;
}
#footer{
    background-color: rgba(0,0,0,.5);
    color: #eee;
    font-size:13px;
    position: absolute;
    bottom:0;
    width:100%;
    padding:15px 0 10px 0;
    text-align: center;
    height:64px;
}
#footer a, #footer a:hover{
    color: #eee;
}

CSS3 ボタンつくってみた

スクリーンショット 2013-05-23 16.23.35

/************* ボタン ***************/
.btn {
	background: -moz-linear-gradient(top,#DFE9F5, #1D25F7 50%,#0020A3 50%,#0039FE);
	background: -webkit-gradient(linear, left top, left bottom, from(#DFE9F5), color-stop(0.5,#1D25F7), color-stop(0.5,#0020A3), to(#0039FE));
	color: #FFF;
	font-size:16px;
	border-radius: 15px;
	-moz-border-radius: 15px;
	-webkit-border-radius: 15px;
	border: 1px solid #0033FF;
	-moz-box-shadow: 1px 1px 1px rgba(000,000,000,0.3),inset 0px 0px 3px rgba(255,255,255,0.5);
	-webkit-box-shadow: 1px 1px 1px rgba(000,000,000,0.3),inset 0px 0px 3px rgba(255,255,255,0.5);
	text-shadow: 0px 0px 3px rgba(0,0,0,0.5);
	width: 40%;
	padding: 5px 0;
}
.btn:hover{
	background: -moz-linear-gradient(top,#EFF9F5, #2D35F7 50%,#1030B3 50%,#1049FE);
	background: -webkit-gradient(linear, left top, left bottom, from(#EFF9F5), color-stop(0.5,#2D35F7), color-stop(0.5,#1030B3), to(#1049FE));
	color: #FFF;
	font-size:16px;
	border-radius: 15px;
	-moz-border-radius: 15px;
	-webkit-border-radius: 15px;
	border: 1px solid #1144FF;
	-moz-box-shadow: 1px 1px 1px rgba(000,000,000,0.3),inset 0px 0px 3px rgba(255,255,255,0.5);
	-webkit-box-shadow: 1px 1px 1px rgba(000,000,000,0.3),inset 0px 0px 3px rgba(255,255,255,0.5);
	text-shadow: 0px 0px 3px rgba(0,0,0,0.5);
	width: 40%;
	padding: 5px 0;
}
.btn:active {
	position:relative;
	top:1px;
}

参考:
5つの効果で作る、よく使うCSS3ボタンデザインサンプル集
CSS Button Generator

HTMLの印刷時の注意

  • IEでは幅649pxまでしか印刷できないのでそれ以内にする必要がある。あるいはwidth:autoにする。
  • media=”print”設定のスタイルシートをつくって、display: none;を設定することで印刷時に不要な箇所を削除できる。
  • 背景画像・背景色はデフォルトでは印刷されない。
  • 透過PNGはデフォルトでは印刷されない
  • しかし、CSSで、bodyとかに、-webkit-print-color-adjust: exact;という設定をするとchrome(safariもっぽい)では背景画像等が印刷されるようになる。
  • 通常のcssの後に印刷用cssをつける(後の方が優先される為)
  • ヘッダー・フッターなどはブラウザの機能であるため、URLを印刷しないなどの設定はブラウザ側で対処する必要がありHTML,CSS等での制御は基本できない
  • 強引的手法としてCSS上で、背景画像をbackground-imageではない方法で表示させることで印刷時にも表示させるようにすることが可能らしい。でも背景色は無理なんだろうから微妙。

紙サイズ(A4等)とpxの関係

紙サイズ一覧Web対応版参照

  • A4は、792×1120(px)