├── .editorconfig
├── .github
├── renovate.json
└── workflows
│ ├── static.yml
│ └── test.yml
├── .gitignore
├── .prettierrc.mjs
├── .textlintrc.js
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── cspell.json
├── eslint.config.js
├── lint-staged.config.mjs
├── package.json
├── src
├── .vitepress
│ ├── config.js
│ └── theme
│ │ ├── custom.css
│ │ └── index.js
├── browsers.md
├── contributing.md
├── css
│ ├── builder.md
│ ├── ids.md
│ ├── index.md
│ ├── order.md
│ ├── rules.md
│ ├── selectors.md
│ ├── structure.md
│ ├── style.md
│ ├── values.md
│ └── variables.md
├── environment.md
├── git
│ ├── branches.md
│ ├── hooks.md
│ ├── index.md
│ └── workflow.md
├── html
│ ├── accessibility.md
│ ├── builder.md
│ ├── components.md
│ ├── doctype.md
│ ├── elements.md
│ ├── ids.md
│ ├── index.md
│ ├── interactions.md
│ ├── links.md
│ ├── meta.md
│ ├── structure.md
│ └── style.md
├── img
│ └── breakpoint.png
├── index.md
├── js
│ ├── builder.md
│ ├── development.md
│ ├── index.md
│ ├── interactions.md
│ ├── libraries.md
│ ├── loading.md
│ ├── no-style-attr.md
│ ├── performance.md
│ ├── structure.md
│ └── style.md
├── media
│ ├── audio.md
│ ├── font.md
│ ├── image.md
│ ├── index.md
│ └── video.md
├── naming
│ ├── abbreviation.md
│ ├── consistency.md
│ ├── index.md
│ ├── principles.md
│ ├── spelling.md
│ └── structure.md
├── preparation.md
├── public
│ └── favicon.png
├── roles.md
├── rules.md
├── testing.md
├── text-files.md
├── tools
│ └── setup-volta.md
└── versioning.md
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # https://editorconfig.org
2 | root = true
3 | indent_style = tab
4 | indent_size = 2
5 |
6 | [*.md]
7 | trim_trailing_whitespace = false
8 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "configMigration": true,
4 | "extends": [
5 | "config:recommended",
6 | "docker:pinDigests",
7 | "helpers:pinGitHubActionDigests",
8 | ":pinDevDependencies",
9 | ":semanticCommitTypeAll(chore)"
10 | ],
11 | "lockFileMaintenance": {
12 | "enabled": true,
13 | "automerge": true
14 | },
15 | "autoApprove": true,
16 | "labels": ["Dependencies", "Renovate"],
17 | "packageRules": [
18 | {
19 | "matchDepTypes": ["optionalDependencies"],
20 | "addLabels": ["Dependencies: Optional"]
21 | },
22 | {
23 | "matchDepTypes": ["devDependencies"],
24 | "addLabels": ["Dependencies: Development"]
25 | },
26 | {
27 | "matchDepTypes": ["dependencies"],
28 | "addLabels": ["Dependencies: Production"]
29 | },
30 | {
31 | "description": "Automerge non-major updates",
32 | "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
33 | "matchCurrentVersion": "!/^0/",
34 | "automerge": true
35 | }
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/.github/workflows/static.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Pages
2 |
3 | on:
4 | push:
5 | branches: ['main']
6 |
7 | permissions:
8 | contents: read
9 | pages: write
10 | id-token: write
11 |
12 | concurrency:
13 | group: 'pages'
14 | cancel-in-progress: true
15 |
16 | jobs:
17 | # Single deploy job since we're just deploying
18 | deploy:
19 | environment:
20 | name: github-pages
21 | url: ${{ steps.deployment.outputs.page_url }}
22 | runs-on: ubuntu-latest
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
26 | - name: Use Node.js
27 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
28 | with:
29 | node-version: 22
30 | - name: Install dependencies
31 | run: yarn install
32 | - name: Build Pages
33 | run: yarn build
34 | - name: Setup Pages
35 | uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
36 | - name: Upload artifact
37 | uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
38 | with:
39 | # Upload entire repository
40 | path: '.dist'
41 | - name: Deploy to GitHub Pages
42 | id: deployment
43 | uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
44 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - dev
7 |
8 | jobs:
9 | test:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout code
13 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
14 |
15 | - name: Setup Node.js
16 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
17 | with:
18 | node-version: 22
19 | - name: Cache dependencies
20 | id: cache-depends
21 | uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
22 | with:
23 | path: '**/node_modules'
24 | key: depends-${{ hashFiles('yarn.lock') }}
25 | - name: Install dependencies
26 | if: steps.cache-depends.outputs.cache-hit != 'true'
27 | run: yarn --frozen-lockfile --check-files
28 | - name: Lint
29 | run: yarn lint
30 | - name: Build
31 | run: yarn build
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # macOS
2 | .DS_Store
3 |
4 | # Dist *.js sources
5 | lib
6 |
7 | # Logs
8 | logs
9 | *.log
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Runtime data
15 | pids
16 | *.pid
17 | *.seed
18 | *.pid.lock
19 |
20 | # Directory for instrumented libs generated by jscoverage/JSCover
21 | lib-cov
22 |
23 | # Coverage directory used by tools like istanbul
24 | coverage
25 |
26 | # nyc test coverage
27 | .nyc_output
28 |
29 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
30 | .grunt
31 |
32 | # Bower dependency directory (https://bower.io/)
33 | bower_components
34 |
35 | # node-waf configuration
36 | .lock-wscript
37 |
38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
39 | build/Release
40 |
41 | # Dependency directories
42 | node_modules/
43 | jspm_packages/
44 |
45 | # TypeScript v1 declaration files
46 | typings/
47 |
48 | # Optional npm cache directory
49 | .npm
50 |
51 | # Optional eslint cache
52 | .eslintcache
53 |
54 | # Optional REPL history
55 | .node_repl_history
56 |
57 | # Output of 'npm pack'
58 | *.tgz
59 |
60 | # Yarn Integrity file
61 | .yarn-integrity
62 |
63 | # dotenv environment variables file
64 | .env
65 |
66 | # next.js build output
67 | .next
68 |
69 | # TypeScript
70 | *.tsbuildinfo
71 |
72 | # Secret Test
73 | test/fixture/.__*
74 |
75 | # Vitepress
76 | src/.vitepress/cache
77 |
78 | # Pages
79 | .dist
80 |
--------------------------------------------------------------------------------
/.prettierrc.mjs:
--------------------------------------------------------------------------------
1 | export { default } from '@d-zero/prettier-config';
2 |
--------------------------------------------------------------------------------
/.textlintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ...require('@d-zero/textlint-config'),
3 | 'no-mix-dearu-desumasu': {
4 | preferInHeader: 'である',
5 | preferInBody: 'ですます',
6 | preferInList: 'である',
7 | strict: true,
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dbaeumer.vscode-eslint",
4 | "editorconfig.editorconfig",
5 | "esbenp.prettier-vscode",
6 | "streetsidesoftware.code-spell-checker"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib",
3 | "editor.defaultFormatter": "esbenp.prettier-vscode",
4 | "eslint.validate": ["javascript", "typescript"],
5 | "editor.formatOnSave": true,
6 | "editor.codeActionsOnSave": {
7 | "source.fixAll.eslint": "explicit"
8 | },
9 | "github.copilot.enable": {
10 | "*": true,
11 | "plaintext": false,
12 | "log": false,
13 | "dotenv": false,
14 | "markdown": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2024 D-ZERO Co., Ltd.
2 |
3 | Licensed under CC BY-NC-SA 4.0
4 | https://creativecommons.org/licenses/by-nc-sa/4.0/
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ディーゼロ フロントエンドガイドライン
2 |
3 | 株式会社ディーゼロの主にフロントエンド開発のために規定しているガイドラインです。
4 |
5 | Copyright (c) 2024 D-ZERO Co., Ltd. Licensed under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
6 |
--------------------------------------------------------------------------------
/cspell.json:
--------------------------------------------------------------------------------
1 | {
2 | "import": ["@d-zero/cspell-config"],
3 | "ignorePaths": [".vscode/*"],
4 | "words": [
5 | //
6 | "huskyrc",
7 | "nodist",
8 | "Splide",
9 | "splidejs",
10 | "vitepress",
11 | "WCAG"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import dz from '@d-zero/eslint-config';
2 |
3 | /**
4 | * @type {import('eslint').Linter.Config[]}
5 | */
6 | export default [
7 | ...dz.configs.standard,
8 | {
9 | files: ['.textlintrc.js'],
10 | ...dz.configs.commonjs,
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/lint-staged.config.mjs:
--------------------------------------------------------------------------------
1 | import lintStagedConfigGenerator from '@d-zero/lint-staged-config';
2 | export default lintStagedConfigGenerator();
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@d-zero/frontend-guidelines",
3 | "version": "5.0.0-alpha.0",
4 | "description": "D-ZERO Frontend Developer's Guideline",
5 | "repository": "https://github.com/d-zero-dev/frontend-guidelines.git",
6 | "author": "D-ZERO Co., Ltd.",
7 | "license": "CC BY-NC-SA 4.0",
8 | "private": true,
9 | "type": "module",
10 | "scripts": {
11 | "dev": "vitepress dev src",
12 | "build": "vitepress build src",
13 | "lint": "run-s lint:eslint lint:prettier lint:textlint lint:cspell",
14 | "lint:cspell": "cspell --no-progress --show-suggestions \"{*,src/{**,.vitepress/**}/*}/\"",
15 | "lint:eslint": "eslint --fix \"*.{js,cjs,mjs}\"",
16 | "lint:prettier": "prettier --write \"{*,src/{**,.vitepress/**}/*}.{md,json,js,cjs,mjs,jsx,ts,cts,mts,tsx}\"",
17 | "lint:textlint": "textlint --fix ./src/{**,.vitepress/**}/*.md; textlint ./src/{**,.vitepress/**}/*.md",
18 | "up": "yarn upgrade-interactive --latest"
19 | },
20 | "devDependencies": {
21 | "@d-zero/cspell-config": "5.0.0-alpha.63",
22 | "@d-zero/eslint-config": "5.0.0-alpha.63",
23 | "@d-zero/lint-staged-config": "5.0.0-alpha.63",
24 | "@d-zero/prettier-config": "5.0.0-alpha.63",
25 | "@d-zero/textlint-config": "5.0.0-alpha.63",
26 | "@d-zero/tsconfig": "0.4.1",
27 | "mermaid": "11.6.0",
28 | "npm-run-all2": "8.0.4",
29 | "typescript": "5.8.3",
30 | "vitepress": "1.6.3",
31 | "vitepress-plugin-mermaid": "2.0.17"
32 | },
33 | "volta": {
34 | "node": "22.16.0",
35 | "yarn": "1.22.22"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/.vitepress/config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitepress';
2 | import { withMermaid } from 'vitepress-plugin-mermaid';
3 |
4 | export default async () => {
5 | return withMermaid(
6 | defineConfig({
7 | outDir: process.cwd() + '/.dist',
8 | lang: 'ja',
9 | title: 'D-ZERO Guidelines',
10 | description:
11 | '株式会社ディーゼロの主にフロントエンド開発のために規定しているガイドラインです。',
12 | head: [['link', { rel: 'icon', type: 'image/png', href: '/favicon.png' }]],
13 | themeConfig: {
14 | search: {
15 | provider: 'local',
16 | },
17 | nav: [
18 | {
19 | text: 'コーディングガイドライン',
20 | link: '/',
21 | },
22 | {
23 | text: 'コンポーネント集',
24 | link: 'https://components.d-zero.co.jp/',
25 | target: '_blank',
26 | },
27 | {
28 | text: 'GitHub',
29 | link: 'https://github.com/d-zero-dev',
30 | target: '_blank',
31 | },
32 | ],
33 | sidebar: [
34 | {
35 | text: '🚩 コーディングガイドライン',
36 | link: '/',
37 | collapsed: true,
38 | items: [
39 | { text: 'ガイドラインの更新', link: '/contributing' },
40 | { text: '制作に取り掛かる前に', link: '/preparation' },
41 | { text: '対応ブラウザとデバイス', link: '/browsers' },
42 | { text: 'プロジェクトのルールの最適化', link: '/rules' },
43 | { text: '責任者の選任', link: '/roles' },
44 | { text: '制作環境', link: '/environment' },
45 | { text: 'バージョン管理', link: '/versioning' },
46 | { text: 'テキストファイルに関して', link: '/text-files' },
47 | { text: '検証とテスト', link: '/testing' },
48 | ],
49 | },
50 | {
51 | text: '🛤 Gitガイドライン',
52 | link: '/git/',
53 | collapsed: true,
54 | items: [
55 | { text: 'ブランチとテストサイト', link: '/git/branches' },
56 | { text: 'pre-commitフック', link: '/git/hooks' },
57 | { text: 'Git操作手順', link: '/git/workflow' },
58 | ],
59 | },
60 | {
61 | text: '📛 識別子の命名規則',
62 | link: '/naming/',
63 | collapsed: true,
64 | items: [
65 | { text: '命名方針', link: '/naming/principles' },
66 | { text: 'スペルチェック', link: '/naming/spelling' },
67 | { text: '文字構成', link: '/naming/structure' },
68 | { text: '省略', link: '/naming/abbreviation' },
69 | { text: '識別子の統一', link: '/naming/consistency' },
70 | ],
71 | },
72 | {
73 | text: '📗 HTMLガイドライン',
74 | link: '/html/',
75 | collapsed: true,
76 | items: [
77 | { text: 'コードスタイル', link: '/html/style' },
78 | { text: 'ファイル構成', link: '/html/structure' },
79 | { text: 'ビルド環境', link: '/html/builder' },
80 | { text: 'DOCTYPE', link: '/html/doctype' },
81 | { text: 'メタ要素', link: '/html/meta' },
82 | { text: 'パスとリンク', link: '/html/links' },
83 | { text: 'コンポーネント', link: '/html/components' },
84 | {
85 | text: 'メインコンテンツのエレメントとヘルパークラス',
86 | link: '/html/elements',
87 | },
88 | { text: 'id属性の利用', link: '/html/ids' },
89 | { text: 'セマンティックとアクセシビリティ', link: '/html/accessibility' },
90 | { text: 'インタラクションの実装', link: '/html/interactions' },
91 | ],
92 | },
93 | {
94 | text: '📘 CSSガイドライン',
95 | link: '/css/',
96 | collapsed: true,
97 | items: [
98 | { text: 'コードスタイル', link: '/css/style' },
99 | { text: 'ビルド環境', link: '/css/builder' },
100 | { text: 'ファイル構成', link: '/css/structure' },
101 | { text: 'IDセレクタの利用の禁止', link: '/css/ids' },
102 | { text: 'ルールの定義規則', link: '/css/rules' },
103 | { text: 'タイプセレクタの利用', link: '/css/selectors' },
104 | { text: '記述順番', link: '/css/order' },
105 | {
106 | text: 'カスタムプロパティ・カスタムクエリー・変数・関数・ミックスイン・プレースホルダー',
107 | link: '/css/variables',
108 | },
109 | { text: '値のルール', link: '/css/values' },
110 | ],
111 | },
112 | {
113 | text: '🖼️ 画像・メディアリソースガイドライン',
114 | link: '/media/',
115 | collapsed: true,
116 | items: [
117 | { text: '画像', link: '/media/image' },
118 | { text: '動画', link: '/media/video' },
119 | { text: '音声', link: '/media/audio' },
120 | { text: 'フォント', link: '/media/font' },
121 | ],
122 | },
123 | {
124 | text: '📙 JavaScriptガイドライン',
125 | link: '/js/',
126 | collapsed: true,
127 | items: [
128 | { text: 'コードスタイル', link: '/js/style' },
129 | { text: 'ビルド環境', link: '/js/builder' },
130 | { text: 'ファイル構成', link: '/js/structure' },
131 | { text: 'HTMLへの読み込み', link: '/js/loading' },
132 | { text: '開発ファイル', link: '/js/development' },
133 | { text: 'インタラクションの実装', link: '/js/interactions' },
134 | { text: 'ライブラリ・モジュールの利用', link: '/js/libraries' },
135 | { text: 'style属性をなるべく変更しない', link: '/js/no-style-attr' },
136 | { text: 'パフォーマンスを意識した実装', link: '/js/performance' },
137 | ],
138 | },
139 | ],
140 | footer: {
141 | message: 'Licensed under CC BY-NC-SA 4.0',
142 | copyright: 'Copyright © 2024 D-ZERO Co., Ltd.',
143 | },
144 | editLink: {
145 | pattern:
146 | 'https://github.com/d-zero-dev/frontend-guidelines/edit/main/src/:path',
147 | text: 'GitHubで編集する',
148 | },
149 | lastUpdated: {
150 | text: '最終更新日',
151 | formatOptions: {
152 | dateStyle: 'long',
153 | },
154 | },
155 | },
156 | }),
157 | );
158 | };
159 |
--------------------------------------------------------------------------------
/src/.vitepress/theme/custom.css:
--------------------------------------------------------------------------------
1 | .VPNav {
2 | a.title {
3 | text-wrap: auto;
4 | }
5 | }
6 |
7 | .vp-doc div[class*='language-'] + div[class*='language-'],
8 | .vp-doc div[class$='-api'] + div[class*='language-'],
9 | .vp-doc div[class*='language-'] + div[class$='-api'] > div[class*='language-'] {
10 | margin-block-start: 1em;
11 | }
12 |
13 | @media print {
14 | .VPNav {
15 | position: relative !important;
16 | }
17 |
18 | .VPLocalNav {
19 | display: none !important;
20 | }
21 |
22 | .vp-doc [class*='language-'] {
23 | border: 1px solid gray;
24 | }
25 |
26 | .vp-doc [class*='language-'] :is(pre, code) {
27 | white-space: pre-wrap;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/.vitepress/theme/index.js:
--------------------------------------------------------------------------------
1 | import DefaultTheme from 'vitepress/theme';
2 | import './custom.css';
3 |
4 | export default DefaultTheme;
5 |
--------------------------------------------------------------------------------
/src/browsers.md:
--------------------------------------------------------------------------------
1 | # 対応ブラウザとデバイス
2 |
3 | - Windows Edge / Chrome / Firefox: いずれもリリース時点での最新版
4 | - macOS Chrome / Firefox: いずれもリリース時点での最新版
5 | - macOS Safari : リリース時点での最新版とその 1 つ前のマイナーバージョン
6 | - Android Chrome: リリース時点での最新版
7 | - iOS Safari : リリース時点での最新版とその 1 つ前のマイナーバージョン
8 |
9 | ::: danger レガシーブラウザへの対応
10 | 上記以外のバージョンおよびレガシーブラウザへの対応は案件に合わせて対応しても構いません。
11 | ただし原則として**追加費用**が発生するため、クライアントとの契約に基づいて対応してください。
12 | :::
13 |
--------------------------------------------------------------------------------
/src/contributing.md:
--------------------------------------------------------------------------------
1 | # ガイドラインの更新
2 |
3 | このガイドラインは日々更新されるウェブの技術やトレンドによって最適化されるべきです。
4 | 変更・追記・削除に関しては常に議論されることが期待されます。
5 | 集めた意見や議論の結果は、リードエンジニアのもとで更新するか判断されます。
6 | プルリクエストを送ることもでき、その場合もリードエンジニアの判断によりマージされます。
7 |
--------------------------------------------------------------------------------
/src/css/builder.md:
--------------------------------------------------------------------------------
1 | # ビルド環境
2 |
3 | *11ty*のTransform機能から[*Vite*のCSS変換](https://ja.vitejs.dev/guide/features#css)を利用します。プリプロセッサーはSassを利用します。
4 |
5 | ```mermaid
6 | flowchart LR
7 | #in["*.scss"]
8 | #out["*.css"]
9 | #vite(["Vite"])
10 |
11 | #in --> #dzBuilder --> #out
12 |
13 | subgraph #dzBuilder["@d-zero/builder"]
14 | direction LR
15 |
16 | subgraph #11ty["11ty"]
17 | subgraph #vite["vite"]
18 | direction TB
19 | #sass --> #postcss
20 | end
21 | end
22 | end
23 | ```
24 |
25 | ## ベンダープレフィックス
26 |
27 | *Autoprefixer*を利用するのでベンダープレフィックス付きのプロパティは必要ありません。
28 |
29 | ```scss
30 | selector {
31 | transition: opacity 300ms;
32 | -webkit-transition: opacity 300ms; // ❌ 不要
33 | -moz-transition: opacity 300ms; // ❌ 不要
34 | }
35 | ```
36 |
37 | ただしCSSの標準規格でないものについては必要なケースがあります。*Stylelint*はその点を考慮して警告を出すので心配はありません。
38 |
39 | ```scss
40 | selector {
41 | -moz-osx-font-smoothing: grayscale; // ✅ ブラウザ固有のプロパティのためプレフィックは必要
42 | -webkit-font-smoothing: antialiased; // ✅ ブラウザ固有のプロパティのためプレフィックは必要
43 | }
44 | ```
45 |
46 | ::: tip 🔧 自動修正可能
47 | このルールは*Stylelint*によって自動修正されます。
48 | :::
49 |
--------------------------------------------------------------------------------
/src/css/ids.md:
--------------------------------------------------------------------------------
1 | # IDセレクタの利用の禁止
2 |
3 | 詳細度で問題を起こすのでIDをセレクタとしてスタイルを定義しないでください。
4 |
--------------------------------------------------------------------------------
/src/css/index.md:
--------------------------------------------------------------------------------
1 | # CSS ガイドライン
2 |
3 | 🔰 当ドキュメントは「[コーディングガイドライン](../index.md)」の一部です。
4 | 基本的なガイドライン・ルールについては先にそれから確認してください。
5 |
6 | ## CSS ガイドラインの目的
7 |
8 | CSSのガイドラインは次の3つを主な目的として策定されています。
9 |
10 | - 確実性
11 | - 影響範囲が明瞭であること
12 | - 確実に場所を特定して追加・変更ができること
13 | - 機能性
14 | - 命名規則が機能的でその機能が予測し易くあること
15 | - プロジェクトにヘルプアサインされてもほとんどが判断がつくこと
16 | - 一貫性
17 | - 一貫した汎用ルールがあることでプロジェクト独自ルールの氾濫を避けられること
18 | - プロジェクトをまたいでも混乱することがないこと
19 |
20 | ### 作用をきちんと理解する
21 |
22 | 「何故か解らないけど出来た」は一番やってはいけません。プロパティひとつひとつ、セレクタひとつひとつが、どういった作用をするかきちんと理解してコーディングすることを心掛けてください。
23 |
24 | ### 別解を用意すること
25 |
26 | ほとんどの場合、表現の方法はひとつではありません。メンテナンス性を優先させた方法、パフォーマンスを優先させた方法など、そのときそのときで最適な方法を探す必要があります。常にいくつかのパターンを考えながらコーディングできるように心掛けてください。また、万が一にブラウザの予期せぬバグに遭遇した際にも別解で解決する必要があります。
27 |
--------------------------------------------------------------------------------
/src/css/order.md:
--------------------------------------------------------------------------------
1 | # 記述順番
2 |
3 | 以下のような順番で定義します。
4 |
5 | ```scss
6 | .component-name {
7 | // 1. 変数定義
8 | // 2. コンポーネント自体のスタイル
9 | // 3. 疑似要素
10 | // 4. 状態変化(※)
11 | // 4-1. メディアクエリ
12 | // 4-2. 疑似クラス(:hover :disabled :nth-child :empty など)
13 | // 4-3. 属性
14 | // 4-4. 状態クラス (&--[状態])
15 | // 5. エレメント
16 | // 6. 結合子セレクタを利用したエレメント(E+E E~E など)
17 | // 7. 子孫要素に影響のある状態変化
18 | }
19 | /* EOF */
20 | ```
21 |
22 | また、プロパティについては*Stylelint*の設定に基づいて種類順に記述します。
23 |
24 | ::: tip 👮♀️ 自動検知
25 | このルールは*Stylelint*によって警告されます。
26 | :::
27 |
28 | ::: danger クラス名の例外
29 |
30 | JavaScript のライブラリの利用など、クラス命名規則に当てはまらないセレクタにスタイルを当てないといけない場合があります。その場合は、`.stylelintrc`ファイルにて`selector-class-pattern`を変更してください。
31 |
32 | ```scss
33 | .c-hero {
34 | // ⚠️ 通常はStylelintによる警告がでる
35 | .any-js-lib-class-name {
36 | /* declaration */
37 | }
38 | }
39 |
40 | .c-hero {
41 | // ✅ .stylelintrcの設定変更によって警告がなくなる
42 | .any-js-lib-class-name {
43 | /* declaration */
44 | }
45 | }
46 | ```
47 |
48 | :::
49 |
--------------------------------------------------------------------------------
/src/css/rules.md:
--------------------------------------------------------------------------------
1 | # ルールの定義規則
2 |
3 | headerコンポーネントの場合を例に解説します。
4 |
5 | 1階層目のセレクタはコンポーネントの定義となり、SCSSファイル内に一度だけ登場するようにします。
6 | ファイルパスは `__assets/_libs/style/component/c-header.scss` となります。
7 |
8 | ```scss
9 | .c-header {
10 | /* declaration */
11 | }
12 | /* EOF */
13 | ```
14 |
15 | 次にエレメントは、それにネストする形で`&`を利用したセレクタをつくります。
16 |
17 | ```scss
18 | .c-header {
19 | /* declaration */
20 |
21 | &__body {
22 | /* declaration */
23 | }
24 |
25 | &__title {
26 | /* declaration */
27 | }
28 |
29 | &__site-name {
30 | /* declaration */
31 | }
32 | }
33 | /* EOF */
34 | ```
35 |
36 | こうすることで、このファイルに記述されたスタイルの影響範囲が、コンポーネント内であることを保証します。
37 |
38 | 状態変化を表す場合も`&`を利用してネストして定義します。メディアクエリの定義も、ユーザエージェントの状態変化と捉えて同様にネストして定義します。
39 |
40 | 状態変化がエレメントを巻き込む場合はコードを後ろにまわして記述します。また、`&`がコンポーネントのクラスを表さないようなネストの状態になる場合があるので変数化して定義します。
41 |
42 |
43 |
44 | ```scss
45 | .c-header {
46 | --foo-bar: 0; // カスタムプロパティ
47 | --foo-baz: calc(32 / 16 * 1em); // カスタムプロパティ
48 |
49 | /* declaration */
50 |
51 | @media (--sm-lte) { /* declaration */ } // メディアクエリ
52 | &:hover { /* declaration */ } // 疑似クラス
53 | &--compact-mode { /* declaration */ } // 状態クラス
54 | &[data-compact-mode="true"] { /* declaration */ } // data属性
55 | &[aria-hidden="true"] { /* declaration */ } // aria属性
56 |
57 | &__body {
58 | /* declaration */
59 |
60 | // 子孫要素も同様のルールになる
61 | @media (--sm-lte) { /* declaration */ } // メディアクエリ
62 | &:hover { /* declaration */ } // 疑似クラス
63 | &--compact-mode { /* declaration */ } // 状態クラス
64 | &[data-compact-mode="true"] { /* declaration */ } // data属性
65 | &[aria-hidden="true"] { /* declaration */ } // aria属性
66 | }
67 |
68 | // 影響がエレメントを巻き込む場合は、後ろに記述する
69 | &[data-fat-mode="true"] {
70 | /* declaration */
71 |
72 | .c-header__body { // ⚠️ `&` が使用できないスコープでは直接クラスを記述する
73 | /* declaration */
74 | }
75 | }
76 | }
77 | /* EOF */
78 | ```
79 |
80 |
81 | 疑似要素は子孫要素の前に定義し、これも`&`を利用する。疑似要素セレクタは`::`で定義してください。
82 |
83 |
84 | ```scss
85 | .c-header {
86 | /* declaration */
87 |
88 | &[data-compact-mode="true"] { /* declaration */ }
89 |
90 | &::before { /* declaration */ }
91 | &::after { /* declaration */ }
92 |
93 | &__body {
94 | /* declaration */
95 | }
96 | }
97 | /* EOF */
98 | ```
99 |
100 |
101 | ::: warning `&`でクラス名を連結する是非について
102 | フルのクラス名が検索にヒットしない理由から忌避されることがありますが、コンポーネントのクラス名とファイル名が一致していることを前提にしているため、`&`を利用してネストして記述するルールを採用しています。
103 | :::
104 |
105 | ::: tip 👮♀️ 自動検知
106 | このルールは*Stylelint*によって警告されます。
107 | :::
108 |
--------------------------------------------------------------------------------
/src/css/selectors.md:
--------------------------------------------------------------------------------
1 | # タイプセレクタの利用
2 |
3 | ::: danger 重要
4 |
5 | タイプセレクタの利用は可能ですが**コンポーネントはコンポーネントを内包できる**点に注意してください。
6 |
7 | :::
8 |
9 | ```scss
10 | .c-header {
11 | /* declaration */
12 |
13 | ul {
14 | /* declaration */
15 | }
16 | li {
17 | /* declaration */
18 | }
19 | }
20 | ```
21 |
22 | ```html
23 |
25 |
28 |