{"componentChunkName":"component---src-templates-post-jsx","path":"/blog/polypane-30-1-selector-specificity-insights-server-html-validation-and-more/","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nconst _frontmatter = {\n  \"title\": \"Polypane 30.1: Selector specificity insights, server HTML validation, and more\",\n  \"cover\": \"/img/mail/icon.svg\",\n  \"date\": \"2026-08-28\",\n  \"type\": [\"announcement\"]\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n    components\n  } = _ref,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, `Polypane 30.1 adds selector specificity highlighting to the elements panel, a new server-sent HTML view in the sources panel, passkey support on Linux and a bunch of improvements and fixes. Like Polypane 30 this release is built on Chromium 152.`), mdx(PolypaneIntro, {\n    mdxType: \"PolypaneIntro\"\n  }), mdx(\"h2\", {\n    \"id\": \"selector-specificity-insights\"\n  }, `Selector specificity insights`), mdx(\"p\", null, `Back in 2020 we launched Polypane's Elements panel, which pioneered showing the selector specificity of your styles right in the elements panel. Not much later we added an online `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/css-specificity-calculator/\"\n  }), `specificity calculator`), ` that you could open from the Elements panel to explain selectors.`), mdx(\"p\", null, `In Polypane 30.1, we're taking this a step further.`), mdx(\"p\", null, `When you hover over a selector in the elements panel, Polypane will now highlight the parts of the selector that contribute to its specificity. It works for plain selectors:`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: specificity1,\n    alt: \"Selector specificity insights\"\n  }), mdx(\"p\", null, `and for nested selectors as well:`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: specificity2,\n    alt: \"Selector specificity insights\"\n  }), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, `When you nest CSS, Polypane shows the resolved selector for the nested rule in the tooltip so you know what the engine is doing under the hood. And now this is of course also highlighted!`)), mdx(\"p\", null, `For nested CSS selectors, you can see that not only does it highlight the parent selector values, but is also intelligent enough to know that `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `.card, #highspecificity`), ` counts as a single ID selector, even if `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `#highspecificity`), ` is not part of the DOM.`), mdx(\"p\", null, `Lastly, If you have a complex selector with lots of nesting, Polypane's highlighting will drill down to highlight the pertinent parts, rather than listing the single top-level wrapped `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `:is()`), ` as being one value:`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: specificity3,\n    alt: \"Selector specificity insights\"\n  }), mdx(\"p\", null, `Drilling down into the selector required us to rebuild our specificity calculation engine, but the end result is an even more robust, accurate and understandable specificity.`), mdx(\"p\", null, `We made all of these improvements available in our free online `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/css-specificity-calculator/\"\n  }), `specificity calculator`), ` as well, so check it out!`), mdx(\"h2\", {\n    \"id\": \"gap-values-in-peek-tooltip\"\n  }, `Gap values in Peek tooltip`), mdx(\"p\", null, `When you use the Peek tool to inspect an element, Polypane will now show you the gap values in the tooltip. Just like the Padding and Margin values, this lets you quickly check the gap values without needing to go to the Elements panel and finding the right declaration.`), mdx(\"h2\", {\n    \"id\": \"passkeys-support-on-linux\"\n  }, `Passkeys support on Linux`), mdx(\"p\", null, `Polypane has had support for passkeys/webauthn on Windows and Mac, which both have operating-system backends to support them, and now Linux support has been added as well. The Linux implementation uses software passkeys through 1Password's `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `passkey-rs`), ` library.`), mdx(\"p\", null, `Because the Linux implementation does not rely on a platform backend it comes with a custom UI:`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: passkeylinux,\n    alt: \"Passkey support on Linux\"\n  }), mdx(\"p\", null, `This brings parity between the three platforms when it comes to passkey support, and allows you to test your passkey implementations on all three platforms!`), mdx(\"h2\", {\n    \"id\": \"server-sent-html-view-in-the-sources-panel\"\n  }, `Server-sent HTML view in the sources panel`), mdx(\"p\", null, `The sources panel now has a new toggle to switch between the rendered HTML (after your JS has run) and the plain server-sent HTML (before your JS has run). This is useful for debugging server-side rendering issues, and for checking that your server is sending the correct HTML to the browser.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: sourcepanel,\n    alt: \"Server-sent HTML view in the sources panel\"\n  }), mdx(\"p\", null, `Both sets of HTML are validated individually, so you can also easily see where HTML validation errors are being introduced.`), mdx(ThanksCallout, {\n    name: \"Matija\",\n    mdxType: \"ThanksCallout\"\n  }, \" for asking about this feature!\"), mdx(\"h2\", {\n    \"id\": \"updated-placeholdifier-debug-overlay\"\n  }, `Updated placeholdifier debug overlay`), mdx(\"p\", null, `We've updated our placeholdifier debug overlay to use a scribble-style font instead of the block font we used before. This makes the blocked content more \"text-like\" and makes it easier to focus on the design instead of the content.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: placeholdifier,\n    alt: \"Placeholdifier debug overlay\"\n  }), mdx(\"h2\", {\n    \"id\": \"chromium-152\"\n  }, `Chromium 152`), mdx(\"p\", null, `Polypane 30.1 is built on Chromium 152. For all the experimental features enabled in this release, check out the `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/experimental-web-platform-features/\"\n  }), `experimental web platform features overview`), `.`), mdx(\"h2\", {\n    \"id\": \"get-polypane-301\"\n  }, `Get Polypane 30.1`), mdx(\"p\", null, `Polypane is available for Windows, Mac, and Linux in 64-bit and ARM versions. Polypane automatically updates, but you can also go to `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/download/\"\n  }), `the download page`), ` to download the latest version!`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Don't have Polypane yet? There is a 14-day trial available. `, mdx(\"br\", null), ` `, mdx(\"a\", _extends({\n    parentName: \"strong\"\n  }, {\n    \"href\": \"https://dashboard.polypane.app/register\"\n  }), `Try it for free`), `.`), ` No credit card needed.`)), mdx(\"h2\", {\n    \"id\": \"polypane-30-changelog\"\n  }, `Polypane 30 Changelog`), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `New`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Elements panel: Highlight specificity parts in selector`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Source panel: Toggle between rendered and server-sent HTML (Thanks Matija!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Passkey/Webauthn support for Linux`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Updated Chromium`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Improved`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Accessibility panel now also checks for WCAG 2.2 2.5.8 target size`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Show a warning for multiple viewport declarations (Thanks Matija!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: improved header order design and updated ruleset`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: After inspecting an element the DOM tree is now focused`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Peek: show gap values in tooltip`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Debug tools: Placeholdifier now uses a scribble instead of a block font`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Find in page has improved performance`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Browse panel: Basic auth popups are now shown in the browse panel`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Panel: focuses the first ordered panel on launch`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Fixes`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Copy image to clipboard works again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Domain custom color was in wrong position in split views`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Detached network panel shows data again (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Detached panel window shows overflow menu again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: Misaligned layout debugging badge for html element`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: specificity explainer link works again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Devtools panel: Issue on linux where the panel would not show content`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Recording: pages without an explicit background color now record on white instead of black`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Peek: decouple showing font-weight from showing line-height value`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Peek: prevent peek from showing when inspection mode is chrome devtools`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Browse panel: Shortcuts now work in detached panel too`)));\n}\n;\nMDXContent.isMDXComponent = true;","timeToRead":3,"tableOfContents":{"items":[{"url":"#selector-specificity-insights","title":"Selector specificity insights"},{"url":"#gap-values-in-peek-tooltip","title":"Gap values in Peek tooltip"},{"url":"#passkeys-support-on-linux","title":"Passkeys support on Linux"},{"url":"#server-sent-html-view-in-the-sources-panel","title":"Server-sent HTML view in the sources panel"},{"url":"#updated-placeholdifier-debug-overlay","title":"Updated placeholdifier debug overlay"},{"url":"#chromium-152","title":"Chromium 152"},{"url":"#get-polypane-301","title":"Get Polypane 30.1"},{"url":"#polypane-30-changelog","title":"Polypane 30 Changelog"}]},"excerpt":"Polypane 30.1 adds selector specificity highlighting to the elements panel, a new server-sent HTML view in the sources panel, passkey support on Linux and a…","frontmatter":{"title":"Polypane 30.1: Selector specificity insights, server HTML validation, and more","cover":"/img/mail/icon.svg","date":"2026-08-28","updated":null},"fields":{"slug":"/blog/polypane-30-1-selector-specificity-insights-server-html-validation-and-more/","date":"2026-08-27T22:00:00.000Z","ogFileName":"polypane-30-1-selector-specificity-insights-server-html-validation-and-more"}}},"pageContext":{"slug":"/blog/polypane-30-1-selector-specificity-insights-server-html-validation-and-more/"}},"staticQueryHashes":["4164364741","425175329"]}