CSS, HTML, and JSON

Purpose and Scope

This page orients contributors and advanced users to the built-in editing experience for CSS, SCSS, Less, HTML, JSON, and JSON with Comments in VS Code. These languages are important because they sit at the boundary between application code and configuration: style sheets shape UI, HTML contains markup plus embedded CSS and JavaScript, and JSON drives package metadata, workspace settings, launch configurations, tasks, and many extension manifests. The public documentation describes the user experience as out-of-the-box syntax highlighting, IntelliSense, formatting, folding, hovers, color tools, and schema-backed validation, while the repository evidence here shows the shared editor mechanisms that make language-specific behavior consistent across bundled languages.

Sources: src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts, src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts

CSS, SCSS, and Less support is presented to users as style-sheet editing with selectors, properties, values, documentation-rich suggestions, color decorators, an integrated color picker, folding markers, and Emmet abbreviations. HTML support includes syntax highlighting, smart completions, formatting, tag closing, linked editing, document symbols, color picker support inside style sections, and embedded CSS and JavaScript awareness within the current document. JSON support focuses on structured data editing: property and value completions, schema validation, hovers, document symbols, formatting, folding, comments in JSONC mode, and schema associations for well-known configuration files.

Relevant Source Files

  • extensions/git-base/languages/git-commit.language-configuration.json - Demonstrates a bundled language configuration declaring comment syntax, bracket pairs, and auto-closing pairs for an editor language mode.
  • extensions/git-base/languages/git-rebase.language-configuration.json - Mirrors the Git commit language configuration pattern for another bundled mode, showing that language behavior is configured declaratively per language.
  • extensions/git-base/languages/ignore.language-configuration.json - Shows a compact language configuration for ignore files with line comments and auto-closing pairs but without an explicit bracket list.
  • src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts - Implements the basic value-navigation behavior that can increment numbers and cycle known textual value sets such as booleans.
  • src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts - Converts language configuration bracket declarations into immutable opening and closing bracket metadata and regular expressions used by editor features.
  • extensions/copilot/src/extension/completions-core/vscode-node/extension/src/panelShared/languages/index.ts - Exports bundled TextMate grammar assets used by Copilot completion panel UI surfaces, illustrating how language assets can be reused outside the main editor surface.

Core Language Features

For a reader using the product, the first mental model is that CSS, HTML, and JSON are first-class built-in language experiences rather than plain text modes. In CSS-family files, IntelliSense proposes selectors, properties, and values, and proposal details can include browser support information. Color decorators are visible inline, and opening the color preview brings up a color picker for hue, saturation, and opacity. Folding is available for declarations and multiline comments, with region markers such as CSS comment regions supported by the public docs. Emmet abbreviations participate in completion lists alongside other editor suggestions.

HTML builds on the same editor foundation but adds markup-specific affordances. The public documentation describes context-specific element suggestions, automatic closing tags, optional linked editing so matching start and end tags update together, document symbols for DOM navigation by id and class, and hovers over tags or embedded styles and JavaScript. The language service intentionally scopes embedded-language understanding to the content in the current HTML file; script and style includes from other files are not followed by the built-in HTML support. That constraint matters when comparing HTML IntelliSense with full project-wide JavaScript or CSS analysis.

JSON support is shaped by schemas. Users receive suggestions for properties and values even without a schema, but schema association enables structural checks, value validation, documentation hovers, and targeted IntelliSense for common files such as package metadata or VS Code configuration. JSONC, the JSON with Comments mode, is used for VS Code configuration files such as settings, tasks, and launch configurations; it accepts line comments, block comments, and trailing commas. This is why a workspace settings file can be comfortable to edit while still benefiting from schema-aware validation and navigation.

System-to-Code Mapping

The source-backed bridge between those public features and editor behavior is the language configuration contract. A language configuration can declare comment tokens, bracket pairs, and auto-closing pairs. The Git bundled language configurations are not CSS, HTML, or JSON themselves, but they are useful representative examples because they show the same declarative shape used by editor language modes: line comments, optional block comments, bracket pairs such as braces and parentheses, and auto-closing pairs for quotes, brackets, and template-like characters. Those declarations feed shared editor services instead of each language reimplementing bracket or quote behavior independently.

Sources: extensions/git-base/languages/git-commit.language-configuration.json, extensions/git-base/languages/git-rebase.language-configuration.json, extensions/git-base/languages/ignore.language-configuration.json

LanguageBracketsConfiguration is the core source file for bracket semantics in the supplied evidence. It accepts a languageId and a LanguageConfiguration, filters configured bracket pairs, builds cached opening and closing bracket objects, and exposes lookup methods such as getOpeningBracketInfo, getClosingBracketInfo, getBracketInfo, and getBracketRegExp. It also treats colorizedBracketPairs as brackets for bracket-pair colorization. When colorized pairs are not explicitly configured, it takes all brackets except < and >, because many languages use angle brackets as comparison operators and default colorization there can be misleading.

Sources: src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts

