diff --git a/.babelrc b/.babelrc deleted file mode 100644 index c13c5f6..0000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["es2015"] -} diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 874a764..0000000 --- a/.eslintrc +++ /dev/null @@ -1,56 +0,0 @@ -{ - "extends": "eslint:recommended", - - "env": { - "es6": true, - "node": true, - "browser": true - }, - - "ecmaFeatures": { - "modules": true - }, - - "rules": { - "array-bracket-spacing": [2, "never"], - "arrow-parens": 2, - "arrow-spacing": [2, {"before": true, "after": true}], - "block-spacing": [2, "always"], - "brace-style": [2, "1tbs"], - "callback-return": [2, ["callback", "cb", "fn", "next"]], - "comma-spacing": [2, {"before": false, "after": true}], - "comma-style": [2, "last"], - "computed-property-spacing": [2, "never"], - "eol-last": 2, - "eqeqeq": 2, - "generator-star-spacing": [2, {"before": true, "after": false}], - "indent": [2, 2, {"SwitchCase": 1}], - "linebreak-style": [2, "unix"], - "no-class-assign": 2, - "no-console": 0, - "no-const-assign": 2, - "no-extra-semi": 2, - "no-inner-declarations": [2, "both"], - "no-multi-spaces": 2, - "no-spaced-func": 2, - "no-trailing-spaces": 2, - "no-useless-call": 2, - "no-var": 2, - "object-curly-spacing": [2, "never"], - "one-var": [2, "never"], - "operator-assignment": [2, "never"], - "operator-linebreak": [2, "after"], - "prefer-spread": 2, - "quotes": [2, "single"], - "semi": [2, "always"], - "space-after-keywords": 2, - "space-before-blocks": 2, - "space-before-function-paren": [2, "never"], - "space-before-keywords": [2, "always"], - "space-in-parens": 2, - "space-infix-ops": 2, - "space-return-throw-case": 2, - "space-unary-ops": [2, {"words": true, "nonwords": false}], - "wrap-iife": [2, "inside"] - } -} diff --git a/.gitignore b/.gitignore index a095df0..edc6c51 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ build/ node_modules/ *.log .DS_Store +.vscode diff --git a/.htmlhintrc b/.htmlhintrc deleted file mode 100644 index 6feda33..0000000 --- a/.htmlhintrc +++ /dev/null @@ -1,24 +0,0 @@ -{ - "tagname-lowercase": true, - "attr-lowercase": true, - "attr-value-double-quotes": true, - "attr-value-not-empty": false, - "attr-no-duplication": true, - "doctype-first": true, - "tag-pair": true, - "tag-self-close": false, - "spec-char-escape": true, - "id-unique": true, - "src-not-empty": true, - "title-require": true, - "alt-require": true, - "doctype-html5": true, - "id-class-value": "dash", - "style-disabled": false, - "inline-style-disabled": false, - "inline-script-disabled": false, - "space-tab-mixed-disabled": "space", - "id-class-ad-disabled": false, - "href-abs-or-rel": false, - "attr-unsafe-chars": true -} diff --git a/.postcss-sorting.json b/.postcss-sorting.json index 31ce4fa..985987f 100644 --- a/.postcss-sorting.json +++ b/.postcss-sorting.json @@ -1,363 +1,396 @@ { - "empty-lines-between-children-rules": 1, - "empty-lines-between-media-rules": 1, - "sort-order": [ - [ - "@mixin" - ], - [ - "content", - "position", - "top", - "right", - "bottom", - "left", - "z-index" - ], - [ - "display", - "-webkit-flex", - "-ms-flex", - "flex", - "-webkit-flex-grow", - "flex-grow", - "-webkit-flex-shrink", - "flex-shrink", - "-webkit-flex-basis", - "flex-basis", - "-webkit-flex-flow", - "flex-flow", - "-webkit-flex-direction", - "-ms-flex-direction", - "flex-direction", - "-webkit-flex-wrap", - "flex-wrap", - "-webkit-justify-content", - "justify-content", - "-webkit-align-content", - "align-content", - "-webkit-align-items", - "align-items", - "-webkit-order", - "-ms-flex-order", - "order", - "-webkit-align-self", - "align-self", - "float", - "clear", - "-webkit-box-sizing", - "-moz-box-sizing", - "box-sizing", - "width", - "min-width", - "max-width", - "height", - "min-height", - "max-height", - "margin", - "margin-top", - "margin-right", - "margin-bottom", - "margin-left", - "padding", - "padding-top", - "padding-right", - "padding-bottom", - "padding-left", - "overflow", - "-ms-overflow-x", - "overflow-x", - "-ms-overflow-y", - "overflow-y", - "-webkit-overflow-scrolling" - ], - [ - "list-style", - "list-style-position", - "list-style-type", - "list-style-image", - "border-collapse", - "border-spacing", - "table-layout", - "empty-cells", - "caption-side", - "font", - "font-weight", - "font-size", - "line-height", - "font-family", - "vertical-align", - "text-align", - "direction", - "color", - "text-transform", - "text-decoration", - "font-style", - "font-variant", - "font-size-adjust", - "font-stretch", - "font-effect", - "font-emphasize", - "font-emphasize-position", - "font-emphasize-style", - "font-smooth", - "-webkit-text-align-last", - "-moz-text-align-last", - "-ms-text-align-last", - "text-align-last", - "letter-spacing", - "word-spacing", - "white-space", - "text-emphasis", - "text-emphasis-color", - "text-emphasis-style", - "text-emphasis-position", - "text-indent", - "-ms-text-justify", - "text-justify", - "-ms-writing-mode", - "text-outline", - "text-wrap", - "-ms-text-overflow", - "text-overflow", - "text-overflow-ellipsis", - "text-overflow-mode", - "text-orientation", - "-ms-word-wrap", - "word-wrap", - "-ms-word-break", - "word-break", - "-moz-tab-size", - "-o-tab-size", - "tab-size", - "-webkit-hyphens", - "-moz-hyphens", - "hyphens", - "unicode-bidi", - "columns", - "column-count", - "column-fill", - "column-gap", - "column-rule", - "column-rule-color", - "column-rule-style", - "column-rule-width", - "column-span", - "column-width", - "text-shadow", - "page-break-after", - "page-break-before", - "page-break-inside" - ], - [ - "background", - "background-color", - "background-image", - "background-repeat", - "background-position", - "-ms-background-position-x", - "background-position-x", - "-ms-background-position-y", - "background-position-y", - "-webkit-background-size", - "-moz-background-size", - "-o-background-size", - "background-size", - "-webkit-background-clip", - "-moz-background-clip", - "background-clip", - "background-origin", - "background-attachment", - "box-decoration-break", - "background-blend-mode", - "border", - "border-width", - "border-style", - "border-color", - "border-top", - "border-top-width", - "border-top-style", - "border-top-color", - "border-right", - "border-right-width", - "border-right-style", - "border-right-color", - "border-bottom", - "border-bottom-width", - "border-bottom-style", - "border-bottom-color", - "border-left", - "border-left-width", - "border-left-style", - "border-left-color", - "-webkit-border-radius", - "-moz-border-radius", - "border-radius", - "-webkit-border-top-left-radius", - "-moz-border-radius-topleft", - "border-top-left-radius", - "-webkit-border-top-right-radius", - "-moz-border-radius-topright", - "border-top-right-radius", - "-webkit-border-bottom-right-radius", - "-moz-border-radius-bottomright", - "border-bottom-right-radius", - "-webkit-border-bottom-left-radius", - "-moz-border-radius-bottomleft", - "border-bottom-left-radius", - "-webkit-border-image", - "-moz-border-image", - "-o-border-image", - "border-image", - "-webkit-border-image-source", - "-moz-border-image-source", - "-o-border-image-source", - "border-image-source", - "-webkit-border-image-slice", - "-moz-border-image-slice", - "-o-border-image-slice", - "border-image-slice", - "-webkit-border-image-width", - "-moz-border-image-width", - "-o-border-image-width", - "border-image-width", - "-webkit-border-image-outset", - "-moz-border-image-outset", - "-o-border-image-outset", - "border-image-outset", - "-webkit-border-image-repeat", - "-moz-border-image-repeat", - "-o-border-image-repeat", - "border-image-repeat", - "outline", - "outline-width", - "outline-style", - "outline-color", - "outline-offset", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "-webkit-transform", - "-moz-transform", - "-ms-transform", - "-o-transform", - "transform", - "-webkit-transform-origin", - "-moz-transform-origin", - "-ms-transform-origin", - "-o-transform-origin", - "transform-origin", - "-webkit-backface-visibility", - "-moz-backface-visibility", - "backface-visibility", - "-webkit-perspective", - "-moz-perspective", - "perspective", - "-webkit-perspective-origin", - "-moz-perspective-origin", - "perspective-origin", - "-webkit-transform-style", - "-moz-transform-style", - "transform-style", - "visibility", - "cursor", - "opacity", - "-webkit-filter", - "filter" - ], - [ - "-webkit-transition", - "-moz-transition", - "-ms-transition", - "-o-transition", - "transition", - "-webkit-transition-delay", - "-moz-transition-delay", - "-ms-transition-delay", - "-o-transition-delay", - "transition-delay", - "-webkit-transition-timing-function", - "-moz-transition-timing-function", - "-ms-transition-timing-function", - "-o-transition-timing-function", - "transition-timing-function", - "-webkit-transition-duration", - "-moz-transition-duration", - "-ms-transition-duration", - "-o-transition-duration", - "transition-duration", - "-webkit-transition-property", - "-moz-transition-property", - "-ms-transition-property", - "-o-transition-property", - "transition-property", - "-webkit-animation", - "-moz-animation", - "-ms-animation", - "-o-animation", - "animation", - "-webkit-animation-name", - "-moz-animation-name", - "-ms-animation-name", - "-o-animation-name", - "animation-name", - "-webkit-animation-duration", - "-moz-animation-duration", - "-ms-animation-duration", - "-o-animation-duration", - "animation-duration", - "-webkit-animation-play-state", - "-moz-animation-play-state", - "-ms-animation-play-state", - "-o-animation-play-state", - "animation-play-state", - "-webkit-animation-timing-function", - "-moz-animation-timing-function", - "-ms-animation-timing-function", - "-o-animation-timing-function", - "animation-timing-function", - "-webkit-animation-delay", - "-moz-animation-delay", - "-ms-animation-delay", - "-o-animation-delay", - "animation-delay", - "-webkit-animation-iteration-count", - "-moz-animation-iteration-count", - "-ms-animation-iteration-count", - "-o-animation-iteration-count", - "animation-iteration-count", - "-webkit-animation-direction", - "-moz-animation-direction", - "-ms-animation-direction", - "-o-animation-direction", - "animation-direction" - ], - [ - "appearance", - "quotes", - "counter-reset", - "counter-increment", - "resize", - "-webkit-user-select", - "-moz-user-select", - "-ms-user-select", - "user-select", - "nav-index", - "nav-up", - "nav-right", - "nav-down", - "nav-left", - "pointer-events", - "will-change", - "clip", - "clip-path", - "zoom" - ], - [ - "@media" - ], - [ - ">child" - ] - ] + "order": [ + "custom-properties", + { + "type": "at-rule", + "name": "mixin" + }, + "declarations", + "at-rules", + "rules" + ], + "properties-order": [ + "content", + "position", + "top", + "right", + "bottom", + "left", + "z-index", + "display", + "-webkit-flex", + "-ms-flex", + "flex", + "-webkit-flex-grow", + "flex-grow", + "-webkit-flex-shrink", + "flex-shrink", + "-webkit-flex-basis", + "flex-basis", + "-webkit-flex-flow", + "flex-flow", + "-webkit-flex-direction", + "-ms-flex-direction", + "flex-direction", + "-webkit-flex-wrap", + "flex-wrap", + "-webkit-justify-content", + "justify-content", + "-webkit-align-content", + "align-content", + "-webkit-align-items", + "align-items", + "-webkit-order", + "-ms-flex-order", + "order", + "-ms-grid-row-align", + "-webkit-align-self", + "align-self", + "-ms-grid-column-align", + "justify-self", + "grid", + "grid-area", + "grid-auto-columns", + "grid-auto-flow", + "grid-auto-rows", + "grid-column", + "grid-column-end", + "-ms-grid-column-span", + "grid-column-gap", + "-ms-grid-column", + "grid-column-start", + "grid-gap", + "grid-row", + "grid-row-end", + "-ms-grid-row-span", + "grid-row-gap", + "-ms-grid-row", + "grid-row-start", + "grid-template", + "grid-template-areas", + "-ms-grid-columns", + "grid-template-columns", + "-ms-grid-rows", + "grid-template-rows", + "float", + "clear", + "-webkit-box-sizing", + "-moz-box-sizing", + "box-sizing", + "width", + "min-width", + "max-width", + "height", + "min-height", + "max-height", + "margin", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + "overflow", + "-ms-overflow-x", + "overflow-x", + "-ms-overflow-y", + "overflow-y", + "-webkit-overflow-scrolling", + "-ms-overflow-style", + "list-style", + "list-style-position", + "list-style-type", + "list-style-image", + "border-collapse", + "border-spacing", + "table-layout", + "empty-cells", + "caption-side", + "font", + "font-weight", + "font-size", + "line-height", + "font-family", + "vertical-align", + "text-align", + "direction", + "color", + "text-transform", + "text-decoration", + "font-style", + "font-variant", + "font-size-adjust", + "font-stretch", + "font-effect", + "font-emphasize", + "font-emphasize-position", + "font-emphasize-style", + "-webkit-font-smoothing", + "-moz-osx-font-smoothing", + "font-smooth", + "-webkit-text-align-last", + "-moz-text-align-last", + "-ms-text-align-last", + "text-align-last", + "letter-spacing", + "word-spacing", + "white-space", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-style", + "text-emphasis-position", + "text-indent", + "-ms-text-justify", + "text-justify", + "-ms-writing-mode", + "text-outline", + "text-wrap", + "-ms-text-overflow", + "text-overflow", + "text-overflow-ellipsis", + "text-overflow-mode", + "text-orientation", + "-ms-word-wrap", + "word-wrap", + "-ms-word-break", + "word-break", + "-moz-tab-size", + "-o-tab-size", + "overflow-wrap", + "tab-size", + "-webkit-hyphens", + "-moz-hyphens", + "hyphens", + "unicode-bidi", + "columns", + "column-count", + "column-fill", + "column-gap", + "column-rule", + "column-rule-color", + "column-rule-style", + "column-rule-width", + "column-span", + "column-width", + "text-shadow", + "page-break-after", + "page-break-before", + "page-break-inside", + "src", + "background", + "background-color", + "background-image", + "background-repeat", + "background-position", + "-ms-background-position-x", + "background-position-x", + "-ms-background-position-y", + "background-position-y", + "-webkit-background-size", + "-moz-background-size", + "-o-background-size", + "background-size", + "-webkit-background-clip", + "-moz-background-clip", + "background-clip", + "background-origin", + "background-attachment", + "box-decoration-break", + "background-blend-mode", + "border", + "border-width", + "border-style", + "border-color", + "border-top", + "border-top-width", + "border-top-style", + "border-top-color", + "border-right", + "border-right-width", + "border-right-style", + "border-right-color", + "border-bottom", + "border-bottom-width", + "border-bottom-style", + "border-bottom-color", + "border-left", + "border-left-width", + "border-left-style", + "border-left-color", + "-webkit-border-radius", + "-moz-border-radius", + "border-radius", + "-webkit-border-top-left-radius", + "-moz-border-radius-topleft", + "border-top-left-radius", + "-webkit-border-top-right-radius", + "-moz-border-radius-topright", + "border-top-right-radius", + "-webkit-border-bottom-right-radius", + "-moz-border-radius-bottomright", + "border-bottom-right-radius", + "-webkit-border-bottom-left-radius", + "-moz-border-radius-bottomleft", + "border-bottom-left-radius", + "-webkit-border-image", + "-moz-border-image", + "-o-border-image", + "border-image", + "-webkit-border-image-source", + "-moz-border-image-source", + "-o-border-image-source", + "border-image-source", + "-webkit-border-image-slice", + "-moz-border-image-slice", + "-o-border-image-slice", + "border-image-slice", + "-webkit-border-image-width", + "-moz-border-image-width", + "-o-border-image-width", + "border-image-width", + "-webkit-border-image-outset", + "-moz-border-image-outset", + "-o-border-image-outset", + "border-image-outset", + "-webkit-border-image-repeat", + "-moz-border-image-repeat", + "-o-border-image-repeat", + "border-image-repeat", + "outline", + "outline-width", + "outline-style", + "outline-color", + "outline-offset", + "-webkit-box-shadow", + "-moz-box-shadow", + "box-shadow", + "-webkit-transform", + "-moz-transform", + "-ms-transform", + "-o-transform", + "transform", + "-webkit-transform-origin", + "-moz-transform-origin", + "-ms-transform-origin", + "-o-transform-origin", + "transform-origin", + "-webkit-backface-visibility", + "-moz-backface-visibility", + "backface-visibility", + "-webkit-perspective", + "-moz-perspective", + "perspective", + "-webkit-perspective-origin", + "-moz-perspective-origin", + "perspective-origin", + "-webkit-transform-style", + "-moz-transform-style", + "transform-style", + "visibility", + "cursor", + "opacity", + "interpolation-mode", + "-webkit-filter", + "filter", + "backdrop-filter", + "-webkit-transition", + "-moz-transition", + "-ms-transition", + "-o-transition", + "transition", + "-webkit-transition-delay", + "-moz-transition-delay", + "-ms-transition-delay", + "-o-transition-delay", + "transition-delay", + "-webkit-transition-timing-function", + "-moz-transition-timing-function", + "-ms-transition-timing-function", + "-o-transition-timing-function", + "transition-timing-function", + "-webkit-transition-duration", + "-moz-transition-duration", + "-ms-transition-duration", + "-o-transition-duration", + "transition-duration", + "-webkit-transition-property", + "-moz-transition-property", + "-ms-transition-property", + "-o-transition-property", + "transition-property", + "-webkit-animation", + "-moz-animation", + "-ms-animation", + "-o-animation", + "animation", + "-webkit-animation-name", + "-moz-animation-name", + "-ms-animation-name", + "-o-animation-name", + "animation-name", + "-webkit-animation-duration", + "-moz-animation-duration", + "-ms-animation-duration", + "-o-animation-duration", + "animation-duration", + "-webkit-animation-play-state", + "-moz-animation-play-state", + "-ms-animation-play-state", + "-o-animation-play-state", + "animation-play-state", + "-webkit-animation-timing-function", + "-moz-animation-timing-function", + "-ms-animation-timing-function", + "-o-animation-timing-function", + "animation-timing-function", + "-webkit-animation-delay", + "-moz-animation-delay", + "-ms-animation-delay", + "-o-animation-delay", + "animation-delay", + "-webkit-animation-iteration-count", + "-moz-animation-iteration-count", + "-ms-animation-iteration-count", + "-o-animation-iteration-count", + "animation-iteration-count", + "-webkit-animation-direction", + "-moz-animation-direction", + "-ms-animation-direction", + "-o-animation-direction", + "animation-direction", + "-webkit-animation-fill-mode", + "-moz-animation-fill-mode", + "-ms-animation-fill-mode", + "-o-animation-fill-mode", + "animation-fill-mode", + "appearance", + "clip", + "clip-path", + "counter-reset", + "counter-increment", + "resize", + "-webkit-user-select", + "-moz-user-select", + "-ms-user-select", + "user-select", + "-webkit-tap-highlight-color", + "nav-index", + "nav-up", + "nav-right", + "nav-down", + "nav-left", + "pointer-events", + "quotes", + "touch-action", + "will-change", + "zoom", + "fill", + "fill-rule", + "clip-rule", + "stroke" + ], + "unspecified-properties-position": "bottom" } diff --git a/.stylelintrc b/.stylelintrc deleted file mode 100644 index 68068db..0000000 --- a/.stylelintrc +++ /dev/null @@ -1,193 +0,0 @@ -{ - "rules": { - "color-hex-case": "lower", - "color-hex-length": "long", - "color-named": null, - "color-no-hex": null, - "color-no-invalid-hex": true, - - "font-family-name-quotes": "double-unless-keyword", - "font-weight-notation": null, - - "function-blacklist": null, - "function-calc-no-unspaced-operator": true, - "function-comma-newline-after": "always-multi-line", - "function-comma-newline-before": "never-multi-line", - "function-comma-space-after": "always", - "function-comma-space-before": "never", - "function-linear-gradient-no-nonstandard-direction": true, - "function-max-empty-lines": 0, - "function-name-case": "lower", - "function-parentheses-newline-inside": null, - "function-parentheses-space-inside": "never", - "function-url-data-uris": null, - "function-url-quotes": "double", - "function-whitelist": null, - "function-whitespace-after": "always", - - "number-leading-zero": "always", - "number-max-precision": null, - "number-no-trailing-zeros": true, - "number-zero-length-no-unit": true, - - "string-no-newline": true, - "string-quotes": "double", - - "time-no-imperceptible": null, - - "unit-blacklist": null, - "unit-case": "lower", - "unit-no-unknown": true, - "unit-whitelist": null, - - "value-no-vendor-prefix": null, - - "value-keyword-case": "lower", - "value-list-comma-newline-after": "always-multi-line", - "value-list-comma-newline-before": "never-multi-line", - "value-list-comma-space-after": "always-single-line", - "value-list-comma-space-before": "never", - - "custom-property-no-outside-root": null, - "custom-property-pattern": null, - - "shorthand-property-no-redundant-values": null, - - "property-blacklist": null, - "property-case": "lower", - "property-no-vendor-prefix": null, - "property-unit-blacklist": null, - "property-unit-whitelist": null, - "property-value-blacklist": null, - "property-value-whitelist": null, - "property-whitelist": null, - - "keyframe-declaration-no-important": true, - - "declaration-bang-space-after": "never", - "declaration-bang-space-before": "always", - "declaration-colon-newline-after": "always-multi-line", - "declaration-colon-space-after": "always-single-line", - "declaration-colon-space-before": "never", - "declaration-no-important": null, - - "declaration-block-no-duplicate-properties": true, - "declaration-block-no-ignored-properties": true, - "declaration-block-no-shorthand-property-overrides": true, - "declaration-block-properties-order": null, - "declaration-block-semicolon-newline-after": "always", - "declaration-block-semicolon-newline-before": "never-multi-line", - "declaration-block-semicolon-space-after": "always-single-line", - "declaration-block-semicolon-space-before": "never", - "declaration-block-single-line-max-declarations": null, - "declaration-block-trailing-semicolon": "always", - - "block-closing-brace-newline-after": "always", - "block-closing-brace-newline-before": "always", - "block-closing-brace-space-after": "always-single-line", - "block-closing-brace-space-before": "always-single-line", - "block-no-empty": true, - "block-no-single-line": true, - "block-opening-brace-newline-after": "always", - "block-opening-brace-newline-before": null, - "block-opening-brace-space-after": "always-single-line", - "block-opening-brace-space-before": "always", - - "selector-attribute-brackets-space-inside": "never", - "selector-attribute-operator-blacklist": null, - "selector-attribute-operator-space-after": "never", - "selector-attribute-operator-space-before": "never", - "selector-attribute-operator-whitelist": null, - "selector-class-pattern": null, - "selector-combinator-space-after": "always", - "selector-combinator-space-before": "always", - "selector-id-pattern": null, - "selector-max-compound-selectors": 3, - "selector-max-specificity": null, - "selector-no-attribute": null, - "selector-no-combinator": null, - "selector-no-id": null, - "selector-no-qualifying-type": [true, { - "ignore": ["attribute"] - }], - "selector-no-type": null, - "selector-no-universal": null, - "selector-no-vendor-prefix": null, - "selector-pseudo-class-case": "lower", - "selector-pseudo-class-no-unknown": true, - "selector-pseudo-class-parentheses-space-inside": "never", - "selector-pseudo-element-case": "lower", - "selector-pseudo-element-colon-notation": "double", - "selector-pseudo-element-no-unknown": true, - "selector-root-no-composition": null, - "selector-type-case": "lower", - "selector-type-no-unknown": true, - "selector-max-empty-lines": 0, - - "selector-list-comma-newline-after": "always", - "selector-list-comma-newline-before": "never-multi-line", - "selector-list-comma-space-after": "always-single-line", - "selector-list-comma-space-before": "never", - - "root-no-standard-properties": null, - - "rule-nested-empty-line-before": ["always", { - "except": ["first-nested"], - "ignore": ["after-comment"] - }], - "rule-non-nested-empty-line-before": ["always", { - "ignore": ["after-comment"] - }], - - "media-feature-colon-space-after": "always", - "media-feature-colon-space-before": "never", - "media-feature-name-no-vendor-prefix": null, - "media-feature-no-missing-punctuation": true, - "media-feature-range-operator-space-after": "always", - "media-feature-range-operator-space-before": "always", - - "custom-media-pattern": null, - - "media-query-parentheses-space-inside": "never", - "media-query-list-comma-newline-after": "always-multi-line", - "media-query-list-comma-newline-before": "never-multi-line", - "media-query-list-comma-space-after": "always-single-line", - "media-query-list-comma-space-before": "never-single-line", - - "at-rule-empty-line-before": ["always", { - "except": [ - "first-nested", - "blockless-group" - ], - "ignore": ["after-comment"] - }], - "at-rule-name-case": "lower", - "at-rule-name-space-after": "always", - "at-rule-no-vendor-prefix": null, - "at-rule-semicolon-newline-after": "always", - - "stylelint-disable-reason": "always-before", - - "comment-empty-line-before": null, - "comment-whitespace-inside": null, - "comment-word-blacklist": null, - - "indentation": [2, { - "except": ["value"] - }], - - "max-empty-lines": 2, - "max-line-length": null, - "max-nesting-depth": 3, - "no-browser-hacks": true, - "no-descending-specificity": null, - "no-duplicate-selectors": true, - "no-eol-whitespace": true, - "no-extra-semicolons": true, - "no-indistinguishable-colors": null, - "no-invalid-double-slash-comments": true, - "no-missing-eof-newline": true, - "no-unknown-animations": null, - "no-unsupported-browser-features": null - } -} diff --git a/Readme.md b/Readme.md index 884fcda..947d906 100644 --- a/Readme.md +++ b/Readme.md @@ -1,54 +1,21 @@ -# Стиль кода Академии HTML +# Стиль кода .html academy -[![dependency status][dependency-image]][dependency-url] -[![devDependency status][devdependency-image]][devdependency-url] - -_TBD_ - -## Сервер для разработки - -Для запуска лайв-сервера нужен [Node.js](https://nodejs.org) версии 0.12 или выше. - -### Установка - -```bash -$ git clone https://github.com/htmlacademy/codeguide.git -$ cd codeguide -$ npm i -``` - -### Запуск - -```bash -$ npm start -``` - -После выполнения команды, откройте в браузере `http://127.0.0.1:3000`. - -### Тестирование - -```bash -$ npm test -``` - -Для проверки скриптов используется [ESLint](http://eslint.org). - -## Нашли ошибку? - -Пожалуйста, [создайте тикет](https://github.com/htmlacademy/codeguide/issues). +Это исходники, публичная версия на сайте [codeguide.academy](https://codeguide.academy/). ## Благодарности * [Code Guide](http://codeguide.co) by @mdo * [CSS Guidelines](http://cssguidelin.es) by Harry Roberts * [Idiomatic CSS](https://github.com/necolas/idiomatic-css) by Nicolas Gallagher -* [Primer Guidelines](http://primercss.io/guidelines/) by GitHub +* [Primer Guidelines](https://primer.style/css/) by GitHub ## Лицензия -Лицензия MIT, смотрите файл `License.md`. +[MIT](./License.md). + +## Правила линтеров -[dependency-image]: https://david-dm.org/htmlacademy/codeguide.svg?style=flat-square -[dependency-url]: https://david-dm.org/htmlacademy/codeguide -[devdependency-image]: https://david-dm.org/htmlacademy/codeguide/dev-status.svg?style=flat-square -[devdependency-url]: https://david-dm.org/htmlacademy/codeguide#info=devDependencies +* [EditorConfig](.editorconfig) +* [ESLint](https://github.com/htmlacademy/eslint-config-htmlacademy) +* [Stylelint](https://github.com/htmlacademy/stylelint-config-htmlacademy) +* [HTMLHint](https://github.com/htmlacademy/htmlhint-config-htmlacademy) diff --git a/app/css/chapter.css b/app/css/chapter.css deleted file mode 100644 index 5c13650..0000000 --- a/app/css/chapter.css +++ /dev/null @@ -1,57 +0,0 @@ -.chapter h2 { - padding: 2rem 1rem; - - background-color: var(--subtle-color); - - @media (--viewport-medium) { - padding: 2rem 2rem 2.5rem; - } - - @media (--viewport-large) { - padding: 2rem 3rem 2.5rem; - } -} - -.chapter-part { - display: flex; - flex-direction: column; - - border-bottom: 1px solid var(--subtle-color); - - @media (--viewport-large) { - flex-direction: row; - } -} - -.chapter-part-col { - padding: 2rem 1rem; - - @media (--viewport-medium) { - padding: 2rem; - } - - @media (--viewport-large) { - width: 50%; - padding: 3rem; - } - - & + .chapter-part-col { - border-top: 1px solid var(--subtle-color); - - @media (--viewport-large) { - border-top: 0; - } - } - - figure { - margin: 0 1rem 0 0; - } - - p { - max-width: 32rem; - } -} - -.gray-bgcolor { - background-color: var(--light-subtle-color); -} diff --git a/app/css/footer.css b/app/css/footer.css deleted file mode 100644 index 00bac59..0000000 --- a/app/css/footer.css +++ /dev/null @@ -1,67 +0,0 @@ -footer { - padding: 2rem; - - background-color: var(--brand-color-dark); -} - -.contacts { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.logo-full { - display: inline-block; - width: 161px; -} - -.social-icons { - display: flex; - justify-content: space-between; - align-items: center; - margin: 0.5rem 0 1rem 0; -} - -.social-icons, -.github { - font-size: 0; -} - -.icon { - min-width: 2rem; - min-height: 2rem; - - background-repeat: no-repeat; - background-position: center; - background-size: calc(100% - 5px); - opacity: 0.5; - - &:hover { - opacity: 1; - } - - &-vk { - background-image: resolve("icon-vkontakte.svg"); - } - - &-fb { - background-image: resolve("icon-facebook.svg"); - } - - &-tw { - background-image: resolve("icon-twitter.svg"); - } - - &-ig { - background-image: resolve("icon-instagram.svg"); - } -} - -.github-link { - display: inline-block; - width: 91px; - height: 16px; - - background-image: resolve("github.svg"); -} diff --git a/app/css/general.css b/app/css/general.css deleted file mode 100644 index 5f1107d..0000000 --- a/app/css/general.css +++ /dev/null @@ -1,89 +0,0 @@ -html { - font-size: var(--base-px-size); - - @media (--viewport-large) { - font-size: var(--large-px-size); - } -} - -body { - margin: 0; - - font: 17px/1.6 "Helvetica", "Arial", sans-serif; - color: var(--dark-color); - - background-color: var(--light-color); -} - -a:any-link { - color: var(--dark-color); - text-decoration: underline; -} - -a:hover { - text-decoration: none; -} - -h1, -h2, -h4 { - margin: 0; - - font-weight: normal; - color: var(--darker-color); - letter-spacing: -0.025em; -} - -h2, -h4 { - line-height: 1.2; -} - -h1 { - font-size: 3rem; - line-height: 1.3; -} - -h2 { - font-size: 2.5rem; -} - -h4 { - font-size: 1.75rem; -} - -code, -pre { - font-family: "Consolas", "Liberation Mono", "Menlo", "Courier", monospace; -} - -code { - padding: 2px 4px; - - font-size: 95%; - color: #d44950; - - background-color: #f7f7f9; - border-radius: 0.2rem; -} - -pre { - display: block; - margin: 0 0 1rem; - - line-height: 1.4; - white-space: pre-wrap; -} - -pre code { - padding: 0; - - color: inherit; - - background-color: transparent; - border: 0; -} - -ul li { - margin-bottom: 0.25rem; -} diff --git a/app/css/header.css b/app/css/header.css deleted file mode 100644 index 9cfa541..0000000 --- a/app/css/header.css +++ /dev/null @@ -1,33 +0,0 @@ -header { - padding: 1rem 1rem 6rem; - - text-align: center; - - background-color: var(--brand-color); - background-image: repeating-linear-gradient(150deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06) 1px, transparent 0, transparent 41px), repeating-linear-gradient(-150deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06) 1px, transparent 0, transparent 41px); - - @media (--viewport-medium) { - padding-bottom: 4rem; - } - - h1 { - margin: 0 0 0.25rem; - - color: var(--light-color); - } - - p { - margin-top: 0; - - font-size: 1.1rem; - } - - a:any-link { - color: var(--light-color); - } -} - -.logo { - width: 300px; - height: 300px; -} diff --git a/app/css/prism.css b/app/css/prism.css deleted file mode 100644 index 4b0f50a..0000000 --- a/app/css/prism.css +++ /dev/null @@ -1,15 +0,0 @@ -/* override default prism theme */ -code[class*="language-"], -pre[class*="language-"] { - white-space: pre-wrap; -} - -pre[class*="language-"] { - margin: 0; - padding: 0; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: initial; -} diff --git a/app/css/style.css b/app/css/style.css deleted file mode 100644 index df17289..0000000 --- a/app/css/style.css +++ /dev/null @@ -1,11 +0,0 @@ -@import "http://github.com/normalize.css"; -@import "http://github.com/variables.css"; - -@import "http://github.com/prismjs-default-theme/prism-default.css"; - -@import "http://github.com/general.css"; -@import "http://github.com/prism.css"; - -@import "http://github.com/header.css"; -@import "http://github.com/chapter.css"; -@import "http://github.com/footer.css"; diff --git a/app/css/variables.css b/app/css/variables.css deleted file mode 100644 index e3e493b..0000000 --- a/app/css/variables.css +++ /dev/null @@ -1,19 +0,0 @@ -:root { - --base-px-size: 16px; - --large-px-size: calc(var(--base-px-size) * 1.25); - - --brand-color: #312785; - --brand-color-dark: #2d2d44; - - --dark-color: #5a5a5a; - --darker-color: color(var(--dark-color) blackness(+50%)); - - --subtle-color: #e5e5e5; - - --light-color: #ffffff; - --light-subtle-color: color(var(--subtle-color) lightness(+8%)); - --lighter-subtle-color: color(var(--subtle-color) lightness(+5%)); -} - -@custom-media --viewport-large (min-width: 48em); -@custom-media --viewport-medium (min-width: 38em); diff --git a/app/img/bane.svg b/app/img/bane.svg deleted file mode 100644 index 2e5cc47..0000000 --- a/app/img/bane.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/img/github.svg b/app/img/github.svg deleted file mode 100644 index e1cffa9..0000000 --- a/app/img/github.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/img/logo-full.svg b/app/img/logo-full.svg deleted file mode 100644 index 7319e8a..0000000 --- a/app/img/logo-full.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/js/app.js b/app/js/app.js deleted file mode 100644 index fb99126..0000000 --- a/app/js/app.js +++ /dev/null @@ -1 +0,0 @@ -import 'prismjs'; diff --git a/app/templates/helpers/import.js b/app/templates/helpers/import.js deleted file mode 100644 index 315dd3c..0000000 --- a/app/templates/helpers/import.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -const fs = require('fs-extra'); -const path = require('path'); -const resolve = require('./resolve'); - -const root = path.resolve('build/'); - -module.exports = function(url) { - let file = path.join(root, resolve(url)); - let content = ''; - - try { - content = fs.readFileSync(file, {'encoding': 'utf8'}); - } catch (e) { - content = e; - } - - return content; -}; diff --git a/app/templates/helpers/resolve.js b/app/templates/helpers/resolve.js deleted file mode 100644 index fd6ed77..0000000 --- a/app/templates/helpers/resolve.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -const fs = require('fs-extra'); -const path = require('path'); - -const options = require(path.resolve('config/kit')); - -const root = path.resolve('build/'); -const discover = options.discover.map(function(folder) { - return path.resolve(root, folder); -}); - -module.exports = function(url) { - let file; - - let found = discover.some(function(folder) { - file = path.join(folder, url); - return fs.existsSync(file); - }); - - if (found) { - url = file.replace(root, ''); - } - - return url; -}; diff --git a/app/templates/index.hbs b/app/templates/index.hbs deleted file mode 100644 index 1fe672b..0000000 --- a/app/templates/index.hbs +++ /dev/null @@ -1,69 +0,0 @@ - - -
- -
- {{~> css/examples/css-selectors-example ~}}
-
-
- {{~> css/examples/css-important-example ~}}
-
-
- {{~> css/examples/css-shorthand-example ~}}
-
-
- {{~> css/examples/css-vertical-align-example ~}}
-
-
- {{~> css/examples/css-syntax-example ~}}
-
-
- {{~> css/examples/css-order-example ~}}
-
-
- {{~> css/examples/css-class-names-example ~}}
-
-
- {{~> css/examples/css-import-example ~}}
-
-
- {{~> css/examples/css-font-variant-example ~}}
-
- !important
- В большинстве случаев необходимость использования !important
в CSS возникает из-за неправильного обращения к элементам страницы через каскад. Однако, в редких случаях, без использования !important
не обойтись.
-
- Подробнее в статье: http://meiert.com/en/blog/20150310/important/. -
diff --git a/app/templates/partials/css/recomendations/css-selectors.hbs b/app/templates/partials/css/recomendations/css-selectors.hbs deleted file mode 100644 index 829bd1e..0000000 --- a/app/templates/partials/css/recomendations/css-selectors.hbs +++ /dev/null @@ -1,5 +0,0 @@ -Селекторы должны быть написаны так, чтобы их можно было переиспользовать в дальнейшем. Цепочки селекторов или селекторы с излишней вложенностью не должны создаваться без необходимости — это увеличивает специфичность правил и уменьшает возможность их переиспользования.
-Длинные цепочки вложенных селекторов также усложняют код и его поддержку. Хорошим подходом считается использовать вложенность до 2 или 3 уровня. Псевдоэлементы или псевдоклассы не увеличивают уровень вложенности. -
-Идентификаторы id
для стилизации не используются. Вместо идентификаторов для задания стилей используются селекторы по классам или тегам.
Cокращенные объявления не используются в тех случаях, когда это может косвенно переопределить другие значения. Наиболее часто злоупотребляют сокращением следующих свойств:
-padding
- margin
- border-radius
- border
- font
- background
-
- Сокращённые свойства, где элементы значений однотипные (например,
- margin: 10px 15px;
или
- padding: 1px 2px 3px;
) сложнее воспринимать, чем отдельные свойства (margin-top: 10px; padding-top: 1px;
).
-
- Свойства с разнотипными элементами значений (например,
- border: 1px solid #000000;
) в сокращённом виде считываются легче – их можно сокращать, если нет опасности переопределить другие значения.
-
.button
и .button-danger
)..btn
для кнопок), но не делайте их слишком длинными (более трёх слов).
- Альтернативные варианты шрифта и тип семейства указываются в конце перечисления font-family
.
-
- В случае использования нестандартных шрифтов альтернативный веб-безопасный шрифт и тип семейства указываются, чтобы в случае отсутствия нестандартного шрифта в системе, изменения внешнего вида страницы были минимальны. Альтернативный шрифт должен быть такого же типа, что и нестандартный. -
-- Порядок шрифтов следующий: -
-- Список веб-безопасных шрифтов можно посмотреть здесь — cssfontstack.com. -
diff --git a/app/templates/partials/css/rules/css-import.hbs b/app/templates/partials/css/rules/css-import.hbs deleted file mode 100644 index 846ec3c..0000000 --- a/app/templates/partials/css/rules/css-import.hbs +++ /dev/null @@ -1,4 +0,0 @@ -@import
- Правило @import
работает медленнее, чем тег <link>
. В стилях @import
не должен использоваться.
-
- Объявления логически связанных свойств группируются в следующем порядке: -
-- Позиционирование следует первым потому, что оно влияет на положение блоков в потоке документа. Блочная модель идёт следующей, так как она определяет размеры и расположение блоков. -
-- Все остальные объявления, которые изменяют вид внутренних частей блоков и не оказывают влияния на другие блоки, идут в последнюю очередь. -
-- Сгруппированные объявления в правиле отделяются друг от друга пустой строкой. -
-
- Порядок объявления подробных правил, таких как font-size
, font-family
, line-height
, должен соответствовать порядку в сокращённой версии правила. В случае совместного использования подробных и сокращённых правил, первой должна идти сокращённая версия.
-
#f5f5f5
..5
вместо 0.5
).top: 10px;
). А перед двоеточием пробел не нужен.rgb()
, rgba()
, hsl()
, hsla()
или rect()
пробелы ставятся. Это повышает удобочитаемость.p > a
) ставится один пробел..selector {
- color: #f5f5f5;
-}
-
border: 0
.vertical-align
- Значение vertical-align
должно быть явно указано для блоков с display: inline-block
.
-
- Значение по умолчанию, baseline
, может приводить к странному отображению блочно-строчных элементов. Например, когда в ряд стоят несколько элементов с разным количеством строк.
-
- Если вы хотите, чтобы элементы выравнивались по умолчанию, то явно укажите для vertical-align
значение baseline
. Это позволит другим понять, что вы знаете об особенностях отображения элементов с таким выравниванием и задали его намеренно.
-
- {{~> html/examples/html-minimal-markup-example ~}}
-
-
- {{~> html/examples/html-semantics-example ~}}
-
-
- {{~> html/examples/html-protocol-example ~}}
-
-
- {{~> html/examples/html-syntax-example ~}}
-
-
- {{~> html/examples/html-doctype-example ~}}
-
-
- {{~> html/examples/html-encoding-example ~}}
-
-
- {{~> html/examples/html-style-includes-example ~}}
-
-
- {{~> html/examples/html-js-includes-example ~}}
-
-
- {{~> html/examples/html-attribute-order-example ~}}
-
-
- {{~> html/examples/html-boolean-example ~}}
-
-
- {{~> html/examples/html-form-labels-example ~}}
-
-
- {{~> html/examples/html-img-sizes-example ~}}
-
-
- {{~> html/examples/html-language-example ~}}
-
- - В разметке должно быть использовано минимальное возможное количество элементов. Не должно быть лишних оберток и блоков, которые используются для оформления и могут быть заменены на псевдоэлементы. -
diff --git a/app/templates/partials/html/recomendations/html-protocol.hbs b/app/templates/partials/html/recomendations/html-protocol.hbs deleted file mode 100644 index e9ca3bd..0000000 --- a/app/templates/partials/html/recomendations/html-protocol.hbs +++ /dev/null @@ -1,7 +0,0 @@ -
- Если сайт поддерживает оба протокола http:
и https:
, то при запросе файлов в HTML через полный URL часть с протоколом из адреса можно исключить. Это сделает URL относительным и избавит от проблем с доступом, а также немного сократит запись.
-
- Если сайт подерживает только один из протоколов, в URL лучше явно указывать соответствующий. -
diff --git a/app/templates/partials/html/recomendations/html-semantics.hbs b/app/templates/partials/html/recomendations/html-semantics.hbs deleted file mode 100644 index 01bbd18..0000000 --- a/app/templates/partials/html/recomendations/html-semantics.hbs +++ /dev/null @@ -1,7 +0,0 @@ -- В разметке должны использоваться семантические теги HTML. -
-
- Параграфы текста должны помещаться в тег <p>
. Тег <br>
должен применяться по назначению.
-
- Атрибут класса у HTML-элементов пишется первым. Единообразное написание помогает легче считывать код и быстрее разбираться в назначении блоков по их классам. -
-- Остальные атрибуты могут быть расставлены в любом порядке, но тоже единообразно для одинаковых элементов. -
diff --git a/app/templates/partials/html/rules/html-boolean.hbs b/app/templates/partials/html/rules/html-boolean.hbs deleted file mode 100644 index 06a16a5..0000000 --- a/app/templates/partials/html/rules/html-boolean.hbs +++ /dev/null @@ -1,4 +0,0 @@ -
- Для логических атрибутов (например, checked
, disabled
, required
) значение не указывается, а сами атрибуты указываются последними и в единообразной последовательности во всём документе.
-
- В начале страницы обязательно должен быть указан актуальный doctype
, чтобы браузер отображал её в режиме соответствия стандартам. Это гарантирует, что страница будет выглядеть единообразно во всех современных браузерах.
-
- Кодировка символов на странице всегда должна быть явно указана, чтобы обеспечить корректное отображение текста. Кодировка utf-8
предпочтительна.
-
- Для улучшения взаимодействия пользователя с элементами форм, при нажатии на подпись поля, оно должно активироваться. Для этого элемент формы связывается с его описанием с помощью идентификатора и атрибута for
тега <label>
.
-
- Изображениям <img>
должны быть явно заданы с помощью атрибута размеры в пикселях или в процентах. В случае пикселей размерность не нужна.
-
- По возможности изображениям указываются действительные размеры, так как это улучшает производительность отрисовки страницы: браузер не будет перерисовывать страницу в процессе загрузки и отображения изображения. -
diff --git a/app/templates/partials/html/rules/html-js-includes.hbs b/app/templates/partials/html/rules/html-js-includes.hbs deleted file mode 100644 index 30d2050..0000000 --- a/app/templates/partials/html/rules/html-js-includes.hbs +++ /dev/null @@ -1,7 +0,0 @@ -- Скрипты должны подключаться в самом низу страницы, чтобы при её загрузке не блокировать отображение содержимого. -
-
- При подключении скриптов в теге <script>
атрибут type
не указывается, так как его значение text/javascript
устанавливается по умолчанию.
-
- Для элемента <html>
в атрибуте lang
должен указываться соответствующий язык документа. Это помогает инструментам синтеза речи определить, какое использовать произношение или системам перевода, какие использовать языковые правила.
-
- Стилевые файлы с помощью <link>
подключаются внутри <head>
. При этом атрибут type
для тега <link>
не указывается, так как его значение text/css
устанавливается по умолчанию.
-
<img>
, <br>
и другие) не ставится.</li>
или </body>
) не пропускаются.- Документ должен проходить проверку на валидность. Для проверки используется современный валидатор. -
diff --git a/browserslist b/browserslist deleted file mode 100644 index 076e30c..0000000 --- a/browserslist +++ /dev/null @@ -1,15 +0,0 @@ -# Browsers that we support - -# Desktop browsers -Explorer >= 11 -Edge >= 12 -Safari >= 8 -last 4 Chrome versions -last 4 Firefox versions -last 4 Opera versions - -# Mobile browsers -iOS >= 8 -Android >= 4.4 -ExplorerMobile >= 11 -BlackBerry >= 10 diff --git a/config/kit.json b/config/kit.json deleted file mode 100644 index febe63c..0000000 --- a/config/kit.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "entry": { - "css": [ - "style.css" - ], - - "js": [ - "app.js" - ] - }, - - "discover": ["img", "css", "js"], - - "cssnext": { - "browsers": "last 2 versions", - "import": false, - "features": { - "customProperties": false, - "rem": false - } - } -} diff --git a/config/webpack.config.js b/config/webpack.config.js deleted file mode 100644 index a53c00d..0000000 --- a/config/webpack.config.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -const path = require('path'); -const webpack = require('webpack'); -const options = require(path.resolve('config/kit')); - -let files = {}; -options.entry.js.forEach(function(file) { - files[path.basename(file, '.js')] = './js/' + file; -}); - -module.exports = { - context: path.resolve('app'), - - entry: files, - - output: { - path: path.resolve('build/js'), - filename: '[name].js', - pathinfo: true - }, - - module: { - loaders: [{ - test: /\.js$/, - exclude: /node_modules|build/, - loader: 'babel-loader', - query: { - cacheDirectory: true - } - }] - }, - - plugins: [ - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false - }, - output: { - comments: false - } - }) - ] -}; diff --git a/css/prism.css b/css/prism.css new file mode 100644 index 0000000..91c4996 --- /dev/null +++ b/css/prism.css @@ -0,0 +1,139 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..a125c80 --- /dev/null +++ b/css/style.css @@ -0,0 +1,494 @@ +/* Common */ + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + height: 100%; +} + +body { + margin: 0; + min-height: 100%; + font-size: 16px; + line-height: 1.6; + font-family: "Helvetica", "Arial", sans-serif; + color: #5a5a5a; + background-color: #ffffff; + display: flex; + flex-direction: column; +} + +a:link, +a:visited { + color: #3f3ccb; + text-decoration: none; +} + +a:hover, +a:focus { + color: #302683; + text-decoration: underline; +} + +h1, +h2, +h3 { + margin: 0; + font-weight: normal; + color: #424242; + letter-spacing: -0.025em; +} + +h2, +h3, +h4 { + line-height: 1.2; +} + +h1 { + font-size: 3rem; + line-height: 1.3; +} + +h2 { + font-size: 2.5rem; +} + +h3 { + font-size: 1.75rem; + scroll-margin-top: 20px; +} + +ul li { + margin-bottom: 0.25rem; +} + +.visually-hidden { + position: absolute; + + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + border: 0; + clip: rect(0, 0, 0, 0); + clip-path: inset(100%); +} + +/* Code */ + +code, +pre { + font-family: "Consolas", "Liberation Mono", "Menlo", "Courier", monospace; +} + +code { + padding: 2px 4px; + font-size: 95%; + color: #d44950; + background-color: #f7f7f9; + border-radius: 0.2rem; +} + +pre { + display: block; + margin: 0 0 1rem; + line-height: 1.4; + white-space: pre-wrap; +} + +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} + +/* Header */ + +header { + padding: 1rem 1rem 6rem; + text-align: center; + background-color: #312785; + background-image: repeating-linear-gradient(150deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06) 1px, transparent 0, transparent 41px), repeating-linear-gradient(-150deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06) 1px, transparent 0, transparent 41px); + background-size: 82px 47px; +} + +header h1 { + margin: 0 0 0.25rem; + color: #ffffff; +} + +header p { + margin-top: 0; + font-size: 1.1rem; +} + +header a:link, +header a:visited { + color: #ffffff; +} + +.logo { + width: 300px; + height: 300px; +} + +.logo-list-js { + margin: 11px 23px 0; +} + +@media (min-width: 38em) { + header { + padding-bottom: 4rem; + } +} + +/* Logo list */ + +.logo-list { + margin: 50px auto; +} + +.logo-list ul { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 0; + padding: 0; + list-style: none; +} + +.logo-list li { + margin-right: 10px; + margin-left: 10px; +} + +/* Gudie content */ + +.guide-content { + display: flex; + flex-wrap: wrap; +} + +/* Sidebar */ + +.sidebar { + display: flex; + flex-direction: column; + width: 100%; +} + +.sidebar a { + display: block; + color: #5a5a5a; +} + +.sidebar a:hover { + color: #3f3ccb; +} + +.sidebar-col { + padding: 2rem 1rem; +} + +.sidebar-col + .sidebar-col { + border-top: 1px solid #e5e5e5; +} + +.sidebar-col > a { + font-size: 1.75rem; + line-height: 1.25; +} + +.sidebar-menu { + padding-left: 1rem; +} + +@media (min-width: 48em) { + .sidebar { + flex-direction: row; + flex-wrap: wrap; + padding: 2rem 0; + } + + .sidebar-col { + width: 50%; + padding: 1rem 3rem; + } + + .sidebar-col + .sidebar-col { + border-top: 0; + } +} + +@media (min-width: 75em) { + .sidebar { + position: sticky; + top: 0; + bottom: 0; + flex-direction: column; + flex-wrap: nowrap; + align-self: flex-start; + width: 230px; + height: 100vh; + padding: 0 1rem; + overflow-y: auto; + line-height: 1.25; + border-right: 1px solid #e5e5e5; + } + + .sidebar-col { + flex-shrink: 0; + width: 100%; + padding: 0; + } + + .sidebar-col-first { + padding-top: 1.75rem; + } + + .sidebar-col-last { + padding-bottom: 1.75rem; + } + + .sidebar-col + .sidebar-col { + margin-top: 1.75em; + } + + .sidebar-col > a { + display: block; + + font-size: 0.8rem; + font-weight: bold; + } + + .sidebar-menu { + padding: 0; + margin: 0.5em 0 0; + list-style: none; + font-size: 0.7rem; + } + + .sidebar-menu li { + margin: 0; + line-height: 1.45; + } + + .sidebar-menu a { + display: block; + padding: 0.25em 0; + } +} + +/* Chapter */ + +.chapters { + width: 100%; +} + +.chapter h2 { + padding: 2rem 1rem; + word-break: break-word; + background-color: #e5e5e5; +} + +.chapter h3[id]::before { + display: block; + height: 2rem; + margin-top: -2rem; + visibility: hidden; + content: ""; +} + +.chapter-part { + display: flex; + flex-direction: column; + border-bottom: 1px solid #e5e5e5; +} + +.chapter-part-col { + padding: 2rem 1rem; +} + +.chapter-part-col figure { + margin: 0 1rem 0 0; +} + +.chapter-part-col p { + max-width: 32rem; +} + +.chapter-part-col + .chapter-part-col { + border-top: 1px solid #e5e5e5; +} + +.gray-bgcolor { + background-color: #fafafa; +} + +@media (min-width: 38em) { + .chapter h2 { + padding: 2rem 2rem 2.5rem; + } + + .chapter-part-col { + padding: 2rem; + } +} + + +@media (min-width: 48em) { + .chapter h2 { + padding: 2rem 3rem 2.5rem; + } + + .chapter-part { + flex-direction: row; + } + + .chapter-part-col { + width: 50%; + padding: 3rem 1.5rem; + } + + .chapter-part-col--full-width { + width: 100%; + } + + .chapter-part-col + .chapter-part-col { + border-top: 0; + } +} + +@media (min-width: 75em) { + .chapters { + width: calc(100% - 230px); + } +} + +/* Footer */ + +footer { + padding: 2rem; + margin-top: auto; + background-color: #2d2d44; +} + +.contacts { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.logo-full { + display: inline-block; + width: 161px; +} + +.social-icons { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0.5rem 0 1rem 0; +} + +.social-icons, +.github { + font-size: 0; +} + +.icon { + min-width: 2rem; + min-height: 2rem; + background-repeat: no-repeat; + background-position: center; + background-size: calc(100% - 5px); + opacity: 0.5; +} + +.icon:hover { + opacity: 1; +} + +.icon-vk { + background-image: url("http://github.com/img/icon-vkontakte.svg"); +} + +.icon-fb { + background-image: url("http://github.com/img/icon-facebook.svg"); +} + +.icon-tw { + background-image: url("http://github.com/img/icon-twitter.svg"); +} + +.icon-ig { + background-image: url("http://github.com/img/icon-instagram.svg"); +} + +.github-link { + display: inline-block; + width: 91px; + height: 16px; + background-image: url("http://github.com/img/github.svg"); +} + +/* Prism */ + +/* override default prism theme */ +code[class*="language-"], +pre[class*="language-"] { + white-space: pre-wrap; +} + +pre[class*="language-"] { + margin: 0; + padding: 0; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: initial; +} + +/* override default prism theme */ +code[class*="language-"], +pre[class*="language-"] { + white-space: pre-wrap; +} + +pre[class*="language-"] { + margin: 0; + padding: 0; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: initial; +} + +pre.language-correct, +pre.language-incorrect { + padding: 5px 10px; +} + +pre.language-correct { + background: #deeede; +} + +pre.language-incorrect { + background: #f4d3d3; +} + +pre.language-correct .token.operator, +pre.language-incorrect .token.operator { + background: none; +} diff --git a/csscomb.json b/csscomb.json index 74429f2..25e9113 100644 --- a/csscomb.json +++ b/csscomb.json @@ -40,32 +40,56 @@ ], [ "display", + "-webkit-box", "-webkit-flex", - "-ms-flex", + "-moz-box", + "-ms-flexbox", "flex", + "-webkit-box-flex", "-webkit-flex-grow", + "-moz-box-flex", + "-ms-flex-positive", "flex-grow", "-webkit-flex-shrink", + "-ms-flex-negative", "flex-shrink", "-webkit-flex-basis", + "-ms-flex-preferred-size", "flex-basis", "-webkit-flex-flow", + "-ms-flex-flow", "flex-flow", + "-webkit-box-orient", + "-webkit-box-direction", "-webkit-flex-direction", + "-moz-box-orient", + "-moz-box-direction", "-ms-flex-direction", "flex-direction", "-webkit-flex-wrap", + "-ms-flex-wrap", "flex-wrap", + "-webkit-box-pack", "-webkit-justify-content", + "-moz-box-pack", + "-ms-flex-pack", "justify-content", "-webkit-align-content", + "-ms-flex-line-pack", "align-content", + "-webkit-box-align", "-webkit-align-items", + "-moz-box-align", + "-ms-flex-align", "align-items", + "-webkit-box-ordinal-group", "-webkit-order", + "-moz-box-ordinal-group", "-ms-flex-order", "order", "-webkit-align-self", + "-ms-flex-item-align", + "-ms-grid-row-align", "align-self", "float", "clear", @@ -106,6 +130,8 @@ "empty-cells", "caption-side", "font", + "font-style", + "font-variant", "font-weight", "font-size", "line-height", @@ -115,9 +141,9 @@ "direction", "color", "text-transform", + "-webkit-text-decoration", + "-moz-text-decoration", "text-decoration", - "font-style", - "font-variant", "font-size-adjust", "font-stretch", "font-effect", @@ -132,9 +158,13 @@ "letter-spacing", "word-spacing", "white-space", + "-webkit-text-emphasis", "text-emphasis", + "-webkit-text-emphasis-color", "text-emphasis-color", + "-webkit-text-emphasis-style", "text-emphasis-style", + "-webkit-text-emphasis-position", "text-emphasis-position", "text-indent", "-ms-text-justify", @@ -143,6 +173,7 @@ "text-outline", "text-wrap", "-ms-text-overflow", + "-o-text-overflow", "text-overflow", "text-overflow-ellipsis", "text-overflow-mode", @@ -156,17 +187,38 @@ "tab-size", "-webkit-hyphens", "-moz-hyphens", + "-ms-hyphens", "hyphens", "unicode-bidi", + "-webkit-columns", + "-moz-columns", "columns", + "-webkit-column-count", + "-moz-column-count", "column-count", + "-webkit-column-fill", + "-moz-column-fill", "column-fill", + "-webkit-column-gap", + "-moz-column-gap", "column-gap", + "-webkit-column-rule", + "-moz-column-rule", "column-rule", + "-webkit-column-rule-color", + "-moz-column-rule-color", "column-rule-color", + "-webkit-column-rule-style", + "-moz-column-rule-style", "column-rule-style", + "-webkit-column-rule-width", + "-moz-column-rule-width", "column-rule-width", + "-webkit-column-span", + "-moz-column-span", "column-span", + "-webkit-column-width", + "-moz-column-width", "column-width", "text-shadow", "page-break-after", @@ -177,6 +229,11 @@ "background", "background-color", "background-image", + "-webkit-gradient", + "-webkit-linear-gradient", + "-moz-linear-gradient", + "-o-linear-gradient", + "linear-gradient", "background-repeat", "background-position", "-ms-background-position-x", @@ -190,8 +247,12 @@ "-webkit-background-clip", "-moz-background-clip", "background-clip", + "-webkit-background-origin", + "-moz-background-origin", + "-o-background-origin", "background-origin", "background-attachment", + "-webkit-box-decoration-break", "box-decoration-break", "background-blend-mode", "border", @@ -373,6 +434,7 @@ "pointer-events", "will-change", "clip", + "-webkit-clip-path", "clip-path", "zoom" ] diff --git a/gulp/copy.js b/gulp/copy.js deleted file mode 100644 index a0eeb66..0000000 --- a/gulp/copy.js +++ /dev/null @@ -1,11 +0,0 @@ -import fs from 'fs-extra'; -import gulp from 'gulp'; - -let files = 'app/!(css|js|templates)/**/*'; - -gulp.task('clean', fs.emptyDir.bind(null, 'build')); - -gulp.task('copy', gulp.series('clean', () => { - return gulp.src(files, {dot: true}) - .pipe(gulp.dest('build')); -})); diff --git a/gulp/handlebars.js b/gulp/handlebars.js deleted file mode 100644 index 674658a..0000000 --- a/gulp/handlebars.js +++ /dev/null @@ -1,28 +0,0 @@ -import fs from 'fs-extra'; -import merge from 'merge'; -import gulp from 'gulp'; -import rename from 'gulp-rename'; -import engine from 'gulp-compile-handlebars'; -import {get as bs} from 'browser-sync'; - -const configure = () => { - fs.ensureDirSync('./app/templates/partials'); - fs.ensureDirSync('./app/templates/helpers'); - - return { - ignorePartials: true, - batch: ['./app/templates/partials'], - helpers: merge( - require('hbs-helpers'), - require('require-dir')('./../app/templates/helpers') - ) - }; -}; - -gulp.task('handlebars', () => { - return gulp.src('app/templates/*.hbs') - .pipe(engine({}, configure())) - .pipe(rename({extname: '.html'})) - .pipe(gulp.dest('build')) - .pipe(bs('kit').stream()); -}); diff --git a/gulp/postcss.js b/gulp/postcss.js deleted file mode 100644 index fb6a3f4..0000000 --- a/gulp/postcss.js +++ /dev/null @@ -1,40 +0,0 @@ -import path from 'path'; -import gulp from 'gulp'; -import postcss from 'gulp-postcss'; -import minify from 'gulp-minify-css'; -import {get as bs} from 'browser-sync'; - -import include from 'postcss-import'; -import mixins from 'postcss-mixins'; -import nested from 'postcss-nested'; -import variables from 'postcss-css-variables'; -import cssnext from 'postcss-cssnext'; -import assets from 'postcss-assets'; -import mqpacker from 'css-mqpacker'; - -const options = require(path.resolve('config/kit')); - -let files = options.entry.css.map((file) => path.join('app', 'css', file)); - -let plugins = [ - include(), - mixins(), - nested(), - variables(), - cssnext(options.cssnext), - assets({ - loadPaths: options.discover, - basePath: 'build/' - }), - mqpacker({ - sort: true - }) -]; - -gulp.task('postcss', () => { - return gulp.src(files, {base: 'app', allowEmpty: true, sourcemaps: true}) - .pipe(postcss(plugins)) - .pipe(minify({keepSpecialComments: 0})) - .pipe(gulp.dest('build', {sourcemaps: {path: '.'}})) - .pipe(bs('kit').stream({match: '**/*.css'})); -}); diff --git a/gulp/serve.js b/gulp/serve.js deleted file mode 100644 index 482d87b..0000000 --- a/gulp/serve.js +++ /dev/null @@ -1,32 +0,0 @@ -import gulp from 'gulp'; - -const bs = require('browser-sync').create('kit'); - -gulp.task('serve', () => { - bs.init({ - server: 'build/', - notify: false, - open: false, - ui: false - }); - - gulp.watch( - 'app/css/**/*.css', - gulp.series('postcss') - ); - - gulp.watch( - 'app/js/**/*.js', - gulp.series('webpack') - ); - - gulp.watch( - 'app/templates/**/*.{hbs,js}', - gulp.series('handlebars') - ); - - gulp.watch( - 'app/img/**/*.{jpg,png,svg,gif}', - gulp.series('handlebars') - ); -}); diff --git a/gulp/webpack.js b/gulp/webpack.js deleted file mode 100644 index bcf9639..0000000 --- a/gulp/webpack.js +++ /dev/null @@ -1,17 +0,0 @@ -import path from 'path'; -import gulp from 'gulp'; -import webpack from 'webpack-stream'; -import {get as bs} from 'browser-sync'; - -gulp.task('webpack', () => { - let options = require(path.resolve('config/webpack.config')); - - options.devtool = 'source-map'; - options.debug = true; - options.cache = true; - - return gulp.src('app/js/app.js', {allowEmpty: true}) - .pipe(webpack(options)) - .pipe(gulp.dest('build/js')) - .pipe(bs('kit').stream({match: '**/*.js'})); -}); diff --git a/gulpfile.babel.js b/gulpfile.babel.js deleted file mode 100644 index d475fa4..0000000 --- a/gulpfile.babel.js +++ /dev/null @@ -1,10 +0,0 @@ -import gulp from 'gulp'; - -require('require-dir')('./gulp'); - -gulp.task('start', gulp.series( - 'copy', - gulp.parallel('postcss', 'webpack'), - 'handlebars', - 'serve' -)); diff --git a/html-css.html b/html-css.html new file mode 100644 index 0000000..8e52a6a --- /dev/null +++ b/html-css.html @@ -0,0 +1,1105 @@ + + + + +При написании кода вам сложно будет запомнить все правила кодгайда. Эту работу стоит отдать роботам.
+По ссылкам находятся конфигурации Академии для этих инструментов. Конфигурации частично покрывают то, что описано в этом стиле кода, и в них нет ничего, что не описано ниже.
+<!-- Хорошо -->
+project/
+ pictures/
+ catalog/
+ wine.jpg
+ cheese.png
+ product/
+ wine-big.jpg
+ cheese-big.png
+ images/
+ logo.svg
+ favicons/
+ 32x32.png
+ 16x16.png
+ content/
+ cat.jpg
+ map.png
+ scripts/
+ menu.js
+ map.js
+ styles/
+ styles.css
+ catalog.html
+ index.html
+
+<!-- Плохо -->
+project/
+ assets/
+ logo.svg
+ icon-32x32.png
+ icon-16x16.png
+ menu.js
+ map.js
+ header.css
+ footer.css
+ index.css
+ fonts.css
+ index.html
+
+ Код проекта соответствует параметрам EditorConfig:
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.{go,py,rb,php}]
+indent_size = 4
+
+[*.md]
+trim_trailing_whitespace = false
+ <!-- Хорошо-->
+<ul>
+∙∙<li>Пункт</li>
+∙∙<li>Пункт</li>
+</ul>
+
+<!-- Плохо-->
+<ul>
+→ <li>Пункт</li>
+∙∙∙∙<li>Пункт</li>∙∙∙∙∙∙∙
+</ul>
+ Минимальная обязательная структура HTML-документы состоит из:
+<!DOCTYPE html>
<html>
с языком документа lang
<head>
<title>
<meta charset="utf-8">
. Кодировка символов на странице явно указана, чтобы обеспечить корректное отображение текста.<body>
<!-- Хорошо -->
+<!DOCTYPE html>
+<html lang="ru">
+ <head>
+ <meta charset="utf-8">
+ <title>Заголовок</title>
+ </head>
+ <body>Страница</body>
+</html>
+
+<!-- Плохо -->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <title>Заголовок</title>
+ Страница
+</html>
+
+<!-- Плохо -->
+<!DOCTYPE html>
+<html lang="ru">
+ <head>
+ <meta charset="windows-1251">
+ </head>
+</html>
+
+ Имена тегов, атрибуты и их значения записаны строчными.
+Исключение: атрибуты для SVG-элементов, например: viewBox
, preserveAspectRatio
и другие.
<!-- Хорошо -->
+<ul>
+ <li>Первый</li>
+ <li>Второй</li>
+ <li>Третий</li>
+</ul>
+
+<img class="image" src="http://github.com/images/picture.png" width="400" height="400" alt="Кот смотрит на солнышко.">
+
+<svg width="27" height="16" viewBox="0 0 128 76">
+ <path d="M125,5.15c.89-3,0-5.15-4.23-5.15h-14a6,6,0,0,0-6.09Z"/>
+</svg>
+
+<!-- Плохо -->
+<UL>
+ <LI>Первый</LI>
+ <LI>Второй</LI>
+ <LI>Третий</LI>
+</UL>
+
+<IMG class="IMAGE" SRC="images/picture.png" WIDTH="400" HEIGHT="400" ALT="Кот смотрит на солнышко.">
+
+ <!-- Хорошо -->
+<div class="menu">
+ <ul>
+ <li>
+ <a href="">Первый</a>
+ </li>
+ <li>
+ <a href="">Второй</a>
+ </li>
+ <li>
+ <a href="">Третий</a>
+ </li>
+ </ul>
+</div>
+
+<p><a href="#">В этом репозитории</a> вы увидите замечательную возможность оптимизацией графикой, а в <a href="#">этом</a> оптимизацию шрифтов.</p>
+<p>Также в <i>тексте</i> может быть <b>какое-то</b> выделение.</p>
+
+<!-- Плохо -->
+<div class="menu"><ul>
+ <li><a href="">
+ Первый
+ </a></li>
+ <li><a href="">Второй
+ </a></li>
+</ul></div>
+
+ <!-- Хорошо -->
+<ul>
+ <li>Первый</li>
+ <li>Второй</li>
+ <li>Третий</li>
+</ul>
+
+<img src="http://github.com/images/picture.png" width="400" height="400" alt="Кот смотрит на солнышко.">
+
+<input type="text" name="name">
+
+<!-- Плохо -->
+<ul>
+ <li>Первый
+ <li>Второй
+ <li>Третий
+</ul>
+
+<img src="http://github.com/images/picture.png" width="400" height="400" alt="Кот смотрит на солнышко." />
+
+<input type="text"></input>
+
+ class
идёт сразу после имени тега.<!-- Хорошо -->
+<label class="field-group-label" for="appointment-phone">
+<input class="field-group-input field" type="text" id="appointment-phone" placeholder="+7 000-00-00">
+
+<label class="field-group-label" for="appointment-date">
+<input class="field-group-input field" type="text" id="appointment-date" placeholder="01.01.2020">
+
+<!-- Плохо -->
+<label for="appointment-phone" class="field-group-label">
+<input class="field-group-input field" type="text" placeholder="+7 000-00-00" id="appointment-phone" >
+
+<label for="appointment-date" class="field-group-label">
+<input id="appointment-date" class="field-group-input field" type="text" placeholder="01.01.2020">
+
+ Логические атрибуты записаны без значения и в единообразной последовательности во всём документе.
+<!-- Хорошо -->
+<input type="text" disabled required>
+
+<!-- Плохо -->
+<input type="text" disabled="disabled" required="required">
+
+ В записи атрибутов нет пробелов вокруг знака «равно» =
.
<!-- Хорошо -->
+<input class="field-group-input field" type="text" id="appointment-date" placeholder="01.01.2020">
+
+<!-- Плохо -->
+<input class = "field-group-input field" type = "text" id = "appointment-date" placeholder = "01.01.2020">
+
+ <!-- Хорошо -->
+<input class="field-group-input field" type="text" id="appointment-date" placeholder="01.01.2020">
+
+<button class="button" type="button" onclick="show('menu')">
+ Меню
+</button>
+
+<!-- Плохо -->
+<input class='field-group-input field' type='text' id='appointment-date' placeholder='01.01.2020'>
+
+<input class=field-group-input type=text id=appointment-date placeholder=01.01.2020>
+
+<button class="button" type="button" onclick="show("menu")">
+ Меню
+</button>
+
+ iframe
указаны размеры.<!-- Хорошо -->
+<img src="http://github.com/logo.png" alt="" width="300" height="150">
+<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"></svg>
+<video src="http://github.com/source/video.mp4" width="400" height="400"></video>
+<iframe src="https://maps.google.com/" width="400" height="400"></iframe>
+
+<!-- Плохо -->
+<img src="http://github.com/logo.png" alt="">
+<img src="http://github.com/logo.png" alt="" width="300px" height="150px">
+<svg xmlns="http://www.w3.org/2000/svg"></svg>
+<video src="http://github.com/source/video.mp4"></video>
+<iframe src="https://maps.google.com/"></iframe>
+
+ Разделителями в имени класса являются только дефисы -
и подчёркивания _
. В коде необходимо придерживаться одного стиля.
<!-- Хорошо -->
+<input class="form-input form-input-field" type="text">
+<input class="form_input form_input_field" type="text">
+<input class="form__input form-input__field" type="text">
+<input class="form--input form-input--field" type="text">
+
+<!-- Плохо -->
+<input class="formInput formInputField" type="text">
+<input class="form-input form_input_field" type="text">
+
+ method
в формеВ атрибуте method
указан тип отправки данных.
<!-- Хорошо -->
+<form method="post"></form>
+<form method="get"></form>
+
+<!-- Плохо -->
+<form method=""></form>
+<form></form>
+
+
+ Стилевые файлы подключены с помощью <link>
внутри <head>
. При этом атрибут type
для тега <link>
не указан, так как его значение text/css
устанавливается по умолчанию.
+
<!-- Хорошо -->
+<!DOCTYPE html>
+<html lang="ru">
+ <head>
+ <link rel="stylesheet" href="http://github.com/style.css">
+ </head>
+ <body>…</body>
+</html>
+
+<!-- Плохо -->
+<!DOCTYPE html>
+<html lang="ru">
+ <head>…</head>
+ <body>
+ <link rel="stylesheet" href="http://github.com/style.css">
+ </body>
+</html>
+ + Скрипты подключены в самом низу страницы, чтобы при её загрузке не блокировать отображение содержимого. +
+
+ При подключении скриптов в теге <script>
атрибут type
не указан, так как его значение text/javascript
устанавливается по умолчанию.
+
<!-- Хорошо -->
+<!DOCTYPE html>
+<html lang="ru">
+ <head>…</head>
+ <body>
+ <!-- Содержимое страницы -->
+ <script src="http://github.com/app.js"></script>
+ </body>
+</html>
+
+<!-- Плохо -->
+<!DOCTYPE html>
+<html lang="ru">
+ <head>
+ <script src="http://github.com/app.js"></script>
+ </head>
+ <body>…</body>
+</html>
+ + Документ проходит проверку на валидность. Для проверки используется современный валидатор. +
+@import
+ Правило @import
работает медленнее, чем тег <link>
. В стилях @import
не использован.
+
<!-- Хорошо -->
+<link rel="stylesheet" href="http://github.com/module.css">
+
+<!-- Плохо -->
+<style>
+ @import url("http://github.com/module.css");
+</style>
+ Селекторы и свойства записаны строчными буквами.
+/* Хорошо */
+.element {
+ color: #ff0000;
+}
+
+/* Плохо */
+.Element {
+ Color: #ff0000;
+}
+
+.ELEMENT {
+ COLOR: #ff0000;
+}
+
+
+ /* Хорошо */
+.block {
+ margin-bottom: 0;
+ margin-top: 0;
+ font-size: 14px;
+ line-height: 20;
+ color: #ff0000;
+}
+
+.element {
+ background-color: #000000;
+}
+
+/* Плохо */
+.block{margin-bottom: 0;
+ margin-top: 0;
+ font-size: 14px;line-height: 20;
+ color :#ff0000}
+.element {
+ background-color: #000000;
+}
+
+ /* Хорошо */
+.alert-danger { … }
+.tweet .user-picture { … }
+.button { … }
+.layout-center { … }
+
+/* Плохо */
+.testElement { … }
+.t { … }
+.big_red_button { … }
+.knopka { … }
+ Селекторы, разделённые запятой, записаны на новых строках.
+/* Хорошо */
+h1,
+h2,
+h3 {
+ margin-top: 0;
+}
+
+/* Плохо */
+h1, h2, h3 {
+ margin-top: 0;
+}
+
+ До и после комбинатора между селекторами стоит один пробел.
+/* Хорошо */
+h2 + h3 {}
+ul > li {}
+
+/* Плохо */
+h2+h2 p{}
+ul >li {}
+
+ rgba
или hsla
, если нужна прозрачность./* Хорошо */
+.block {
+ background-color: #ff0000;
+ border-left-color: #00ff00;
+ color: rgba(0, 0, 0, 0.5);
+}
+
+/* Плохо */
+.block {
+ background-color: #F00;
+ border-left-color: rgb(0, 255, 0);
+ color: black;
+}
+
+ /* Хорошо */
+.field[type="text"] {
+ background-image: url("http://github.com/images/cat.jpg");
+}
+
+/* Плохо */
+.field[type=text] {
+ background-image: url(http://github.com/images/cat.jpg);
+}
+
+
+ /* Хорошо */
+.block {
+ opacity: 0.5;
+ background-color: rgba(0, 0, 0, 0.5);
+}
+
+/* Плохо */
+.block {
+ opacity: .5;
+ background-color: rgba(0, 0, 0, .5);
+}
+
+.element {
+ color: rgba(0 ,0 ,0 ,0.5);
+}
+
+
+ /* Хорошо */
+.block {
+ margin: 0;
+ margin-left: 20px;
+ border: 10px solid #000000;
+ border-bottom-color: #ff0000;
+}
+
+/* Плохо */
+.block {
+ margin-left: 10px;
+ border-left: 10px solid #000000;
+ margin-left: 20px;
+ border-left: 10px solid #ff0000;
+}
+
+ /* Хорошо */
+:root {
+ --size: 0px;
+}
+
+.element {
+ border: 0;
+ box-shadow: 0 1px 2px #cccccc, inset 0 1px 0 #ffffff;
+ margin-top: 0;
+ width: calc(100% - var(--size));
+}
+
+/* Плохо */
+:root {
+ --size: 0;
+}
+
+.element {
+ border: 0px;
+ box-shadow: 0px 1px 2px #cccccc, inset 0px 1px 0 #ffffff;
+ margin-top: 0px;
+ width: calc(100% - var(--size));
+}
+
+
+ В дробных значениях нет больше двух знаков после точки.
+/* Хорошо */
+.block {
+ width: 2.33%;
+}
+
+/* Плохо */
+.block {
+ width: 2.33333%;
+}
+
+ !important
!important
не использовано для борьбы со специфичностью.!important
./* Хорошо */
+.visually-hidden {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ margin: -1px !important;
+ border: 0 !important;
+ padding: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ overflow: hidden !important;
+}
+
+/* Плохо */
+.element {
+ font-size: 17px !important;
+}
+
+
+ Контент скрыт утилитарным классом visually-hidden
, чтобы он был доступен для скринридеров и поисковиков.
+
/* Хорошо */
+.visually-hidden {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ margin: -1px;
+ border: 0;
+ padding: 0;
+ white-space: nowrap;
+ clip-path: inset(100%);
+ clip: rect(0 0 0 0);
+ overflow: hidden;
+}
+ <h2 class="visually-hidden">Заголовок</h2>
+ /* Плохо */
+h1 {
+ font-size: 0;
+}
+
+.title {
+ display: none;
+}
+ + Объявления логически связанных свойств сгруппированы в следующем порядке: +
++ Позиционирование следует первым, потому что оно влияет на положение блоков в потоке документа. Блочная модель идёт следующей, так как она определяет размеры и расположение блоков. +
++ Все остальные объявления, которые изменяют вид внутренних частей блоков и не оказывают влияния на другие блоки, идут в последнюю очередь. +
++ Сгруппированные объявления в правиле отделены друг от друга пустой строкой. +
+
+ Порядок объявления подробных правил, таких как font-size
, font-family
, line-height
, соответствует порядку в сокращённой версии правила. В случае совместного использования подробных и сокращённых правил, первой идёт сокращённая версия.
+
.declaration-order {
+ /* Позиционирование */
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 100;
+
+ /* Блочная модель */
+ display: block;
+ float: right;
+ width: 100px;
+ height: 100px;
+ margin: 10px;
+ padding: 10px;
+
+ /* Типографика */
+ font-family: "Arial", sans-serif;
+ font-style: normal;
+ font-size: 13px;
+ line-height: 20px;
+ font-weight: 700;
+ text-align: center;
+ color: #333333;
+
+ /* Оформление */
+ background-color: #f5f5f5;
+ border: 1px solid #e5e5e5;
+ border-radius: 3px;
+ opacity: 1;
+
+ /* Анимация */
+ transition: color 1s;
+
+ /* Разное */
+ will-change: auto;
+}
+ Для правильного форматирования используйте файл .editorconfig в вашем редакторе.+ +
Для отступов используются два пробела. Знак табуляции не используется
+ +При переносах в продолжении строки используется четыре пробела
+ +Запрещено одновременное использование табов и пробелов для отступов
+ +Для отступов ключевых слов, операторов и т. д. используется не более одного пробела
+const name = 1;
+const longerName = 2;
+
+ const name = 1;
+const longerName = 2;
+
+ Открывающие скобки блоков кода находятся на одной строке с оператором, который их использует:
+if (condition)
+{
+ // code
+}
+
+ if (condition) {
+ // code
+}
+ В однострочных блоках кода, код отделен от открывающей и закрывающей скобки пробелом
+ +В однострочных массивах скобки не отделяются пробелами, первое значение идёт непосредственно после открывающей скобки, а закрывающая скобка идёт непосредственно после последнего значения массива
+ +После запятой всегда должен ставиться пробел, если запятая не в конце строки
+ +Обязательно переносить запятую на новую строку при объявлении массивов и объектов. Обязательно использовать запятую в конце списков, объектов или перечислений параметров функции
+const foo = {
+ a: 1,
+ b: 2
+};
+
+const bar = [
+ 1,
+ 2
+];
+ const foo = {
+ a: 1,
+ b: 2,
+};
+
+const bar = [
+ 1,
+ 2,
+];
+
+ Файл должен заканчиваться пустой строкой
+ +Строка не должна заканчиваться пробелами
+ +В однострочных объектах и при деструктуризации фигурные скобки не отделяются пробелами от содержимого
+const foo = { a: 1 };
+
+ const foo = {a: 1};
+
+ const { a, b } = someObject;
+
+ const {a, b} = someObject;
+
+ Смысловые блоки кода отделяются друг от друга не более чем двумя пустыми строками
+ +В качестве символа переноса строки используется стандартный символ, который используется в системе
+ +При объявлении вычисляемых ключей в объектах с помощью синтаксиса ES2016 в квадратных скобках не используются пробелы
+ +Оператор вызова функции ()
отделяется пробелом от названия функции
В объектах после объявления ключа не ставится пробел. После двоеточия, которое отделяет в объектах ключ от значения может стоять только один пробел, выравнивать несколько значений при объявлении многострочного объекта запрещено
+ +Ключевые слова отделяются пробелами. Правило касается всех блоков, которые не оговорены отдельно в других правилах. В частности ключевые слова должны отделяться пробелами для условных операторов, циклов, операторов множественного выбора, блоков try..catch
, объявлений классов и т. д.
В блоках кода первая и последняя строка не должны быть пустыми (код не отбивается от начала блока кода)
+ +После двоеточий и точек с запятыми ставятся пробелы. Перед ними — не ставятся
+ +Перед скобками начинающими новый блок кода должен ставиться пробел
+ +В комментариях текст отбивается пробелом от начала комментария
+ +При создании генераторов, звездочка идёт сразу после ключевого слова function
без пробелов
Звездочка после ключевого слова yield
не отбивается пробелом. После звездочки пробел ставится всегда
В spread-операторе точки не отделяются от названия коллекции
+В строках, объявленных с помощью одинарных кавычек, запрещено использовать переносы
+ +В строках запрещено указывать код спецсимволов в восьмеричной системе счисления
+const foo = 'Copyright \251';
+
+ const foo = 'Copyright \u00A9';
+
+ При создании объектов через литералы свойства должны объявляться в едином стиле: или без кавычек или с ними
+ +В строках используются одинарные кавычки. Разрешено использовать строковые шаблоны в случаях, когда необходима интерполяция
+В числах запрещено опускать ноль в дробной и целой части
+ +Запрещено использовать ведущий ноль при создании чисел, поскольку это приводит к созданию числа в восьмеричной системе счисления
+Массивы должны создаваться через литерал массива, а не через конструктор. Допустимое исключение — создание массива определенной длины
+ +Объекты должны создаваться через литерал объекта, а не через конструктор
+ +При создании объектов запрещено дублирование ключей
+ +При описании функций запрещено дублировать названия параметров
+ +В операторе switch
запрещено дублировать условия (case)
В бинарных и тернарных операторах операнды и символы оператора отделяются пробелами
+ +Унарные операторы не отделяются от операнда пробелом. Исключения составляют операторы, состоящие из слов, а не символов, например оператор typeof
Все переменные должны быть названы в верблюжьем регистре (camelCase). Исключения составляют константы, которые должны именоваться прописными буквами в константном регистре (CONSTANT_CASE) и названия классов, функций-конструкторов и перечислений, которые именуются с заглавной буквы (PascalCase)
+ +Запрещено использовать имена переменных, которые используются во внешних областях видимости
+ +Запрещено называть переменные и свойства ключевыми словами JS
+ +Запрещено использовать переменные, не объявленные ранее. При использовании переменной, объявленной в другом модуле в глобальной области видимости, нужно обращаться к ней как к свойству объекта window
Запрещено напрямую обращаться к значению undefined
. Для проверки типа рекомендуется использовать typeof
. Исключение составляет явная передача undefined
при вызове функции вместо аргумента, чтобы использовать значение параметра по умолчанию
Все точки с запятой должны быть проставлены явно, не стоит рассчитывать на автоматическую расстановку точек с запятой ASI (Automatic Semicolon Insertion)
+ +Не рекомендуется использовать указатель Unicode BOM в коде, потому что код должен быть сохранен не в кодировке UTF-16, а в кодировке UTF-8, в которой нет указателя порядка бит
+ +Обязательно используются блоки кода, даже если в выражении содержится одна строчка
+ +В коде нет пустых блоков кода
+ +Код работает в строгом режиме: в начале всех файлов явно прописана директива "use strict"
или используются модули ECMAScript, которые по умолчанию работают в строгом режиме
Запрещена «проверка Йоды» — в условных операторах в блоке условия при сравнении переменной или свойства со значением сначала идет переменная или свойство объекта и только потом значения, а не наоборот.
+if (1 === myValue) { /*...*/ }
+
+ if (myValue === 1) { /*...*/ }
+ При сравнении двух значений используется оператор строгого сравнения вместо оператора нестрогого сравнения
+ +В условных операторах не используется оператор присвоения
+ +В условиях не используется небезопасное отрицание, например использование !
в in
или instanceof
без скобок
Запрещено сравнение с NaN
. Для проверки, является ли результат операции числовым, нужно использовать Number.isNaN
Запрещено использовать case
без break
или return
в блоках switch
Не используются вложенные тернарные операторы
+Если в функции используется ветвление, в котором есть возврат значения, то return
должен быть добавлен и в остальных ветках.
const doThings = function() {
+ if (cond) {
+ return 1;
+ } else {
+ doSomethingElse();
+ }
+};
+
+ const doThings = function() {
+ if (cond) {
+ return 1;
+ } else {
+ return doSomethingElse();
+ }
+};
+
+ Это правило предотвращает создание функций, при использовании которых непонятно, вернут ли они какое-то значение. В первом примере, функция do
может вернуть значение 1
, а может undefined
Единственное исключение — использование return
без значения для прекращения работы функции:
const doThings = function() {
+ if (cond) {
+ doSomething()
+ return;
+ }
+
+ doSomethingElse();
+};
+
+ В return
не используется оператор присваивания
В стрелочных функциях всегда используются скобки для параметров, даже если параметр один
+В конструкторе классов-наследников обязательно вызывается super()
В конструкторе нет обращения к this
до того, как будет вызван super()
При объявлении переменных предпочтение отдается ключевым словам let
и const
. Переменные объявляются через var
только при наличии проблем с поддержкой ECMAScript 2015
Запрещено переопределять с помощью ключевого слова ранее созданные переменные
+ +Запрещено использовать множественное объявление через одно ключевое слово. Для каждой переменной используется отдельный var
, let
или const
.
const a = 1, b = 2;
+
+ const a = 1;
+const b = 2;
+ Запрещено переопределение функций, созданных с помощью функционального объявления (function declaration)
+function myFunc() {};
+myFunc = 2;
+
+ Новые функции не создаются с помощью конструктора Function
Вместо коллекции arguments
, используется rest-оператор, если это позволяет версия языка
Для превращения массива с данными в аргументы вместо вызова функции через apply
используется spread-оператор, если это позволяет версия языка
Math.max.apply(null, [1, 100, 15, 1000]);
+
+ Math.max(...[1, 100, 15, 1000]);
+
+ Не вызываются служебные конструкторы, создающие объекты из глобальной области видимости Math()
, JSON()
, Reflect()
При создании непустых массивов запрещено опускать пустые значения (ставить подряд несколько запятых)
+ +Для создания новых значений не используются конструкторы примитивов String
, Number
, Boolean
Конструкторы вызываются со скобками, даже если у них нет параметров
+ +Символы (Symbol
) создаются вызовом функции Symbol
без ключевого слова new
Не используется конструкция with
Не используются alert
Не используется выполнение кода через eval
Не используется неявный eval
— в функциях, которые поддерживают передачу исполняемого кода как строку, например setTimeout
В ссылках используется протокол javascript:
Конструкторы не используются без ключевого слова new
В функциях не используются обращения к caller
и callee
Встроенные в язык объекты и прототипы не расширяются в рантайме
+ +Не переопределяются глобальные значения (undefined
, null
, Object
, window
и прочие)
bind
не используется вне методов классов
В функциях, которые не являются методами никакого объекта или класса, не используется this
Переменные, объявленные через var
не удаляются оператором delete
Не используется лишнее приведение к Boolean. Например, нет большого смысла переводить в boolean условия в конструкциях if
, while
, for
, в первом операнде тернарного оператора
Оператор typeof
используется корректно — используются только правильные значения, возвращаемые оператором, не производится сравнения со строковыми литералами, которые содержат некорректные значения typeof
В parseInt
обязательно передается второй параметр — основание системы счисления, даже в случае с десятичной системой счисления
В блоки условия операторов if
, while
, for
и тернарного оператора не передается константное значение, которое подразумевает, что условие выполняется (или не выполняется) всегда
if (true) {}
+
+ if (a > 1) {}
+
+ const ternaryValue = true ? 'a' : 'b';
+
+ const ternaryValue = isA() ? 'a' : 'b';
+ Не используются лишние (множественные) точки с запятой
+В коде не используются оставленные выводы в консоль
+ +В коде нет забытых инструкций debugger
В проекте нет недоступного кода, который никогда не выполнится
+if (false) {
+ doSomething();
+}
+
+ if (needToDoSomething()) {
+ doSomething();
+}
+
+ В коде нет объявленных, но неиспользуемых переменных
+Для выбрасывания исключения в оператор throw
передаются только объекты Error. Передавать литералы запрещено.
throw 'Passed value is out of range';
+
+ throw new RangeError('Passed value is out of range');
+
+ В конструкции try..catch
запрещен пустой блок catch
При итерировании по объектам через for..in
при работе со свойствами используется конструкция hasOwnProperty
В объектах напрямую не переопределяется свойство __iterator__
В объектах напрямую не переопределяется свойство __proto__
. Разрешено переопределять __proto__
через Object.create
или запись в прототип, объектов, созданных другими конструкторами, но напрямую редактировать __proto__
нельзя
const obj = {
+ __proto__: Parent
+};
+
+ const Obj = function() {};
+Obj.prototype = new Parent();
+const obj = new obj;
+
+const obj = Object.create(Parent.prototype);
+
+ В коде не используются лейблы. Лейблы используются с конструкциями break
и continue
для направленного выхода из цикла и могут привести к слишком сложному для понимания коду
Блоки, использующиеся в коде, должны описывать тело функции, условия, оператора switch
и прочие конструкции, относящиеся к группировке множественных операций. Блоки не должны использоваться сами по себе, любой блок должен быть частью другого выражения
В коде не используется оператор «запятая» для описания последовательностей действий. Для создания переменных используются отдельные ключевые слова let
, const
, var
, операторы группировки, условные операторы и прочие конструкции. Исключение составляет начальное условие оператора for
const result = (1, 2); // 2
+
+ const result = 2;
+ switch (val = getVal(), val) {}
+
+ val = getVal();
+switch(val) {}
+
+for (let i = 0, l = 100; i < l; i++);
+ В регулярных выражениях не используются «управляющие выражения»
+ +В регулярных выражениях не используются пустые классы символов []
(блоки, ограниченные квадратными скобками)
В коде регулярные выражения не создаются через конструктор RegExp
из строки, которая не может быть разобрана как правильное регулярное выражение
В регулярных выражениях не используются нескольких последовательных пробелов. Вместо этого предлагается использовать модификаторы количества
+/ /.exec(myString);
+
+ /\s\s\s/.exec(myString);
+
+ /\s{3}/.exec(myString);
+