diff --git a/docs/rules/html-indent.md b/docs/rules/html-indent.md
index 0b407c955..39a34fe88 100644
--- a/docs/rules/html-indent.md
+++ b/docs/rules/html-indent.md
@@ -65,6 +65,7 @@ This rule enforces a consistent indentation style in ``. The default s
{
"vue/html-indent": ["error", type, {
"attribute": 1,
+ "baseIndent": 1,
"closeBracket": 0,
"alignAttributesVertically": true,
"ignores": []
@@ -74,6 +75,7 @@ This rule enforces a consistent indentation style in ``. The default s
- `type` (`number | "tab"`) ... The type of indentation. Default is `2`. If this is a number, it's the number of spaces for one indent. If this is `"tab"`, it uses one tab for one indent.
- `attribute` (`integer`) ... The multiplier of indentation for attributes. Default is `1`.
+- `baseIndent` (`integer`) ... The multiplier of indentation for top-level statements. Default is `1`.
- `closeBracket` (`integer`) ... The multiplier of indentation for right brackets. Default is `0`.
- `alignAttributesVertically` (`boolean`) ... Condition for whether attributes should be vertically aligned to the first attribute in multiline case or not. Default is `true`
- `ignores` (`string[]`) ... The selector to ignore nodes. The AST spec is [here](https://github.com/mysticatea/vue-eslint-parser/blob/master/docs/ast.md). You can use [esquery](https://github.com/estools/esquery#readme) to select nodes. Default is an empty array.
@@ -144,3 +146,15 @@ This rule enforces a consistent indentation style in ``. The default s
/>
```
+
+:+1: Examples of **correct** code for `{baseIndent: 0}`:
+
+```html
+
+
+
+ Hello!
+
+
+
+```
diff --git a/lib/rules/html-indent.js b/lib/rules/html-indent.js
index ca9cb4f11..8924a9c19 100644
--- a/lib/rules/html-indent.js
+++ b/lib/rules/html-indent.js
@@ -44,6 +44,7 @@ module.exports = {
type: 'object',
properties: {
'attribute': { type: 'integer', minimum: 0 },
+ 'baseIndent': { type: 'integer', minimum: 0 },
'closeBracket': { type: 'integer', minimum: 0 },
'switchCase': { type: 'integer', minimum: 0 },
'alignAttributesVertically': { type: 'boolean' },
diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js
index 0c5303e4f..6e92b4912 100644
--- a/lib/utils/indent-common.js
+++ b/lib/utils/indent-common.js
@@ -882,7 +882,9 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
VElement (node) {
if (node.name !== 'pre') {
- processNodeList(node.children.filter(isNotEmptyTextNode), node.startTag, node.endTag, 1)
+ const isTopLevel = node.parent.type !== 'VElement'
+ const offset = isTopLevel ? options.baseIndent : 1
+ processNodeList(node.children.filter(isNotEmptyTextNode), node.startTag, node.endTag, offset)
} else {
const startTagToken = tokenStore.getFirstToken(node)
const endTagToken = node.endTag && tokenStore.getFirstToken(node.endTag)
diff --git a/tests/fixtures/html-indent/opts-base-indent-0.vue b/tests/fixtures/html-indent/opts-base-indent-0.vue
new file mode 100644
index 000000000..3313f9603
--- /dev/null
+++ b/tests/fixtures/html-indent/opts-base-indent-0.vue
@@ -0,0 +1,8 @@
+
+
+
+
+ Hello!
+
+After
+
diff --git a/tests/fixtures/html-indent/opts-base-indent-1.vue b/tests/fixtures/html-indent/opts-base-indent-1.vue
new file mode 100644
index 000000000..4366d6f6c
--- /dev/null
+++ b/tests/fixtures/html-indent/opts-base-indent-1.vue
@@ -0,0 +1,8 @@
+
+
+
+
+ Hello!
+
+ After
+
diff --git a/tests/fixtures/html-indent/opts-base-indent-2.vue b/tests/fixtures/html-indent/opts-base-indent-2.vue
new file mode 100644
index 000000000..dfff28373
--- /dev/null
+++ b/tests/fixtures/html-indent/opts-base-indent-2.vue
@@ -0,0 +1,8 @@
+
+
+
+
+ Hello!
+
+ After
+