span等行内元素空格问题与prettier.htmlWhitespaceSensitivity

8,851 阅读3分钟

span等行内元素空格问题

在写span等行内元素时,编辑器或者prettier会自动进行格式化,一般情况下,会对span做自动换行,比如这样:

span被换行后,在浏览器中的表现会是一个空格的距离。 这个空格的距离具体是多大呢?它是当前字体大小的一半。 如果避免这个空格,有如下几种办法:1)让编辑器不要给span标签自动换行;2)给父元素设置font-size为0,然后再给span设置自己的font-size;3)给span前面的文字增加a标签,比如将上图中改写为:

htmlWhitespaceSensitivity

回到第一个解决办法,就是让编辑器知道这是空格敏感模式 htmlWhitespaceSensitivity。 Prettier官网上对htmlWhitespaceSensitivity的描述:Specify the global whitespace sensitivity for HTML files, see whitespace-sensitive-formatting

大意是是对于空格的处理,如果是css的话,就根据标签的display属性,正常的行内元素不换行,strict是所有的空格换行情况都保留,ignore的话就是所有元素间的空格都会被忽略,直接另起一行。主要是浏览器中对于代码换行和空格会比较敏感,css 和strict就是两种程度不同的格式化模式。

看到这里可能还觉得有点迷糊。下面给一个完整的示例:

格式化之前:

格式化之前
ignore模式:
ignore模式
css模式:
css模式
strict模式:
strict模式

可以看到ignore模式下,span和div都被完整的换行了。 css模式下,只有div被换行,span是和上一个标签的>连在一起;表示span没有被自动换行,在浏览器里显示不会出现span这类元素的空格问题。只要在coding的时候span不是换行的,那么prettier也会很知趣的不自动换行。 strict模式下,div和span都和上一个标签的>连载一起。这样可以对某些div的display被改为inline-block的情况也进行保护。只要coding的时候div或者span没有换行,prettier也不会自动去换行,以免引入空格造成样式问题。

(注意到上面span的内容仍然有一些换行,是由于prettier里面对printWidth设置了80;所以超出80就会换行。如果需要对这种浏览器的显示做处理,就需要word-break等属性的配合)

vscode配置

在写vue的时候应该没有人不安装vetur插件吧。那么prettier和vetur的格式化差异,就不得不重视起来。(如果安装了eslint插件,那么他们的格式化差异也要统筹考虑。) vue文件的格式化,vscode settings里常见配置为vetur的fomatter,比如:

"[vue]": {
    "editor.defaultFormatter": "octref.vetur"
  },

但是vue采用vetur的配置会导致vue文件会被编辑器全部自动换行。

有时候会发现明明工程中的prettierrc.js里 htmlWhitespaceSensitivity 配置的是 strict,但是span等标签仍然被自动换行处理了,就是这里的vetur formatter 的影响。

如果不想被自动换行,则还需要设置 "vetur.format.defaultFormatter.html": "js-beautify-html" 来表示vue里采用span不换行。

但是这种情况会发生 vetur的格式化和prettire可能发生不一致的情况,需要协调。所以不如将 vue的formatter直接设置为 esbenp.prettier-vscode:

"[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },

可参考配置

vscode settings:

{
  "git.enabled": false,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "search.followSymlinks": false,
  "javascript.implicitProjectConfig.experimentalDecorators": true,
  "emmet.includeLanguages": {
    "vue-html": "html",
    "vue": "html",
    "javascript": "javascriptreact",
    "wxml": "html"
  },
  "emmet.syntaxProfiles": {
    "vue-html": "html",
    "vue": "html"
  },
  "eslint.alwaysShowStatus": true,
  "eslint.run": "onSave",
  "editor.formatOnSave": true
}

工程中的.prettierrc.js

module.exports = {
  printWidth: 80,
  tabWidth: 2,
  useTabs: false,
  semi: false,
  singleQuote: true,
  trailingComma: 'es5',
  bracketSpacing: true,
  jsxBracketSameLine: false,
  arrowParens: 'always',
  proseWrap: 'never',
  htmlWhitespaceSensitivity: 'strict',
  endOfLine: 'lf',
}

reference

www.cnblogs.com/aloehui/p/9… blog.csdn.net/ubuntu_yang… blog.csdn.net/real_lt/art… blog.csdn.net/u010007013/… blog.csdn.net/StacyMo/art… blog.csdn.net/promiseCao/… blog.csdn.net/microcosmv/…