<style>* { display: block }</style>,然后<title>就显示在了文档里,它本就该如此这般。可这样的话<style>的内容也显示出来了
这是响应式样式编辑器。
<pre><style contenteditable=plaintext-only>style{display:block}
<head>中的元素并非不可显示,只是用户代理样式表为<head>、<title>、<style>、<script>等设置了display: none。
我的<style>里不管写什么都报语法错
你可能是JSX受害者。糟糕的是<style>里也不识别{
和}
。用{'{'}
和{'}'}
这种技巧吧,即使有多个文本节点把样式表割开,样式似乎也能整段正常生效。
等等,为什么要在JSX里写<style>?每个组件实例都在<body>里写一遍样式只会让你在开发者工具里禁一条又冒出来一条。不过如果你的组件是单例,或者不用React的JSX转换,这样的CSS in JS只会让你的样式变得动态。
让你的头焕然一新
教条规定<style>应该出现在<head>里。就像无论逻辑上属于哪个组件,渲染时都应追加在<body>上的弹出层一样,所以把样式元素传送到头吧。
function App() { const [count, setCount] = useState(0) return <> <button onClick={() => setCount(count + 1)}>{count}</button> {createPortal(<style> html {'{'} color-scheme: {count & 1 ? 'light' : 'dark'}; {'}'} </style>, document.head)} </> } render(<App />, document.body)
画外音:这个站点采用的Crayon足够古老,尚不知JSX是何物……不过貌似我的站点里的代码高亮一直是坏的……
因为头比较重要,所以应用的主体应是头,而把应处于身体中的内容传送走。毕竟,<body>是传送门最常见的目标,没错吧?
function App() { const [count, setCount] = useState(0) return <> <style> html {'{'} color-scheme: {count & 1 ? 'light' : 'dark'}; {'}'} </style> {createPortal(<button onClick={() => setCount(count + 1)}> {count} </button>, document.body)} </> } render(<App />, document.head)
[Vue警告]:不要把Vue挂载到<html>或<body>上,请挂载在普通元素上。
不需要传送门,因为可以靠一个组件渲染出整个文档结构。
<html> <head> <title>App</title> </head> <body> <input type="button"> </body> </html>
这是有效的HTML,也是有效的JSX——<html>和片段的存在的意义等同。
如果返回<head>和<body>构成的片段的话,就可以把应用渲染到<html>里。记得先把现有的<head>和<body>删了。
document.head.remove() document.body.remove()
React和Vue 3都能正确处理。Vue 2会报错:
这是在质疑<html>不够普通吗?很遗憾,对于Vue 2需要支持的Internet Explorer 8来说,是的。
Vue 3起飞了,不仅可以直接挂载在<html>、<head>、<body>上,甚至还可以挂载在document上。
import { createApp } from 'https://unpkg.com/vue@3.3.4/dist/vue.esm-browser.js' const app = createApp({ data() { return { count: 0 } }, template: ` <html> <head> <title>{{ count }}</title> <meta name="color-scheme" :content="count & 1 ? 'light' : 'dark'" /> </head> <body> <button @click="count++">{{ count }}</button> </body> </html> `, }) document.replaceChildren() app.mount(document)
挂载到document自Vue 3.0.0-alpha.1以来就可行(不过那时候的API有些许不同)。可能是因为Vue 3原生支持了Web组件吧,毕竟shadow root和document都是根。
import { createApp } from 'https://unpkg.com/vue@3.0.0-alpha.1/dist/vue.esm.js' document.replaceChildren() createApp().mount({ data() { return { count: 0 } }, template: ` <html> <head> <title>{{ count }}</title> <meta name="color-scheme" :content="count & 1 ? 'light' : 'dark'" /> </head> <body> <button @click="count++">{{ count }}</button> </body> </html> `, }, document)
但是,不像React,Vue对<style>和<script>作了特殊处理,会滤除模板中的这些标签。
[Vue warn]: Template compilation error: Tags with side effect (<script> and <style>) are ignored in client component templates.
但是,这是模板编译时行为,只消一个<component is="style">
,就能让<style>漏到运行时去。
而React完全做不到把组件渲染在document上。
Vue为什么是神
Vue为什么是神?在谈论这个问题之前,我想先说说其他前端框架相较于Vue究竟差在了哪里。首先是犯下傲慢之罪的React……
审查审查审查元素
可以在取消停靠的Chrome开发者工具中按Ctrl+Shift+I打开开发者工具的开发者工具,此为审查审查元素。
Solid Playground采用Chii以在网页上嵌入Chrome开发者工具,获得不一样的本地远程调试体验,这其他浏览器中也能正常运行,故可在Firefox开发者工具中检查Chrome开发者工具。
看来CodeMirror是Web代码编辑器的版本答案。
兼容性速报
Chrome和Firefox分别已于112和117版本开始支持原生CSS规则嵌套,只是开发者工具支持有待提升。配合可构造的样式表,不可调试性已经拉满了。
const s = new CSSStyleSheet s.replaceSync('&{&{&{&{&{&{&{&{}}}}}}}}') document.adoptedStyleSheets = [s]