[CSS] スマホで見た時に、下固定のメニューを表示させたい

ヤフオクとかでもそうだが、SP表示の際に下に固定メニューを表示させたい。
イメージとしてはこんな感じ。

<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="styles.css" type="text/css">
</head>
<body>
	<h1>Test</h1>
	<div id="sp-fixed-menu" class="for-sp">
		<ul>
			<li><a href="#">お買い得品</a></li>
			<li><a href="#">セール品</a></li>
			<li><a href="#">カート</a></li>
		</ul>
	</div>
</body>
</html>
#sp-fixed-menu {
	position: fixed;
	width: 100%;
	bottom: 0px;
	font-size: 0;
	opacity: 0.9;
	z-index: 99;
}

#sp-fixed-menu ul {
	display: flex;
	list-style: none;
	padding: 0;
	margin: 0;
	width: 100%;
}

#sp-fixed-menu li {
	justify-content: center;
	align-items: center;
	width: 50%;
	padding: 0;
	margin: 0;
	font-size: 14px;
	border-right: 1px solid #fff;
}

#sp-fixed-menu li:first-child {
	background: #38b435;
}
#sp-fixed-menu li:nth-child(2) {
	background: #38b435;
}
#sp-fixed-menu li:last-child{
   background: #f3a324;
}

#sp-fixed-menu li a {
	color: #fff;
	text-align: center;
	display: block;
	width: 100%;
	padding: 10px;
	padding-left: 0px;
}

/* spのみ表示 */
@media (min-width: 768px){
	.for-sp {
		display: none;
	}
}

OK
さーワイヤー書くか。
一日中ワイヤー書くと、疲労感が半端ないんだよなー。

[CSS] スクロールしても横固定のメニュー

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<header id="header"></header>
<main id="main">
	<h2>MAIN BLOCK</h2>
</main>

<aside id="sub">
	<h2>Menu</h2>
	<ul>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
	</ul>
	<h2>Menu</h2>
	<ul>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
	</ul>
	<h2>Menu</h2>
	<ul>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
		<li>Subject</li>
	</ul>
</aside>
</body>
</html>
body {
	margin: 0;
	padding: 0;
}
#header {
	box-sizing: border-box;
	background: #ccc;
	height: 50px;
}
#main {
	box-sizing: border-box;
	margin-left: 220px;
	padding: 20px 40px;
}
#sub {
	box-sizing: border-box;
	top: 50px;
	height: 100%;
	width: 220px;
	position: fixed;
	overflow: auto;
	background: #eee;
	padding: 20px;
}

OK, keep goin
出掛けよう

jQueryとCSSでタブメニューを切り替える

yahooトップのタブのように、クリックしてもページ遷移しないタブを作りたい。

### jQueryとCSSで作る場合
index.html
– jqueryの制御は後から書きます。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="styles.css" type="text/css">
	<script
  src="https://code.jquery.com/jquery-3.5.1.js"
  integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
  crossorigin="anonymous"></script>
</head>
<body>
	<div class="tab">
		<ul class="tab-menu">
			<li class="tab-item active">タブ1</li>
			<li class="tab-item">タブ2</li>
			<li class="tab-item">タブ3</li>
		</ul>

		<div class="tab-box">
			<div class="tab-content show">コンテンツ1</div>
			<div class="tab-content">コンテンツ2</div>
			<div class="tab-content">コンテンツ3</div>
		</div>
	</div>
	<script>
	</script>
</body>
</html>

styles.css

* {
	box-sizing: border-box;
}
ul, li {
	padding: 0;
	margin: 0;
}
li {
	list-style: none;
}
.tab {
	width: 500px;
	max-width: 100%;
	margin: auto;
}
.tab-menu{
	display: flex;
}
.tab-item {
	text-align: center;
	padding: 10px 0;
	cursor: pointer;

	flex-grow: 1;

	border-top: 1px solid skyblue;
	border-left: 1px solid skyblue;
	border-right: 1px solid skyblue;
}
.tab-item:not(:first-child){
	border-left: none;
}
.tab-item.active {
	background: red;
	color: white;
}
.tab-box {
	height:200px;
	display: flex;
	justify-content: center;
	align-items: center;
	border: 1px solid skyblue;
}
.tab-content {
	display: none;
	font-size: 40px;
}
.tab-content.show {
	display: block;
}

jquery
– タブclick時にactiveとshowのclassをremoveして、clickされたタブのindexと同じindexにcontentのclassにshowを追加する
– タブとコンテンツの数、順番を一致させる必要がある

