この記事では、CSSでkintoneアプリの見た目をデザインする方法を紹介します。
今回は、CSSでマテリアルデザインを表現してみました。
マテリアルデザインとは、UIをカードなどのリアルな物体に見立てることで、直感的な操作性を演出するデザインの手法です。
CSSの基本的な書き方を理解している方が、アプリへ適用する際の参考になるよう、具体的なサンプルコードとその解説を提供します。
また、kintone全体の見た目のカスタマイズを行う場合は
kintone全体のカスタマイズ
を参照してください。
まずは、完成したデザインのイメージを確認しましょう。
レコード内の詳細情報エリアをカード状にあしらうことで、マテリアルデザインを表現しています。
カスタマイズを適用するアプリ
固定リンクがコピーされました
今回カスタマイズするアプリは、kintoneのアプリストアからインストールできる「案件管理(営業支援パック)」です。
アプリストアから
営業支援パック
を、サンプルデータを含めるにチェックを入れた状態でインストールしてください。
警告
ここで紹介する例では、kintoneのクラス名を指定しています。
kintoneのアップデートの際に、影響を受けて動かなくなる可能性があります。
注意事項
カスタマイズで使用するソースコードを紹介します。
見た目を変更するためのCSSファイルに加え、DOM操作するためのJavaScriptファイルも作成します。
JavaScript
固定リンクがコピーされました
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/*
* Material design sample program
* Copyright (c) 2024 Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
*/
// 既存の DOM に付与する独自の クラス名を設定
const subTableClass = '.value-5517967'; // 関連レコード一覧フィールドに採番されている クラス名を指定
const classesToAdd = [
{targetDom: '.container-gaia', add: 'md-container'},
{targetDom: '#record-gaia', add: 'md-record'},
{targetDom: '.layout-gaia', add: 'md-card-wrapper'},
{targetDom: '.row-gaia', add: 'md-row'},
{targetDom: '.control-gaia', add: 'md-column'},
{targetDom: '.control-label-gaia', add: 'md-label'},
{targetDom: '.control-value-gaia', add: 'md-value'},
{targetDom: '.control-design-gaia', add: 'md-value--blanc'},
{targetDom: '.control-hr-field-gaia', add: 'md-column--hr'},
{targetDom: '.subtable-gaia', add: 'md-subtable'},
{targetDom: '.subtable-label-gaia', add: 'md-subtable-label'},
{targetDom: subTableClass, add: 'md-value--subtable'}
];
(() => {
'use strict';
const applyMaterialDesignStyles = (classesToAdd) => {
// 既存の DOM に 独自のクラス名を追加
classesToAdd.forEach(item => {
document.querySelectorAll(item.targetDom).forEach(element => {
element.classList.add(item.add);
});
});
// カードのスタイルを適用するために、既存の DOM を独自の DOM で囲う
document.querySelectorAll('.md-card-wrapper').forEach((wrapper) => {
const card = document.createElement('div');
const scrollBox = document.createElement('div');
const scrollBoxInner = document.createElement('div');
card.classList.add('md-card');
scrollBox.classList.add('md-card-scroll');
scrollBoxInner.classList.add('md-card-scroll-inner');
// .md-card-wrapper 内にあるすべての子要素 DOM を scrollBoxInner の直下に移動
while (wrapper.firstChild) {
scrollBoxInner.appendChild(wrapper.firstChild);
}
// scrollBoxInner の DOM を scrollBox の直下に移動
scrollBox.appendChild(scrollBoxInner);
// scrollBox の DOM を card の直下に移動
card.appendChild(scrollBox);
// card の DOM を wrapper の直下に移動
wrapper.appendChild(card);
});
};
kintone.events.on([
'app.record.detail.show',
'app.record.create.show',
'app.record.edit.show'
], (event) => {
applyMaterialDesignStyles(classesToAdd);
return event;
});
})();
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
* Material design sample program
* Copyright (c) 2024 Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
*/
@charset "UTF-8";
/* 【----- アプリ全体のスタイル -----】 */
.md-container .md-record#record-gaia {
font-size: 16px;
padding: 22px;
}
.md-container .md-card-wrapper.layout-gaia {
width: 100% !important;
box-sizing: border-box;
}
/* 【----- カード部分のスタイル -----】 */
.md-card {
max-width: 910px;
margin-inline: auto;
padding-block: 40px;
background-color: #fff;
border-radius: 10px;
box-shadow: 2px 0 1px rgba(0, 0, 0, .05),
-2px 0 1px rgba(0, 0, 0, .05),
0 2px 1px rgba(0, 0, 0, .05),
0 -2px 1px rgba(0, 0, 0, .05);
}
/* 【----- カードの内側のスタイル -----】 */
.md-card-scroll {
overflow: auto;
width: 100%;
}
.md-card-scroll-inner {
width: 910px;
display: grid;
grid-template-columns: 1fr;
grid-gap: 36px 0;
padding-inline: 40px;
box-sizing: border-box;
}
/* 【----- カードの内の行のスタイル -----】 */
.md-row.row-gaia {
margin: 0;
display: flex;
gap: 16px;
}
.md-row.row-gaia::after {
content: none;
}
/* 【----- カードの内のカラムのスタイル -----】 */
.md-row.row-gaia .md-column {
padding: 0;
}
.md-row.row-gaia .md-column.control-gaia.control-label-field-gaia {
padding: 0;
margin: 0;
background-color: transparent;
}
.md-column--hr {
width: 100% !important;
padding-block: 20px;
}
.md-label.control-label-gaia {
padding: 0;
margin: 0 0 12px 0;
background-color: transparent;
font-size: 16px;
font-weight: 600;
}
.showlayout-gaia .md-row.row-gaia .md-value.control-value-gaia {
border: solid 0 transparent;
padding: 6px 12px;
background-color: #f5f5f5;
border-radius: 6px;
}
.md-value + .md-value--blanc {
display: none;
}
/* 【----- 関連レコード一覧のスタイル -----】 */
.showlayout-gaia .md-row.row-gaia .md-value.md-value--subtable.control-value-gaia {
padding: 0;
overflow: hidden;
position: relative;
border: solid 1px #e3e7e8;
}
.md-subtable.subtable-gaia td:first-child,
.md-subtable.subtable-gaia td:last-child {
border-right: none;
}
.md-subtable.subtable-gaia tr:last-child td {
border-bottom: none;
}
.md-subtable-label {
font-size: 14px;
font-weight: 600;
}
|
サンプルコードの解説
固定リンクがコピーされました
サンプルコードの主なポイントについて詳しく説明します。
JavaScriptの主なポイント
固定リンクがコピーされました
まずは、既存のDOMに独自のクラス名を付与しています。
subTableClass
に、関連レコード一覧フィールドで自動採番されているクラス名を指定してください。
1
|
const subTableClass = '.value-5517967'; // 関連レコード一覧フィールドに採番されている クラス名を指定
|
たとえばGoogle Chromeでは、次の手順で上記のクラス名を取得します。
レコード詳細画面で開発者ツールを開き、「案件に紐付く活動履歴」のDOMを選択します。
このDOMのソースコードを見ると、クラス名はlabel-○○○○○○○
となっています。
このlabel-○○○○○○○
に隣接するdiv
のクラス名value-○○○○○○○
が対象になりますので、コピーして利用してください。
以下の部分では、カードのスタイルを適用するためのクラス名を指定しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
const classesToAdd = [
{targetDom: '.container-gaia', add: 'md-container'},
{targetDom: '#record-gaia', add: 'md-record'},
{targetDom: '.layout-gaia', add: 'md-card-wrapper'},
{targetDom: '.row-gaia', add: 'md-row'},
{targetDom: '.control-gaia', add: 'md-column'},
{targetDom: '.control-label-gaia', add: 'md-label'},
{targetDom: '.control-value-gaia', add: 'md-value'},
{targetDom: '.control-design-gaia', add: 'md-value--blanc'},
{targetDom: '.control-hr-field-gaia', add: 'md-column--hr'},
{targetDom: '.subtable-gaia', add: 'md-subtable'},
{targetDom: '.subtable-label-gaia', add: 'md-subtable-label'},
{targetDom: subTableClass, add: 'md-value--subtable'}
];
|
今回のカスタマイズでは、接頭辞md-
が付与されているクラス名にスタイルが適用されます。
標準で付与されているクラス名に変更があった際は、targetDom
の値を変更することで、カスタマイズが適用できるようにしています。
次に、以下の記述でカード部分のDOMを追加しています。
標準のDOM構造では、今回のカスタマイズを適用するのが難しいため、標準の<div>
内に独自の<div>
を追加しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// カードのスタイルを適用するために、既存の DOM を独自の DOM で囲う
document.querySelectorAll('.md-card-wrapper').forEach((wrapper) => {
const card = document.createElement('div');
const scrollBox = document.createElement('div');
const scrollBoxInner = document.createElement('div');
card.classList.add('md-card');
scrollBox.classList.add('md-card-scroll');
scrollBoxInner.classList.add('md-card-scroll-inner');
// .md-card-wrapper 内にあるすべての子要素 DOM を scrollBoxInner の直下に移動
while (wrapper.firstChild) {
scrollBoxInner.appendChild(wrapper.firstChild);
}
// scrollBoxInner の DOM を scrollBox の直下に移動
scrollBox.appendChild(scrollBoxInner);
// scrollBox の DOM を card の直下に移動
card.appendChild(scrollBox);
// card の DOM を wrapper の直下に移動
wrapper.appendChild(card);
});
|
出力されるhtmlは、以下のようなイメージになります。
1
2
3
4
5
6
7
8
9
10
11
|
<div class="layout-gaia showlayout-gaia md-card-wrapper"> <!-- 標準のDOM -->
<div class="md-card"> <!-- 追加したDOM 1 -->
<div class="md-card-scroll"> <!-- 追加したDOM 2 -->
<div class="md-card-scroll-inner"> <!-- 追加したDOM 3 -->
<!-- レコード詳細部分のDOM -->
</div>
</div>
</div>
</div>
|
上記のような構造にすることで、画面幅の狭いモニターでスクロールバーを出現させるCSSが指定できます。
CSSの主なポイント
固定リンクがコピーされました
カード部分には、以下のようなスタイルを指定します。
1
2
3
4
5
6
7
8
9
10
11
|
.md-card {
max-width: 910px;
margin-inline: auto;
padding-block: 40px;
background-color: #fff;
border-radius: 10px;
box-shadow: 2px 0 1px rgba(0, 0, 0, .05), /* 右方向の影 */
-2px 0 1px rgba(0, 0, 0, .05), /* 左方向の影 */
0 2px 1px rgba(0, 0, 0, .05), /* 下方向の影 */
0 -2px 1px rgba(0, 0, 0, .05); /* 上方向の影 */
}
|
box-shadow
プロパティで、要素のフレームに影を付与できます。
カンマで区切ることで、複数の値を設定できます。
たとえば、box-shadow: 2px 0 1px rgba(0, 0, 0, .05);
と指定すると、以下のような影を付与できます。
- X軸方向に2pxのオフセット
- Y軸方向に0pxのオフセット
- 1pxのぼかし
- 色が
rgba(0, 0, 0, .05)
の影
今回のカスタマイズでは、上下左右4方向に影を付与しています。
kintoneのクラス名は変更される可能性があります。
そのため先ほど利用したcontainer-gaia
などの、kintoneのクラス名を使用することは推奨されていません。
詳細は
kintoneで使われているidやclass属性
を確認してください。
カスタマイズの適用方法
固定リンクがコピーされました
JavaScript、CSSのサンプルコードはそれぞれ以下のような任意のファイル名をつけて保存します。
- material-design.js
- material-design.css
次に、「案件管理(営業支援パック)」アプリの管理画面に移動し、「設定」タブに移動します。
「カスタマイズ/サービス連携」内の「JavaScript / CSSでカスタマイズ」をクリックします。
すると、以下のような画面に移動します。
「PC用のJavaScript / CSSファイル」内の「アップロードして追加」ボタンから先ほどの2つのファイルをアップロードします。
無事、デザインが適用されました。
この記事では、kintoneのサンプルアプリ「案件管理(営業支援パック)」をCSSでカスタマイズする方法を紹介しました。
CSSを使ってアプリの見た目を自由に変更することで、より使いやすく、視覚的に魅力的なアプリが作成できます。
ぜひ、他のアプリでも同様のカスタマイズを試してみてください。