That angle-bracket rule is especially relevant when thinking about HTML-like syntax. HTML itself needs tag-oriented behavior, but the generic bracket-colorization layer avoids assuming every configured < and > pair should be colorized in every language. This separation lets language-specific services provide markup intelligence while the common editor infrastructure remains conservative. The same pattern applies to JSON and CSS: a schema service or CSS language service can provide high-level suggestions and validation, while common bracket maps, auto-closing pairs, and editor commands keep everyday structural editing predictable.

Editing Commands and Value Navigation

The supplied BasicInplaceReplace implementation shows another shared editing primitive: value navigation. Its navigateValueSet method tries the first range and text, then a second range and text, and returns a replacement range plus value when it can compute one. Numeric text is incremented or decremented with precision derived from the decimal portion, with a guard that avoids decrementing zero into a negative value. Text values cycle through built-in sets such as true and false, True and False, and common access-modifier groups. This supports quick keyboard-driven edits in structured text.

Sources: src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts

For CSS and JSON users, that behavior maps to small but frequent editing actions: adjusting numeric values, toggling booleans, or replacing known keyword-like values without manually selecting and rewriting the text. The implementation is intentionally generic. It does not need to know that a number is a CSS length, a JSON numeric property, or an HTML attribute value; it operates on selected ranges and textual values supplied by the editor. Higher-level language services can add completions and diagnostics, while the basic replace support handles a narrow, repeatable editing operation.

AI and Embedded Language Surfaces

The Copilot completion panel language index in the supplied evidence exports specific TextMate grammar assets such as JavaScript React, TypeScript React, Markdown math, reStructuredText, CUDA C++, and search results. This is not the same as the built-in CSS, HTML, or JSON language services, but it demonstrates an adjacent pattern inside the repository: language tokenization assets can be packaged and reused by a feature-specific UI surface. When AI completions or chat panels render code-like content, they still need language-aware highlighting and classification to make generated or referenced code readable.

Sources: extensions/copilot/src/extension/completions-core/vscode-node/extension/src/panelShared/languages/index.ts

This distinction helps contributors avoid mixing responsibilities. The main editor’s CSS, HTML, and JSON behavior is about editing real workspace documents: validation, completions, formatting, folding, hovers, and structural navigation. Panel rendering for Copilot or other UI surfaces may need grammar exports to present snippets, search results, or generated code, but that does not automatically imply the full language service is running in that panel. When extending language behavior, decide whether the feature belongs in the document language service, the editor language configuration layer, or a secondary rendering surface.

Compact Reference

AreaPublic behaviorSource-backed implementation signal
CSS, SCSS, LessIntelliSense for selectors, properties, and values; color decorators; color picker; folding; Emmet abbreviationsShared bracket, auto-closing, and value-navigation infrastructure applies to structured text editing
HTMLElement suggestions, auto close tags, linked editing, document symbols, formatting, embedded CSS and JavaScript supportShared bracket configuration remains conservative around < and > unless colorized pairs are explicit
JSON and JSONCSchema-backed IntelliSense, validation, hovers, symbols, formatting, folding, comments and trailing commas in JSONCGeneric value navigation can cycle booleans and adjust numeric literals
Language configurationComments, brackets, and auto-closing pairs are declared per languageGit language configuration files provide representative declarative examples
Bracket metadataOpening and closing bracket lookups plus generated bracket regular expressionsLanguageBracketsConfiguration builds immutable maps from LanguageConfiguration
Panel grammarsFeature-specific UI can reuse grammar assets for syntax-aware renderingCopilot panel language index re-exports selected TextMate grammars

Implementation Details and Settings

Several user-visible settings described in the public docs are worth remembering when diagnosing reports. CSS color decorators can be disabled globally with editor.colorDecorators or scoped per language, for example under [css]. CSS folding can be switched to indentation-based folding through editor.foldingStrategy in a language override. HTML suggestions can be controlled with html.suggest.html5, automatic tag closing can be disabled with html.autoClosingTags, and linked tag editing is enabled with editor.linkedEditing. JSON validation is controlled by json.validate.enable, which affects whether schema-backed errors are reported.

The implementation pattern is layered. Language extensions and services provide domain intelligence such as CSS property metadata, HTML tag completions, or JSON schema validation. Language configurations describe syntax-adjacent editor rules that are cheap, declarative, and shared: comment markers, brackets, quote pairs, and auto-closing behavior. Core editor support classes then turn those declarations into fast runtime structures or generic editing commands. This layered design makes the built-in experience feel cohesive while allowing each language to keep its own semantics and settings.

Next Steps

If you are adding or debugging CSS, HTML, or JSON behavior, start by identifying the layer involved. Completion quality, validation, hovers, and formatting usually belong to the relevant language service or bundled extension. Unexpected bracket highlighting, pair matching, or auto-closing behavior should be traced through language configuration and LanguageBracketsConfiguration. Numeric or boolean keyboard replacement behavior should be compared with BasicInplaceReplace. For adjacent rendering in AI panels, inspect the feature-specific grammar packaging pattern rather than assuming a full editor language mode is involved.