<script>
		$(function(){
			$('.tab-item').click(function(){
				$('.active').removeClass('active');
				$(this).addClass('active');
				$('.show').removeClass('show');

				const index = $(this).index();

				$('.tab-content').eq(index).addClass('show');
			})
		})
	</script>

### CSSのみで作る場合
index.html

<div class="tab">
		<input id="menu1" class="tab-input" name="menu" type="radio" checked="checked">
		<label for="menu1" class="tab-item">タブ1</label>
		<div class="tab-content">コンテンツ1</div>

		<input id="menu2" class="tab-input" name="menu" type="radio">
		<label for="menu2" class="tab-item">タブ2</label>
		<div class="tab-content">コンテンツ2</div>

		<input id="menu3" class="tab-input" name="menu" type="radio">
		<label for="menu3" class="tab-item">タブ3</label>
		<div class="tab-content">コンテンツ3</div>
	</div>

* {
	box-sizing: border-box;
}
input[type="radio"]{
	display:none;
}
.tab {
	width: 500px;
	max-width: 100%;
	margin: auto;
	display: flex;
	flex-flow: wrap;
}
.tab-item {
	display: block;
	flex-grow: 1;
	text-align: center;
	padding: 10px 0;
	cursor: pointer;
	order: -1;

	border-top: 1px solid skyblue;
	border-left: 1px solid skyblue;
	border-right: 1px solid skyblue;
}
.tab-item:not(:first-of-type){
	border-left: none;
}
.tab-input:checked + .tab-item {
	background: red;
	color: white;
}
.tab-content {
	width: 100%;
	height: 200px;
	display: none;
	justify-content: center;
	align-items:center;
	font-size: 40px;
	border: 1px solid skyblue;
}

.tab-input:checked + .tab-item + .tab-content {
	display: flex;
}

input formとradioボタンで切り替えるってなんか違和感あるけど、うまく表示されますね。
思ったより簡単でワロタ。

footer下固定のcss

/dist/login/html

<body>
	<div class="wrapper">
		<div class="container">
			// 省略
		</div>
		<footer>
			<p>(c)hanbai all right reserved.</p>
		</footer>
	</div>
</body>

/src/scss/style.scss

.wrapper {
	min-height: 100vh;
	position: relative;
	padding-bottom: 120px;
	box-sizing: border-box;
}
footer {
	width: 100%;
	background-color: #89c7de;
	color: #fff;
	text-align: center;
	padding: 30px 0;

	position: absolute;
	bottom: 0;
}

pc

sp

OK! 続いてTopページを作っていきます^^

あ、コピーライトはhtmlでは &copyでした。

		<footer>
			<p>&copy; hanbai All Right Reserved.</p>
		</footer>

ま、Djangoのインクルード時に修正すればいいのですが、気づいたタイミングで変えます。

cssのmozとwebkit

ベンダープレフィックスとは、ブラウザベンダーが独自の拡張機能を実装する際に、それが拡張機能であることを明示するために付ける識別子
/src/scss/style.scss

body {
	height: 100%;
	background-color: #fff;
}

.login {
	.card-container.card {
		max-width: 350px;
		padding: 40px 40px;
	}
	.btn {
		font-weight: 700;
		height: 36px;
		-moz-user-select: none;
		-webkit-user-select: none;
		user-select: none;
		cursor: default;
	}
	.card {
		background-color: #F7F7F7;
		padding: 20px 25px 30px;
		margin: 0 auto 25px;
		margin-top: 50px;
		-moz-border-radius: 2px;
		-webkit-border-radius: 2px;
		border-radius: 2px;
		-moz-box-shadow: 0px 2px 2px rgba(0,0,0,0.3);
		-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
		box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
	}
	.profile-img-card {
		width: 96px;
		height: 96px;
		margin: 0 auto 10px;
		display: block;
		-moz-border-radius: 50%;
		-webkit-border-radius: 50%;
		border-radius: 50%;
	}
	.form-signin #inputEmail, .form-signin #inputPassword {
		direction: ltr;
		height: 44px;
		font-size: 16px;
	}
	.form-signin input[type="email"], .form-signin input[type="password"], .form-signin input[type="text"], .form-signin button {
		width: 100%;
		diplay: block;
		margin-bottom: 10px;
		z-index: 1;
		postion: relative;
		-moz-box-sizing: border-box;
		-webkit-box-sizing: border-box;
		box-sizing: border-box;
	}
	.form-signin .form-control:focus {
		border-color: rgb(104, 145, 162);
		outline: 0;
		-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.75), 0 0 8px rgb(104, 145, 162);
		box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgb(104, 145, 162);
	}
	.btn.btn-signin {
		background-color: rgb(104, 145, 162);
		padding: 0px;
		font-weight: 700;
		font-size: 14px;
		height: 36px;
		-moz-border-radius: 3px;
		-webkit-border-radius: 3px;
		border-radius: 3px;
		border: none;
		-o-transition: all 0.218s;
		-moz-transition: all 0.218s;
		-webkit-transition: all 0.218s;
		transition: all 0.218s;
	}
}

