refactor: 4개 검사 엔진을 YAML 기반 표준 규칙으로 리팩토링
- YAML 규칙 파일 4개 신규 생성 (html_css, accessibility, seo, performance_security) W3C, WCAG 2.0/2.1/2.2, OWASP, Google Search Essentials 공식 표준 기반 - rules/__init__.py: YAML 로더 + 캐싱 + 리로드 모듈 - html_css.py: 30개 폐기 요소, 100+개 폐기 속성을 YAML에서 동적 로드 - accessibility.py: WCAG 버전 선택 지원 (wcag_version 파라미터) - seo.py: title/description 길이, OG 필수 태그 등 임계값 YAML 로드 - performance_security.py: COOP/COEP/CORP 검사 추가, 정보 노출 헤더 검사 추가, TTFB/페이지 크기 임계값 YAML 로드 - PyYAML 의존성 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
821
backend/app/rules/html_css.yaml
Normal file
821
backend/app/rules/html_css.yaml
Normal file
@ -0,0 +1,821 @@
|
||||
# ============================================================
|
||||
# HTML/CSS Web Standards Rules
|
||||
# Based on: W3C HTML Living Standard (WHATWG), CSS Specifications
|
||||
# ============================================================
|
||||
|
||||
metadata:
|
||||
name: "HTML/CSS Web Standards"
|
||||
version: "1.0.0"
|
||||
last_updated: "2026-02-13"
|
||||
sources:
|
||||
- name: "HTML Living Standard (WHATWG)"
|
||||
url: "https://html.spec.whatwg.org/multipage/"
|
||||
section: "16 Obsolete features"
|
||||
- name: "HTML Living Standard - Obsolete Features"
|
||||
url: "https://html.spec.whatwg.org/multipage/obsolete.html"
|
||||
- name: "MDN Web Docs - HTML Elements Reference"
|
||||
url: "https://developer.mozilla.org/en-US/docs/Web/HTML/Element"
|
||||
- name: "W3C CSS Specifications"
|
||||
url: "https://www.w3.org/Style/CSS/"
|
||||
|
||||
# ============================================================
|
||||
# 1. Obsolete (Non-Conforming) HTML Elements
|
||||
# Source: HTML Living Standard Section 16
|
||||
# ============================================================
|
||||
obsolete_elements:
|
||||
# --- Entirely Obsolete (must not be used) ---
|
||||
- tag: "applet"
|
||||
replacement: "embed or object"
|
||||
reason: "Outdated plugin technology (Java applets)"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "acronym"
|
||||
replacement: "abbr"
|
||||
reason: "Redundant; abbr covers both abbreviations and acronyms"
|
||||
severity: "major"
|
||||
|
||||
- tag: "bgsound"
|
||||
replacement: "audio"
|
||||
reason: "Proprietary (IE-only) audio element"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "dir"
|
||||
replacement: "ul"
|
||||
reason: "Non-standard directory list"
|
||||
severity: "major"
|
||||
|
||||
- tag: "frame"
|
||||
replacement: "iframe with CSS, or server-side includes"
|
||||
reason: "Frame-based layouts are obsolete"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "frameset"
|
||||
replacement: "iframe with CSS, or server-side includes"
|
||||
reason: "Frame-based layouts are obsolete"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "noframes"
|
||||
replacement: "N/A (remove with frame/frameset)"
|
||||
reason: "Related to obsolete frames"
|
||||
severity: "major"
|
||||
|
||||
- tag: "isindex"
|
||||
replacement: "form with input[type=text]"
|
||||
reason: "Outdated form method"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "keygen"
|
||||
replacement: "Web Cryptography API"
|
||||
reason: "Certificate enrollment; use Web Crypto API"
|
||||
severity: "major"
|
||||
|
||||
- tag: "listing"
|
||||
replacement: "pre + code"
|
||||
reason: "Obsolete code presentation element"
|
||||
severity: "major"
|
||||
|
||||
- tag: "menuitem"
|
||||
replacement: "Script handling contextmenu event"
|
||||
reason: "Context menu item (never widely supported)"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "nextid"
|
||||
replacement: "GUIDs or UUIDs"
|
||||
reason: "Obsolete identifier generation"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "noembed"
|
||||
replacement: "object instead of embed"
|
||||
reason: "Fallback for embed; use object element"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "param"
|
||||
replacement: "data attribute on object"
|
||||
reason: "Object parameter passing"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "plaintext"
|
||||
replacement: "MIME type text/plain"
|
||||
reason: "Obsolete text rendering mode"
|
||||
severity: "major"
|
||||
|
||||
- tag: "rb"
|
||||
replacement: "ruby element directly"
|
||||
reason: "Ruby base text (use ruby directly)"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "rtc"
|
||||
replacement: "Nested ruby elements"
|
||||
reason: "Ruby text container (use nested ruby)"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "strike"
|
||||
replacement: "del (edits) or s (no longer relevant)"
|
||||
reason: "Presentational strikethrough"
|
||||
severity: "major"
|
||||
|
||||
- tag: "xmp"
|
||||
replacement: "pre + code with escaped entities"
|
||||
reason: "Obsolete code display element"
|
||||
severity: "major"
|
||||
|
||||
# --- Presentational Elements (use CSS instead) ---
|
||||
- tag: "basefont"
|
||||
replacement: "CSS font properties"
|
||||
reason: "Base font styling (presentational)"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "big"
|
||||
replacement: "CSS font-size or semantic elements (h1-h6, strong, mark)"
|
||||
reason: "Presentational text sizing"
|
||||
severity: "major"
|
||||
|
||||
- tag: "blink"
|
||||
replacement: "CSS animations/transitions"
|
||||
reason: "Presentational text animation"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "center"
|
||||
replacement: "CSS text-align or margin auto"
|
||||
reason: "Presentational centering"
|
||||
severity: "major"
|
||||
|
||||
- tag: "font"
|
||||
replacement: "CSS font properties"
|
||||
reason: "Presentational font styling"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "marquee"
|
||||
replacement: "CSS animations/transitions"
|
||||
reason: "Presentational scrolling text"
|
||||
severity: "critical"
|
||||
|
||||
- tag: "multicol"
|
||||
replacement: "CSS columns"
|
||||
reason: "Presentational multi-column layout"
|
||||
severity: "major"
|
||||
|
||||
- tag: "nobr"
|
||||
replacement: "CSS white-space: nowrap"
|
||||
reason: "Presentational no-break text"
|
||||
severity: "minor"
|
||||
|
||||
- tag: "spacer"
|
||||
replacement: "CSS margin/padding"
|
||||
reason: "Presentational spacing"
|
||||
severity: "major"
|
||||
|
||||
- tag: "tt"
|
||||
replacement: "kbd, var, code, or samp (context-dependent)"
|
||||
reason: "Presentational monospace text"
|
||||
severity: "major"
|
||||
|
||||
# ============================================================
|
||||
# 2. Obsolete HTML Attributes
|
||||
# Source: HTML Living Standard Section 16
|
||||
# ============================================================
|
||||
obsolete_attributes:
|
||||
# --- Global Attributes ---
|
||||
global:
|
||||
- attr: "contextmenu"
|
||||
replacement: "Script for contextmenu event"
|
||||
severity: "minor"
|
||||
- attr: "datasrc"
|
||||
replacement: "XMLHttpRequest / Fetch API"
|
||||
severity: "minor"
|
||||
- attr: "datafld"
|
||||
replacement: "XMLHttpRequest / Fetch API"
|
||||
severity: "minor"
|
||||
- attr: "dataformatas"
|
||||
replacement: "XMLHttpRequest / Fetch API"
|
||||
severity: "minor"
|
||||
- attr: "dropzone"
|
||||
replacement: "Script for drag/drop events"
|
||||
severity: "minor"
|
||||
|
||||
# --- Element-Specific Attributes ---
|
||||
a:
|
||||
- attr: "charset"
|
||||
replacement: "HTTP Content-Type header"
|
||||
severity: "minor"
|
||||
- attr: "coords"
|
||||
replacement: "area element for image maps"
|
||||
severity: "minor"
|
||||
- attr: "shape"
|
||||
replacement: "area element for image maps"
|
||||
severity: "minor"
|
||||
- attr: "methods"
|
||||
replacement: "HTTP OPTIONS"
|
||||
severity: "minor"
|
||||
- attr: "name"
|
||||
replacement: "id attribute"
|
||||
severity: "major"
|
||||
- attr: "rev"
|
||||
replacement: "rel with opposite term"
|
||||
severity: "minor"
|
||||
- attr: "urn"
|
||||
replacement: "href attribute"
|
||||
severity: "minor"
|
||||
|
||||
body:
|
||||
- attr: "alink"
|
||||
replacement: "CSS :active pseudo-class"
|
||||
severity: "major"
|
||||
- attr: "bgcolor"
|
||||
replacement: "CSS background-color"
|
||||
severity: "major"
|
||||
- attr: "bottommargin"
|
||||
replacement: "CSS margin-bottom"
|
||||
severity: "major"
|
||||
- attr: "leftmargin"
|
||||
replacement: "CSS margin-left"
|
||||
severity: "major"
|
||||
- attr: "link"
|
||||
replacement: "CSS color for links"
|
||||
severity: "major"
|
||||
- attr: "marginheight"
|
||||
replacement: "CSS margin"
|
||||
severity: "major"
|
||||
- attr: "marginwidth"
|
||||
replacement: "CSS margin"
|
||||
severity: "major"
|
||||
- attr: "rightmargin"
|
||||
replacement: "CSS margin-right"
|
||||
severity: "major"
|
||||
- attr: "text"
|
||||
replacement: "CSS color"
|
||||
severity: "major"
|
||||
- attr: "topmargin"
|
||||
replacement: "CSS margin-top"
|
||||
severity: "major"
|
||||
- attr: "vlink"
|
||||
replacement: "CSS :visited pseudo-class"
|
||||
severity: "major"
|
||||
|
||||
br:
|
||||
- attr: "clear"
|
||||
replacement: "CSS clear property"
|
||||
severity: "minor"
|
||||
|
||||
form:
|
||||
- attr: "accept"
|
||||
replacement: "accept attribute on individual input elements"
|
||||
severity: "minor"
|
||||
|
||||
head:
|
||||
- attr: "profile"
|
||||
replacement: "Omit (unnecessary)"
|
||||
severity: "minor"
|
||||
|
||||
hr:
|
||||
- attr: "align"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
- attr: "color"
|
||||
replacement: "CSS border-color / background-color"
|
||||
severity: "minor"
|
||||
- attr: "noshade"
|
||||
replacement: "CSS border/background"
|
||||
severity: "minor"
|
||||
- attr: "size"
|
||||
replacement: "CSS height"
|
||||
severity: "minor"
|
||||
- attr: "width"
|
||||
replacement: "CSS width"
|
||||
severity: "minor"
|
||||
|
||||
html:
|
||||
- attr: "manifest"
|
||||
replacement: "Service Workers"
|
||||
severity: "major"
|
||||
- attr: "version"
|
||||
replacement: "Omit (unnecessary)"
|
||||
severity: "minor"
|
||||
|
||||
iframe:
|
||||
- attr: "align"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "allowtransparency"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "frameborder"
|
||||
replacement: "CSS border"
|
||||
severity: "minor"
|
||||
- attr: "framespacing"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "hspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
- attr: "longdesc"
|
||||
replacement: "Link to description page"
|
||||
severity: "minor"
|
||||
- attr: "marginheight"
|
||||
replacement: "CSS padding"
|
||||
severity: "minor"
|
||||
- attr: "marginwidth"
|
||||
replacement: "CSS padding"
|
||||
severity: "minor"
|
||||
- attr: "scrolling"
|
||||
replacement: "CSS overflow"
|
||||
severity: "minor"
|
||||
- attr: "vspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
|
||||
img:
|
||||
- attr: "align"
|
||||
replacement: "CSS float or vertical-align"
|
||||
severity: "minor"
|
||||
- attr: "border"
|
||||
replacement: "CSS border"
|
||||
severity: "major"
|
||||
- attr: "hspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
- attr: "lowsrc"
|
||||
replacement: "Progressive JPEG or srcset"
|
||||
severity: "minor"
|
||||
- attr: "name"
|
||||
replacement: "id attribute"
|
||||
severity: "minor"
|
||||
- attr: "vspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
|
||||
input:
|
||||
- attr: "align"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "border"
|
||||
replacement: "CSS border"
|
||||
severity: "minor"
|
||||
- attr: "hspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
- attr: "vspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
|
||||
link:
|
||||
- attr: "charset"
|
||||
replacement: "HTTP Content-Type header"
|
||||
severity: "minor"
|
||||
- attr: "methods"
|
||||
replacement: "HTTP OPTIONS"
|
||||
severity: "minor"
|
||||
- attr: "rev"
|
||||
replacement: "rel with opposite term"
|
||||
severity: "minor"
|
||||
- attr: "target"
|
||||
replacement: "Omit"
|
||||
severity: "minor"
|
||||
|
||||
meta:
|
||||
- attr: "scheme"
|
||||
replacement: "Include scheme in value"
|
||||
severity: "minor"
|
||||
|
||||
object:
|
||||
- attr: "align"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "archive"
|
||||
replacement: "data and type attributes"
|
||||
severity: "minor"
|
||||
- attr: "border"
|
||||
replacement: "CSS border"
|
||||
severity: "minor"
|
||||
- attr: "classid"
|
||||
replacement: "data and type attributes"
|
||||
severity: "minor"
|
||||
- attr: "code"
|
||||
replacement: "data and type attributes"
|
||||
severity: "minor"
|
||||
- attr: "codebase"
|
||||
replacement: "data and type attributes"
|
||||
severity: "minor"
|
||||
- attr: "codetype"
|
||||
replacement: "data and type attributes"
|
||||
severity: "minor"
|
||||
- attr: "declare"
|
||||
replacement: "Repeat element"
|
||||
severity: "minor"
|
||||
- attr: "hspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
- attr: "standby"
|
||||
replacement: "Optimize resource loading"
|
||||
severity: "minor"
|
||||
- attr: "typemustmatch"
|
||||
replacement: "Avoid untrusted resources"
|
||||
severity: "minor"
|
||||
- attr: "vspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
|
||||
script:
|
||||
- attr: "charset"
|
||||
replacement: "Omit (UTF-8 required)"
|
||||
severity: "minor"
|
||||
- attr: "event"
|
||||
replacement: "DOM event listeners"
|
||||
severity: "minor"
|
||||
- attr: "for"
|
||||
replacement: "DOM event listeners"
|
||||
severity: "minor"
|
||||
- attr: "language"
|
||||
replacement: "Omit for JavaScript"
|
||||
severity: "minor"
|
||||
|
||||
style:
|
||||
- attr: "type"
|
||||
replacement: "Omit for CSS (default)"
|
||||
severity: "info"
|
||||
|
||||
table:
|
||||
- attr: "align"
|
||||
replacement: "CSS margin"
|
||||
severity: "major"
|
||||
- attr: "bgcolor"
|
||||
replacement: "CSS background-color"
|
||||
severity: "major"
|
||||
- attr: "border"
|
||||
replacement: "CSS border"
|
||||
severity: "major"
|
||||
- attr: "bordercolor"
|
||||
replacement: "CSS border-color"
|
||||
severity: "minor"
|
||||
- attr: "cellpadding"
|
||||
replacement: "CSS padding on td/th"
|
||||
severity: "major"
|
||||
- attr: "cellspacing"
|
||||
replacement: "CSS border-spacing"
|
||||
severity: "major"
|
||||
- attr: "frame"
|
||||
replacement: "CSS border"
|
||||
severity: "minor"
|
||||
- attr: "height"
|
||||
replacement: "CSS height"
|
||||
severity: "minor"
|
||||
- attr: "rules"
|
||||
replacement: "CSS border on td/th"
|
||||
severity: "minor"
|
||||
- attr: "summary"
|
||||
replacement: "caption element or aria-describedby"
|
||||
severity: "minor"
|
||||
- attr: "width"
|
||||
replacement: "CSS width"
|
||||
severity: "minor"
|
||||
|
||||
td_th:
|
||||
- attr: "abbr"
|
||||
applies_to: "td only"
|
||||
replacement: "Descriptive text or title attribute"
|
||||
severity: "minor"
|
||||
- attr: "align"
|
||||
replacement: "CSS text-align"
|
||||
severity: "minor"
|
||||
- attr: "axis"
|
||||
replacement: "scope on th"
|
||||
severity: "minor"
|
||||
- attr: "bgcolor"
|
||||
replacement: "CSS background-color"
|
||||
severity: "minor"
|
||||
- attr: "char"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "charoff"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "height"
|
||||
replacement: "CSS height"
|
||||
severity: "minor"
|
||||
- attr: "nowrap"
|
||||
replacement: "CSS white-space"
|
||||
severity: "minor"
|
||||
- attr: "valign"
|
||||
replacement: "CSS vertical-align"
|
||||
severity: "minor"
|
||||
- attr: "width"
|
||||
replacement: "CSS width"
|
||||
severity: "minor"
|
||||
|
||||
tr:
|
||||
- attr: "align"
|
||||
replacement: "CSS text-align"
|
||||
severity: "minor"
|
||||
- attr: "bgcolor"
|
||||
replacement: "CSS background-color"
|
||||
severity: "minor"
|
||||
- attr: "char"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "charoff"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "height"
|
||||
replacement: "CSS height"
|
||||
severity: "minor"
|
||||
- attr: "valign"
|
||||
replacement: "CSS vertical-align"
|
||||
severity: "minor"
|
||||
|
||||
thead_tbody_tfoot:
|
||||
- attr: "align"
|
||||
replacement: "CSS text-align"
|
||||
severity: "minor"
|
||||
- attr: "char"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "charoff"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "height"
|
||||
replacement: "CSS height"
|
||||
severity: "minor"
|
||||
- attr: "valign"
|
||||
replacement: "CSS vertical-align"
|
||||
severity: "minor"
|
||||
|
||||
ol_ul:
|
||||
- attr: "compact"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "type"
|
||||
applies_to: "ul only (ol type is valid)"
|
||||
replacement: "CSS list-style-type"
|
||||
severity: "minor"
|
||||
|
||||
heading:
|
||||
- attr: "align"
|
||||
applies_to: "h1-h6"
|
||||
replacement: "CSS text-align"
|
||||
severity: "minor"
|
||||
|
||||
embed:
|
||||
- attr: "align"
|
||||
replacement: "CSS"
|
||||
severity: "minor"
|
||||
- attr: "hspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
- attr: "name"
|
||||
replacement: "id attribute"
|
||||
severity: "minor"
|
||||
- attr: "vspace"
|
||||
replacement: "CSS margin"
|
||||
severity: "minor"
|
||||
|
||||
# ============================================================
|
||||
# 3. Semantic HTML5 Elements
|
||||
# Source: HTML Living Standard - Sections, Grouping
|
||||
# ============================================================
|
||||
semantic_elements:
|
||||
structural:
|
||||
- tag: "header"
|
||||
description: "Introductory content or navigational aids for a section/page"
|
||||
typical_use: "Site header, section header"
|
||||
- tag: "nav"
|
||||
description: "Section with navigation links"
|
||||
typical_use: "Main navigation, breadcrumbs, table of contents"
|
||||
- tag: "main"
|
||||
description: "Dominant content of the body (unique per page)"
|
||||
typical_use: "Primary content area (one per page)"
|
||||
- tag: "footer"
|
||||
description: "Footer for its nearest sectioning content/root"
|
||||
typical_use: "Site footer, section footer"
|
||||
- tag: "aside"
|
||||
description: "Content tangentially related to surrounding content"
|
||||
typical_use: "Sidebar, pull quotes, related links"
|
||||
- tag: "section"
|
||||
description: "Generic standalone section of a document"
|
||||
typical_use: "Thematic grouping with heading"
|
||||
- tag: "article"
|
||||
description: "Self-contained composition independently distributable"
|
||||
typical_use: "Blog post, news article, forum post, comment"
|
||||
|
||||
text_level:
|
||||
- tag: "figure"
|
||||
description: "Self-contained content with optional caption"
|
||||
typical_use: "Images, diagrams, code listings with captions"
|
||||
- tag: "figcaption"
|
||||
description: "Caption for a figure element"
|
||||
typical_use: "Image caption, diagram description"
|
||||
- tag: "details"
|
||||
description: "Disclosure widget for additional information"
|
||||
typical_use: "FAQ, expandable sections"
|
||||
- tag: "summary"
|
||||
description: "Visible heading for a details element"
|
||||
typical_use: "Click-to-expand label"
|
||||
- tag: "mark"
|
||||
description: "Text highlighted for reference or notation"
|
||||
typical_use: "Search result highlighting"
|
||||
- tag: "time"
|
||||
description: "Machine-readable date/time"
|
||||
typical_use: "Publication dates, event times"
|
||||
- tag: "address"
|
||||
description: "Contact information for author/owner"
|
||||
typical_use: "Author contact info in article/footer"
|
||||
- tag: "search"
|
||||
description: "Container for search functionality"
|
||||
typical_use: "Search form wrapper (new in HTML5.2+)"
|
||||
|
||||
interactive:
|
||||
- tag: "dialog"
|
||||
description: "Dialog box or interactive component"
|
||||
typical_use: "Modal dialogs, alerts"
|
||||
- tag: "menu"
|
||||
description: "List of commands or options"
|
||||
typical_use: "Context menus, toolbars"
|
||||
|
||||
# ============================================================
|
||||
# 4. Required/Recommended Meta Tags
|
||||
# Source: HTML Living Standard, MDN Web Docs
|
||||
# ============================================================
|
||||
meta_tags:
|
||||
required:
|
||||
- name: "charset"
|
||||
element: '<meta charset="UTF-8">'
|
||||
description: "Character encoding declaration (must be UTF-8)"
|
||||
severity: "critical"
|
||||
standard: "HTML Living Standard"
|
||||
|
||||
- name: "viewport"
|
||||
element: '<meta name="viewport" content="width=device-width, initial-scale=1">'
|
||||
description: "Viewport configuration for responsive design"
|
||||
severity: "critical"
|
||||
standard: "CSS Device Adaptation"
|
||||
|
||||
recommended:
|
||||
- name: "description"
|
||||
element: '<meta name="description" content="...">'
|
||||
description: "Page description for search engines (150-160 chars)"
|
||||
severity: "major"
|
||||
standard: "HTML Living Standard"
|
||||
|
||||
- name: "title"
|
||||
element: "<title>Page Title</title>"
|
||||
description: "Document title (required by spec, shown in browser tab)"
|
||||
severity: "critical"
|
||||
standard: "HTML Living Standard"
|
||||
|
||||
- name: "lang"
|
||||
element: '<html lang="ko">'
|
||||
description: "Document language declaration"
|
||||
severity: "major"
|
||||
standard: "HTML Living Standard"
|
||||
|
||||
- name: "content-type"
|
||||
element: 'Content-Type HTTP header or <meta http-equiv="Content-Type">'
|
||||
description: "MIME type and encoding declaration"
|
||||
severity: "major"
|
||||
standard: "HTML Living Standard"
|
||||
|
||||
social_media:
|
||||
- name: "og:title"
|
||||
element: '<meta property="og:title" content="...">'
|
||||
description: "Open Graph title for social sharing"
|
||||
severity: "minor"
|
||||
standard: "Open Graph Protocol"
|
||||
|
||||
- name: "og:description"
|
||||
element: '<meta property="og:description" content="...">'
|
||||
description: "Open Graph description for social sharing"
|
||||
severity: "minor"
|
||||
standard: "Open Graph Protocol"
|
||||
|
||||
- name: "og:image"
|
||||
element: '<meta property="og:image" content="...">'
|
||||
description: "Open Graph image for social sharing"
|
||||
severity: "minor"
|
||||
standard: "Open Graph Protocol"
|
||||
|
||||
- name: "og:url"
|
||||
element: '<meta property="og:url" content="...">'
|
||||
description: "Canonical URL for Open Graph"
|
||||
severity: "minor"
|
||||
standard: "Open Graph Protocol"
|
||||
|
||||
- name: "og:type"
|
||||
element: '<meta property="og:type" content="website">'
|
||||
description: "Content type for Open Graph"
|
||||
severity: "minor"
|
||||
standard: "Open Graph Protocol"
|
||||
|
||||
- name: "twitter:card"
|
||||
element: '<meta name="twitter:card" content="summary_large_image">'
|
||||
description: "Twitter Card type"
|
||||
severity: "info"
|
||||
standard: "Twitter Cards"
|
||||
|
||||
- name: "twitter:title"
|
||||
element: '<meta name="twitter:title" content="...">'
|
||||
description: "Twitter Card title"
|
||||
severity: "info"
|
||||
standard: "Twitter Cards"
|
||||
|
||||
- name: "twitter:description"
|
||||
element: '<meta name="twitter:description" content="...">'
|
||||
description: "Twitter Card description"
|
||||
severity: "info"
|
||||
standard: "Twitter Cards"
|
||||
|
||||
# ============================================================
|
||||
# 5. Document Structure Rules
|
||||
# Source: HTML Living Standard
|
||||
# ============================================================
|
||||
document_structure:
|
||||
doctype:
|
||||
rule: "Document must start with <!DOCTYPE html>"
|
||||
severity: "critical"
|
||||
description: "HTML5 doctype declaration required"
|
||||
|
||||
heading_hierarchy:
|
||||
rule: "Headings must follow proper hierarchy (h1 > h2 > h3...)"
|
||||
severity: "major"
|
||||
checks:
|
||||
- id: "single-h1"
|
||||
description: "Page should have exactly one h1 element"
|
||||
severity: "major"
|
||||
- id: "no-skipped-levels"
|
||||
description: "Heading levels should not be skipped (e.g., h1 to h3)"
|
||||
severity: "major"
|
||||
- id: "logical-order"
|
||||
description: "Headings should follow logical document outline"
|
||||
severity: "minor"
|
||||
|
||||
image_alt:
|
||||
rule: "All img elements must have alt attribute"
|
||||
severity: "critical"
|
||||
description: "Alternative text for images (accessibility + validity)"
|
||||
exceptions:
|
||||
- "Decorative images may use alt=''"
|
||||
- "Images with role='presentation' may omit alt"
|
||||
|
||||
inline_styles:
|
||||
rule: "Avoid inline style attributes"
|
||||
severity: "minor"
|
||||
description: "Inline styles reduce maintainability and violate separation of concerns"
|
||||
|
||||
duplicate_ids:
|
||||
rule: "Element id attributes must be unique within the document"
|
||||
severity: "critical"
|
||||
description: "Duplicate IDs cause accessibility and JavaScript issues"
|
||||
|
||||
empty_links:
|
||||
rule: "Anchor elements should have accessible content"
|
||||
severity: "major"
|
||||
description: "Links without text or aria-label are not accessible"
|
||||
|
||||
table_structure:
|
||||
rule: "Data tables should have proper structure"
|
||||
severity: "major"
|
||||
checks:
|
||||
- id: "table-has-thead"
|
||||
description: "Data tables should have thead with th elements"
|
||||
- id: "table-has-caption"
|
||||
description: "Complex tables should have caption or aria-label"
|
||||
- id: "th-has-scope"
|
||||
description: "th elements should have scope attribute"
|
||||
|
||||
form_structure:
|
||||
rule: "Form elements should have proper labels"
|
||||
severity: "major"
|
||||
checks:
|
||||
- id: "input-has-label"
|
||||
description: "Every form input should have an associated label"
|
||||
- id: "form-has-submit"
|
||||
description: "Forms should have a submit mechanism"
|
||||
- id: "fieldset-has-legend"
|
||||
description: "Fieldset elements should have a legend"
|
||||
|
||||
link_integrity:
|
||||
rule: "Links and resources should be valid"
|
||||
severity: "minor"
|
||||
checks:
|
||||
- id: "no-empty-href"
|
||||
description: "Links should not have empty href attributes"
|
||||
- id: "valid-rel"
|
||||
description: "Link rel values should be valid"
|
||||
|
||||
# ============================================================
|
||||
# 6. CSS Best Practices
|
||||
# Source: CSS Specifications, MDN Web Docs
|
||||
# ============================================================
|
||||
css_checks:
|
||||
- id: "no-important-overuse"
|
||||
description: "Avoid excessive use of !important declarations"
|
||||
severity: "minor"
|
||||
standard: "CSS Cascading and Inheritance"
|
||||
|
||||
- id: "vendor-prefix-check"
|
||||
description: "Check for unnecessary vendor prefixes on well-supported properties"
|
||||
severity: "info"
|
||||
standard: "CSS Specifications"
|
||||
|
||||
- id: "no-universal-selector-performance"
|
||||
description: "Avoid universal selector (*) in complex selectors for performance"
|
||||
severity: "info"
|
||||
standard: "CSS Selectors Level 4"
|
||||
Reference in New Issue
Block a user