うむ、まあまあいい感じ。

webpack環境設定: style.cssの設定

### 前提条件
– node:v12.18.3、npm:6.14.6
– webpack, webpack-cli, webpack-dev-serverインストール済

### Style LoaderとCSS Loaderのインストール
$ npm i -D style-loader css-loader

– 拡張子.cssファイルに対して、useで指定したLoaderが後ろから順番に適用される
– cssファイル -> css-loader -> style-loader -> main.js
webpack.config.js

module.exports = {
	// 省略

	module: {
		rules: [
			{
				test: /\.css/,
				use: [
					"style-loader",
					{
						loader: "css-loader",
						options: { url: false }
					}
				]
			}
		]
	}
};

/src/index.js

import "./style.css";

/src/style.css

$ npm run build
-> style.cssが /dist/main.jsにバンドルされる

### ソースマップの出力
– ソースマップとは変換前のコード情報
webpack.config.js

const MODE = "development";
const enabledSourceMap = MODE === "development";

module.exports = {

	entry: `./src/index.js`,

	output: {
		filename: "main.js"
	},

	devServer: {
		host: '192.168.33.10',
		port: '8000',
		contentBase: "dist",
		open: true
	},

	module: {
		rules: [
			{
				test: /\.css/,
				use: [
					"style-loader",
					{
						loader: "css-loader",
						options: { 
							url: false,
							sourceMap: enabledSourceMap
						}
					}
				]
			}
		]
	}
};

さあ、続いてSassに行きます。

BEMとは

BEMとは
– フロントエンドの設計方法
– Block、Element、Modifier
– 厳格なclass名の命名ルール
https://en.bem.info/methodology/

背景
– スタイルの優先順位の指定が難しい
– !importantの多用
– パーツを別の場所に流用すると表示が崩れる
– 制作者本人しかわからないclass名

制作ボリュームが膨大になった時、全体像を誰も理解できないってのはよくありますね。
特に、長いサービスだと、前任者が全員退職して、知っている人がいないとか。

BEMではパーツをBlockと呼ぶ
Blockはid属性ではなく、classを使う
※idは1ページ1回、classは重複利用可能
Blockは入れ子にしない

ElementはBlockの構成要素
Elementのclass名はblockの構成要素名を入れる

.search
.search__input
.search__button


Modiferは既存のBlockやElementと似た物を作りたいとき

<ul class="list  list_type_disc">
  <li class="list__item"></li>
  <li class="list__item"></li>
  ...
</ul>
 
<ul class="list  list_type_check">
  <li class="list__item"></li>
  <li class="list__item"></li>
  ...
</ul>

BEMでは、block, element, modiferで一貫したセパレーター(_)を使う

modife: Block_key_value
単語はハイフン(-)もしくはキャメルケースなど

で、BEMはどれ位使われているかというと、50%くらい
50%といえば、かなりの割合ですなー

Q&Aの見出しをCCSで装飾(邪道?)

[ccs]
#qa dt .q {
padding:2px 5px 2px 5px;
background-color:orangered;
color:#fff;
margin-right:5px;
}
#qa dd .a {
padding:2px 5px 2px 5px;
background-color:orangered;
color:#fff;
margin-right:5px;
}
[/ccs]

邪道かな。やっぱimgでやるべきか。。

Specifying multiple elements in CCS

Specify CCS by separating element name + class name with comma.
The same style can be applied by separating element name + class name with comma.
[ccs]
#right-contents input[type=”text”], #right-contents input[type=”email”], #right-contents [type=”number”] {
width: 45%;
height: 3.5%;
border-radius: 5px;
background-color: #a9a9a9;
color: #f5f5f5;
padding-left: 3%;
font-size: 15px;
}
[/ccs]

なるほど~