this repo has no description
at main 546 lines 36 kB view raw
1-- BigQuery query for HTTP Archive CSS + HTML observables 2-- Generated: 2026-02-18 3-- Scans parsed_css ONCE for CSS properties, selectors, and at-rules 4-- Scans pages for HTML element usage via custom_metrics.element_count 5-- Uses efficient single-scan approach with REGEXP_EXTRACT_ALL on JSON strings 6 7DECLARE crawl_date DATE DEFAULT '2026-01-01'; 8 9-- ============================================================================= 10-- LOOKUP TABLES: observable names and their web-feature ID mappings 11-- ============================================================================= 12WITH css_property_lookup AS ( 13 SELECT * FROM UNNEST([ 14 STRUCT('align-content' AS observable, 'flexbox,grid,align-content-block' AS feature_ids), 15 STRUCT('align-items' AS observable, 'flexbox,grid,anchor-positioning' AS feature_ids), 16 STRUCT('align-self' AS observable, 'flexbox,grid,anchor-positioning' AS feature_ids), 17 STRUCT('display' AS observable, 'flexbox,grid,display-animation,mathml,two-value-display' AS feature_ids), 18 STRUCT('flex' AS observable, 'flexbox' AS feature_ids), 19 STRUCT('flex-basis' AS observable, 'flexbox' AS feature_ids), 20 STRUCT('flex-direction' AS observable, 'flexbox' AS feature_ids), 21 STRUCT('flex-flow' AS observable, 'flexbox' AS feature_ids), 22 STRUCT('flex-grow' AS observable, 'flexbox' AS feature_ids), 23 STRUCT('flex-shrink' AS observable, 'flexbox' AS feature_ids), 24 STRUCT('flex-wrap' AS observable, 'flexbox' AS feature_ids), 25 STRUCT('justify-content' AS observable, 'flexbox,grid' AS feature_ids), 26 STRUCT('justify-items' AS observable, 'flexbox,grid,anchor-positioning' AS feature_ids), 27 STRUCT('order' AS observable, 'flexbox' AS feature_ids), 28 STRUCT('place-content' AS observable, 'flexbox,grid' AS feature_ids), 29 STRUCT('place-items' AS observable, 'flexbox,grid,anchor-positioning' AS feature_ids), 30 STRUCT('place-self' AS observable, 'flexbox,grid,anchor-positioning' AS feature_ids), 31 STRUCT('position' AS observable, 'flexbox' AS feature_ids), 32 STRUCT('outline' AS observable, 'outline' AS feature_ids), 33 STRUCT('column-gap' AS observable, 'flexbox-gap,grid' AS feature_ids), 34 STRUCT('gap' AS observable, 'flexbox-gap,grid' AS feature_ids), 35 STRUCT('row-gap' AS observable, 'flexbox-gap,grid' AS feature_ids), 36 STRUCT('appearance' AS observable, 'appearance,customizable-select' AS feature_ids), 37 STRUCT('background-clip' AS observable, 'background-clip-text' AS feature_ids), 38 STRUCT('clip-path' AS observable, 'clip-path,clip-path-boxes' AS feature_ids), 39 STRUCT('grid' AS observable, 'grid' AS feature_ids), 40 STRUCT('grid-area' AS observable, 'grid' AS feature_ids), 41 STRUCT('grid-auto-columns' AS observable, 'grid' AS feature_ids), 42 STRUCT('grid-auto-flow' AS observable, 'grid' AS feature_ids), 43 STRUCT('grid-auto-rows' AS observable, 'grid' AS feature_ids), 44 STRUCT('grid-column' AS observable, 'grid' AS feature_ids), 45 STRUCT('grid-column-end' AS observable, 'grid' AS feature_ids), 46 STRUCT('grid-column-start' AS observable, 'grid' AS feature_ids), 47 STRUCT('grid-row' AS observable, 'grid' AS feature_ids), 48 STRUCT('grid-row-end' AS observable, 'grid' AS feature_ids), 49 STRUCT('grid-row-start' AS observable, 'grid' AS feature_ids), 50 STRUCT('grid-template' AS observable, 'grid' AS feature_ids), 51 STRUCT('grid-template-areas' AS observable, 'grid' AS feature_ids), 52 STRUCT('grid-template-columns' AS observable, 'grid,subgrid' AS feature_ids), 53 STRUCT('grid-template-rows' AS observable, 'grid,subgrid' AS feature_ids), 54 STRUCT('justify-self' AS observable, 'grid,anchor-positioning' AS feature_ids), 55 STRUCT('scrollbar-width' AS observable, 'scrollbar-width' AS feature_ids), 56 STRUCT('will-change' AS observable, 'will-change' AS feature_ids), 57 STRUCT('text-indent' AS observable, 'text-indent' AS feature_ids), 58 STRUCT('mask' AS observable, 'masks' AS feature_ids), 59 STRUCT('mask-clip' AS observable, 'masks' AS feature_ids), 60 STRUCT('mask-composite' AS observable, 'masks' AS feature_ids), 61 STRUCT('mask-image' AS observable, 'masks' AS feature_ids), 62 STRUCT('mask-mode' AS observable, 'masks' AS feature_ids), 63 STRUCT('mask-origin' AS observable, 'masks' AS feature_ids), 64 STRUCT('mask-position' AS observable, 'masks' AS feature_ids), 65 STRUCT('mask-repeat' AS observable, 'masks' AS feature_ids), 66 STRUCT('mask-size' AS observable, 'masks' AS feature_ids), 67 STRUCT('block-size' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 68 STRUCT('border-block' AS observable, 'logical-properties' AS feature_ids), 69 STRUCT('border-block-color' AS observable, 'logical-properties' AS feature_ids), 70 STRUCT('border-block-end' AS observable, 'logical-properties' AS feature_ids), 71 STRUCT('border-block-end-color' AS observable, 'logical-properties' AS feature_ids), 72 STRUCT('border-block-end-style' AS observable, 'logical-properties' AS feature_ids), 73 STRUCT('border-block-end-width' AS observable, 'logical-properties' AS feature_ids), 74 STRUCT('border-block-start' AS observable, 'logical-properties' AS feature_ids), 75 STRUCT('border-block-start-color' AS observable, 'logical-properties' AS feature_ids), 76 STRUCT('border-block-start-style' AS observable, 'logical-properties' AS feature_ids), 77 STRUCT('border-block-start-width' AS observable, 'logical-properties' AS feature_ids), 78 STRUCT('border-block-style' AS observable, 'logical-properties' AS feature_ids), 79 STRUCT('border-block-width' AS observable, 'logical-properties' AS feature_ids), 80 STRUCT('border-end-end-radius' AS observable, 'logical-properties' AS feature_ids), 81 STRUCT('border-end-start-radius' AS observable, 'logical-properties' AS feature_ids), 82 STRUCT('border-inline' AS observable, 'logical-properties' AS feature_ids), 83 STRUCT('border-inline-color' AS observable, 'logical-properties' AS feature_ids), 84 STRUCT('border-inline-end' AS observable, 'logical-properties' AS feature_ids), 85 STRUCT('border-inline-end-color' AS observable, 'logical-properties' AS feature_ids), 86 STRUCT('border-inline-end-style' AS observable, 'logical-properties' AS feature_ids), 87 STRUCT('border-inline-end-width' AS observable, 'logical-properties' AS feature_ids), 88 STRUCT('border-inline-start' AS observable, 'logical-properties' AS feature_ids), 89 STRUCT('border-inline-start-color' AS observable, 'logical-properties' AS feature_ids), 90 STRUCT('border-inline-start-style' AS observable, 'logical-properties' AS feature_ids), 91 STRUCT('border-inline-start-width' AS observable, 'logical-properties' AS feature_ids), 92 STRUCT('border-inline-style' AS observable, 'logical-properties' AS feature_ids), 93 STRUCT('border-inline-width' AS observable, 'logical-properties' AS feature_ids), 94 STRUCT('border-start-end-radius' AS observable, 'logical-properties' AS feature_ids), 95 STRUCT('border-start-start-radius' AS observable, 'logical-properties' AS feature_ids), 96 STRUCT('clear' AS observable, 'logical-properties' AS feature_ids), 97 STRUCT('float' AS observable, 'logical-properties' AS feature_ids), 98 STRUCT('inline-size' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 99 STRUCT('inset' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 100 STRUCT('inset-block' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 101 STRUCT('inset-block-end' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 102 STRUCT('inset-block-start' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 103 STRUCT('inset-inline' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 104 STRUCT('inset-inline-end' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 105 STRUCT('inset-inline-start' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 106 STRUCT('margin-block' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 107 STRUCT('margin-block-end' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 108 STRUCT('margin-block-start' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 109 STRUCT('margin-inline' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 110 STRUCT('margin-inline-end' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 111 STRUCT('margin-inline-start' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 112 STRUCT('max-block-size' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 113 STRUCT('max-inline-size' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 114 STRUCT('min-block-size' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 115 STRUCT('min-inline-size' AS observable, 'logical-properties,anchor-positioning' AS feature_ids), 116 STRUCT('overflow-block' AS observable, 'logical-properties' AS feature_ids), 117 STRUCT('overflow-inline' AS observable, 'logical-properties' AS feature_ids), 118 STRUCT('padding-block' AS observable, 'logical-properties' AS feature_ids), 119 STRUCT('padding-block-end' AS observable, 'logical-properties' AS feature_ids), 120 STRUCT('padding-block-start' AS observable, 'logical-properties' AS feature_ids), 121 STRUCT('padding-inline' AS observable, 'logical-properties' AS feature_ids), 122 STRUCT('padding-inline-end' AS observable, 'logical-properties' AS feature_ids), 123 STRUCT('padding-inline-start' AS observable, 'logical-properties' AS feature_ids), 124 STRUCT('forced-color-adjust' AS observable, 'forced-colors' AS feature_ids), 125 STRUCT('aspect-ratio' AS observable, 'aspect-ratio' AS feature_ids), 126 STRUCT('backdrop-filter' AS observable, 'backdrop-filter' AS feature_ids), 127 STRUCT('text-wrap' AS observable, 'text-wrap,text-wrap-balance,text-wrap-pretty' AS feature_ids), 128 STRUCT('overflow-x' AS observable, 'overflow-clip,overflow-shorthand' AS feature_ids), 129 STRUCT('overflow-y' AS observable, 'overflow-clip,overflow-shorthand' AS feature_ids), 130 STRUCT('overflow' AS observable, 'overflow-clip,overflow-shorthand' AS feature_ids), 131 STRUCT('color-scheme' AS observable, 'color-scheme' AS feature_ids), 132 STRUCT('rotate' AS observable, 'individual-transforms' AS feature_ids), 133 STRUCT('scale' AS observable, 'individual-transforms' AS feature_ids), 134 STRUCT('translate' AS observable, 'individual-transforms' AS feature_ids), 135 STRUCT('scrollbar-color' AS observable, 'scrollbar-color' AS feature_ids), 136 STRUCT('text-underline-offset' AS observable, 'text-underline-offset' AS feature_ids), 137 STRUCT('scroll-margin' AS observable, 'scroll-snap' AS feature_ids), 138 STRUCT('scroll-margin-block' AS observable, 'scroll-snap' AS feature_ids), 139 STRUCT('scroll-margin-block-end' AS observable, 'scroll-snap' AS feature_ids), 140 STRUCT('scroll-margin-block-start' AS observable, 'scroll-snap' AS feature_ids), 141 STRUCT('scroll-margin-bottom' AS observable, 'scroll-snap' AS feature_ids), 142 STRUCT('scroll-margin-inline' AS observable, 'scroll-snap' AS feature_ids), 143 STRUCT('scroll-margin-inline-end' AS observable, 'scroll-snap' AS feature_ids), 144 STRUCT('scroll-margin-inline-start' AS observable, 'scroll-snap' AS feature_ids), 145 STRUCT('scroll-margin-left' AS observable, 'scroll-snap' AS feature_ids), 146 STRUCT('scroll-margin-right' AS observable, 'scroll-snap' AS feature_ids), 147 STRUCT('scroll-margin-top' AS observable, 'scroll-snap' AS feature_ids), 148 STRUCT('scroll-padding' AS observable, 'scroll-snap' AS feature_ids), 149 STRUCT('scroll-padding-block' AS observable, 'scroll-snap' AS feature_ids), 150 STRUCT('scroll-padding-block-end' AS observable, 'scroll-snap' AS feature_ids), 151 STRUCT('scroll-padding-block-start' AS observable, 'scroll-snap' AS feature_ids), 152 STRUCT('scroll-padding-bottom' AS observable, 'scroll-snap' AS feature_ids), 153 STRUCT('scroll-padding-inline' AS observable, 'scroll-snap' AS feature_ids), 154 STRUCT('scroll-padding-inline-end' AS observable, 'scroll-snap' AS feature_ids), 155 STRUCT('scroll-padding-inline-start' AS observable, 'scroll-snap' AS feature_ids), 156 STRUCT('scroll-padding-left' AS observable, 'scroll-snap' AS feature_ids), 157 STRUCT('scroll-padding-right' AS observable, 'scroll-snap' AS feature_ids), 158 STRUCT('scroll-padding-top' AS observable, 'scroll-snap' AS feature_ids), 159 STRUCT('scroll-snap-align' AS observable, 'scroll-snap' AS feature_ids), 160 STRUCT('scroll-snap-stop' AS observable, 'scroll-snap' AS feature_ids), 161 STRUCT('scroll-snap-type' AS observable, 'scroll-snap' AS feature_ids), 162 STRUCT('container' AS observable, 'container-queries' AS feature_ids), 163 STRUCT('container-name' AS observable, 'container-queries' AS feature_ids), 164 STRUCT('container-type' AS observable, 'container-queries,container-scroll-state-queries' AS feature_ids), 165 STRUCT('scrollbar-gutter' AS observable, 'scrollbar-gutter' AS feature_ids), 166 STRUCT('hyphens' AS observable, 'hyphens' AS feature_ids), 167 STRUCT('quotes' AS observable, 'quotes' AS feature_ids), 168 STRUCT('content-visibility' AS observable, 'content-visibility,display-animation' AS feature_ids), 169 STRUCT('contain-intrinsic-block-size' AS observable, 'contain-intrinsic-size' AS feature_ids), 170 STRUCT('contain-intrinsic-height' AS observable, 'contain-intrinsic-size' AS feature_ids), 171 STRUCT('contain-intrinsic-inline-size' AS observable, 'contain-intrinsic-size' AS feature_ids), 172 STRUCT('contain-intrinsic-size' AS observable, 'contain-intrinsic-size' AS feature_ids), 173 STRUCT('contain-intrinsic-width' AS observable, 'contain-intrinsic-size' AS feature_ids), 174 STRUCT('border-image' AS observable, 'border-image' AS feature_ids), 175 STRUCT('border-image-outset' AS observable, 'border-image' AS feature_ids), 176 STRUCT('border-image-repeat' AS observable, 'border-image' AS feature_ids), 177 STRUCT('border-image-slice' AS observable, 'border-image' AS feature_ids), 178 STRUCT('border-image-source' AS observable, 'border-image' AS feature_ids), 179 STRUCT('border-image-width' AS observable, 'border-image' AS feature_ids), 180 STRUCT('line-break' AS observable, 'line-break' AS feature_ids), 181 STRUCT('transform-box' AS observable, 'transform-box' AS feature_ids), 182 STRUCT('animation-range' AS observable, 'scroll-driven-animations' AS feature_ids), 183 STRUCT('animation-range-end' AS observable, 'scroll-driven-animations' AS feature_ids), 184 STRUCT('animation-range-start' AS observable, 'scroll-driven-animations' AS feature_ids), 185 STRUCT('animation-timeline' AS observable, 'scroll-driven-animations' AS feature_ids), 186 STRUCT('animation' AS observable, 'scroll-driven-animations' AS feature_ids), 187 STRUCT('scroll-timeline' AS observable, 'scroll-driven-animations' AS feature_ids), 188 STRUCT('scroll-timeline-axis' AS observable, 'scroll-driven-animations' AS feature_ids), 189 STRUCT('scroll-timeline-name' AS observable, 'scroll-driven-animations' AS feature_ids), 190 STRUCT('timeline-scope' AS observable, 'scroll-driven-animations' AS feature_ids), 191 STRUCT('view-timeline' AS observable, 'scroll-driven-animations' AS feature_ids), 192 STRUCT('view-timeline-axis' AS observable, 'scroll-driven-animations' AS feature_ids), 193 STRUCT('view-timeline-inset' AS observable, 'scroll-driven-animations' AS feature_ids), 194 STRUCT('view-timeline-name' AS observable, 'scroll-driven-animations' AS feature_ids), 195 STRUCT('interpolate-size' AS observable, 'interpolate-size' AS feature_ids), 196 STRUCT('print-color-adjust' AS observable, 'print-color-adjust' AS feature_ids), 197 STRUCT('box-decoration-break' AS observable, 'box-decoration-break' AS feature_ids), 198 STRUCT('accent-color' AS observable, 'accent-color' AS feature_ids), 199 STRUCT('font-optical-sizing' AS observable, 'font-optical-sizing' AS feature_ids), 200 STRUCT('text-spacing-trim' AS observable, 'text-spacing-trim' AS feature_ids), 201 STRUCT('font-size-adjust' AS observable, 'font-size-adjust' AS feature_ids), 202 STRUCT('font-synthesis' AS observable, 'font-synthesis' AS feature_ids), 203 STRUCT('field-sizing' AS observable, 'field-sizing' AS feature_ids), 204 STRUCT('paint-order' AS observable, 'paint-order' AS feature_ids), 205 STRUCT('font-size' AS observable, 'mathml' AS feature_ids), 206 STRUCT('math-depth' AS observable, 'mathml' AS feature_ids), 207 STRUCT('math-shift' AS observable, 'mathml' AS feature_ids), 208 STRUCT('math-style' AS observable, 'mathml' AS feature_ids), 209 STRUCT('text-transform' AS observable, 'mathml' AS feature_ids), 210 STRUCT('text-box' AS observable, 'text-box' AS feature_ids), 211 STRUCT('text-box-edge' AS observable, 'text-box' AS feature_ids), 212 STRUCT('text-box-trim' AS observable, 'text-box' AS feature_ids), 213 STRUCT('white-space-collapse' AS observable, 'white-space-collapse' AS feature_ids), 214 STRUCT('transition-behavior' AS observable, 'transition-behavior' AS feature_ids), 215 STRUCT('transition' AS observable, 'transition-behavior' AS feature_ids), 216 STRUCT('view-transition-name' AS observable, 'view-transitions' AS feature_ids), 217 STRUCT('counter-set' AS observable, 'counter-set' AS feature_ids), 218 STRUCT('font-language-override' AS observable, 'font-language-override' AS feature_ids), 219 STRUCT('background-image' AS observable, 'image-set' AS feature_ids), 220 STRUCT('content' AS observable, 'image-set' AS feature_ids), 221 STRUCT('offset' AS observable, 'motion-path' AS feature_ids), 222 STRUCT('offset-anchor' AS observable, 'motion-path' AS feature_ids), 223 STRUCT('offset-distance' AS observable, 'motion-path' AS feature_ids), 224 STRUCT('offset-path' AS observable, 'motion-path' AS feature_ids), 225 STRUCT('offset-position' AS observable, 'motion-path' AS feature_ids), 226 STRUCT('offset-rotate' AS observable, 'motion-path' AS feature_ids), 227 STRUCT('animation-composition' AS observable, 'animation-composition' AS feature_ids), 228 STRUCT('anchor-name' AS observable, 'anchor-positioning' AS feature_ids), 229 STRUCT('anchor-scope' AS observable, 'anchor-positioning' AS feature_ids), 230 STRUCT('bottom' AS observable, 'anchor-positioning' AS feature_ids), 231 STRUCT('height' AS observable, 'anchor-positioning' AS feature_ids), 232 STRUCT('left' AS observable, 'anchor-positioning' AS feature_ids), 233 STRUCT('margin-bottom' AS observable, 'anchor-positioning' AS feature_ids), 234 STRUCT('margin-left' AS observable, 'anchor-positioning' AS feature_ids), 235 STRUCT('margin-right' AS observable, 'anchor-positioning' AS feature_ids), 236 STRUCT('margin-top' AS observable, 'anchor-positioning' AS feature_ids), 237 STRUCT('margin' AS observable, 'anchor-positioning' AS feature_ids), 238 STRUCT('max-height' AS observable, 'anchor-positioning' AS feature_ids), 239 STRUCT('max-width' AS observable, 'anchor-positioning' AS feature_ids), 240 STRUCT('min-height' AS observable, 'anchor-positioning' AS feature_ids), 241 STRUCT('min-width' AS observable, 'anchor-positioning' AS feature_ids), 242 STRUCT('position-anchor' AS observable, 'anchor-positioning' AS feature_ids), 243 STRUCT('position-area' AS observable, 'anchor-positioning' AS feature_ids), 244 STRUCT('position-try' AS observable, 'anchor-positioning' AS feature_ids), 245 STRUCT('position-try-fallbacks' AS observable, 'anchor-positioning' AS feature_ids), 246 STRUCT('position-try-order' AS observable, 'anchor-positioning' AS feature_ids), 247 STRUCT('position-visibility' AS observable, 'anchor-positioning' AS feature_ids), 248 STRUCT('right' AS observable, 'anchor-positioning' AS feature_ids), 249 STRUCT('top' AS observable, 'anchor-positioning' AS feature_ids), 250 STRUCT('width' AS observable, 'anchor-positioning' AS feature_ids), 251 STRUCT('font-variant-alternates' AS observable, 'font-variant-alternates' AS feature_ids), 252 STRUCT('text-justify' AS observable, 'text-justify' AS feature_ids), 253 STRUCT('hyphenate-character' AS observable, 'hyphenate-character' AS feature_ids), 254 STRUCT('font-variant-position' AS observable, 'font-variant-position' AS feature_ids), 255 STRUCT('text-emphasis' AS observable, 'text-emphasis' AS feature_ids), 256 STRUCT('text-emphasis-color' AS observable, 'text-emphasis' AS feature_ids), 257 STRUCT('text-emphasis-position' AS observable, 'text-emphasis' AS feature_ids), 258 STRUCT('text-emphasis-style' AS observable, 'text-emphasis' AS feature_ids), 259 STRUCT('image-orientation' AS observable, 'image-orientation' AS feature_ids), 260 STRUCT('ruby-position' AS observable, 'ruby-position' AS feature_ids), 261 STRUCT('ruby-align' AS observable, 'ruby-align' AS feature_ids), 262 STRUCT('hyphenate-limit-chars' AS observable, 'hyphenate-limit-chars' AS feature_ids), 263 STRUCT('font-synthesis-weight' AS observable, 'font-synthesis-weight' AS feature_ids), 264 STRUCT('text-wrap-style' AS observable, 'text-wrap-style' AS feature_ids), 265 STRUCT('initial-letter' AS observable, 'initial-letter' AS feature_ids), 266 STRUCT('view-transition-class' AS observable, 'view-transition-class' AS feature_ids), 267 STRUCT('font-variant-emoji' AS observable, 'font-variant-emoji' AS feature_ids), 268 STRUCT('font-palette' AS observable, 'font-palette,font-palette-animation' AS feature_ids), 269 STRUCT('font-family' AS observable, 'font-family-math' AS feature_ids), 270 STRUCT('scroll-marker-group' AS observable, 'scroll-markers' AS feature_ids), 271 STRUCT('word-break' AS observable, 'word-break-auto-phrase' AS feature_ids), 272 STRUCT('overlay' AS observable, 'overlay' AS feature_ids), 273 STRUCT('object-view-box' AS observable, 'object-view-box' AS feature_ids), 274 STRUCT('contain' AS observable, 'contain-inline-size' AS feature_ids), 275 STRUCT('reading-flow' AS observable, 'reading-flow' AS feature_ids), 276 STRUCT('reading-order' AS observable, 'reading-flow' AS feature_ids), 277 STRUCT('font-synthesis-style' AS observable, 'font-synthesis-style' AS feature_ids), 278 STRUCT('direction' AS observable, 'vertical-form-controls' AS feature_ids), 279 STRUCT('writing-mode' AS observable, 'vertical-form-controls' AS feature_ids), 280 STRUCT('interactivity' AS observable, 'interactivity' AS feature_ids), 281 STRUCT('baseline-source' AS observable, 'baseline-source' AS feature_ids), 282 STRUCT('scroll-initial-target' AS observable, 'scroll-initial-target' AS feature_ids), 283 STRUCT('font-synthesis-small-caps' AS observable, 'font-synthesis-small-caps' AS feature_ids) 284 ]) 285), 286 287css_selector_lookup AS ( 288 SELECT * FROM UNNEST([ 289 STRUCT('not' AS observable, 'not' AS feature_ids, ':not' AS search_pattern), 290 STRUCT('slotted' AS observable, 'slot' AS feature_ids, '::slotted' AS search_pattern), 291 STRUCT('focus-visible' AS observable, 'focus-visible' AS feature_ids, ':focus-visible' AS search_pattern), 292 STRUCT('has' AS observable, 'has' AS feature_ids, ':has' AS search_pattern), 293 STRUCT('where' AS observable, 'where' AS feature_ids, ':where' AS search_pattern), 294 STRUCT('is' AS observable, 'is' AS feature_ids, ':is' AS search_pattern), 295 STRUCT('marker' AS observable, 'marker' AS feature_ids, '::marker' AS search_pattern), 296 STRUCT('nesting' AS observable, 'nesting' AS feature_ids, '&' AS search_pattern), 297 STRUCT('file-selector-button' AS observable, 'file-selector-button' AS feature_ids, '::file-selector-button' AS search_pattern), 298 STRUCT('dir' AS observable, 'dir-pseudo' AS feature_ids, ':dir' AS search_pattern), 299 STRUCT('cue' AS observable, 'webvtt' AS feature_ids, '::cue' AS search_pattern), 300 STRUCT('nth-child' AS observable, 'nth-child-of' AS feature_ids, ':nth-child' AS search_pattern), 301 STRUCT('nth-last-child' AS observable, 'nth-child-of' AS feature_ids, ':nth-last-child' AS search_pattern), 302 STRUCT('modal' AS observable, 'modal' AS feature_ids, ':modal' AS search_pattern), 303 STRUCT('autofill' AS observable, 'autofill' AS feature_ids, ':autofill' AS search_pattern), 304 STRUCT('backdrop' AS observable, 'popover' AS feature_ids, '::backdrop' AS search_pattern), 305 STRUCT('popover-open' AS observable, 'popover' AS feature_ids, ':popover-open' AS search_pattern), 306 STRUCT('view-transition' AS observable, 'view-transitions' AS feature_ids, '::view-transition' AS search_pattern), 307 STRUCT('view-transition-group' AS observable, 'view-transitions' AS feature_ids, '::view-transition-group' AS search_pattern), 308 STRUCT('view-transition-image-pair' AS observable, 'view-transitions' AS feature_ids, '::view-transition-image-pair' AS search_pattern), 309 STRUCT('view-transition-new' AS observable, 'view-transitions' AS feature_ids, '::view-transition-new' AS search_pattern), 310 STRUCT('view-transition-old' AS observable, 'view-transitions' AS feature_ids, '::view-transition-old' AS search_pattern), 311 STRUCT('grammar-error' AS observable, 'spelling-grammar-error' AS feature_ids, '::grammar-error' AS search_pattern), 312 STRUCT('spelling-error' AS observable, 'spelling-grammar-error' AS feature_ids, '::spelling-error' AS search_pattern), 313 STRUCT('details-content' AS observable, 'details-content' AS feature_ids, '::details-content' AS search_pattern), 314 STRUCT('user-invalid' AS observable, 'user-pseudos' AS feature_ids, ':user-invalid' AS search_pattern), 315 STRUCT('user-valid' AS observable, 'user-pseudos' AS feature_ids, ':user-valid' AS search_pattern), 316 STRUCT('future' AS observable, 'time-relative-selectors' AS feature_ids, ':future' AS search_pattern), 317 STRUCT('past' AS observable, 'time-relative-selectors' AS feature_ids, ':past' AS search_pattern), 318 STRUCT('state' AS observable, 'state' AS feature_ids, ':state' AS search_pattern), 319 STRUCT('active-view-transition' AS observable, 'active-view-transition' AS feature_ids, ':active-view-transition' AS search_pattern), 320 STRUCT('active-view-transition-type' AS observable, 'active-view-transition' AS feature_ids, ':active-view-transition-type' AS search_pattern), 321 STRUCT('target-text' AS observable, 'target-text' AS feature_ids, '::target-text' AS search_pattern), 322 STRUCT('highlight' AS observable, 'highlight' AS feature_ids, '::highlight' AS search_pattern), 323 STRUCT('scroll-marker' AS observable, 'scroll-markers' AS feature_ids, '::scroll-marker' AS search_pattern), 324 STRUCT('scroll-marker-group' AS observable, 'scroll-markers' AS feature_ids, '::scroll-marker-group' AS search_pattern), 325 STRUCT('picture-in-picture' AS observable, 'picture-in-picture' AS feature_ids, ':picture-in-picture' AS search_pattern), 326 STRUCT('checkmark' AS observable, 'customizable-select' AS feature_ids, '::checkmark' AS search_pattern), 327 STRUCT('picker' AS observable, 'customizable-select' AS feature_ids, '::picker' AS search_pattern), 328 STRUCT('picker-icon' AS observable, 'customizable-select' AS feature_ids, '::picker-icon' AS search_pattern), 329 STRUCT('scroll-button' AS observable, 'scroll-buttons' AS feature_ids, '::scroll-button' AS search_pattern), 330 STRUCT('xr-overlay' AS observable, 'webxr-dom-overlays' AS feature_ids, ':xr-overlay' AS search_pattern), 331 STRUCT('column' AS observable, 'column-pseudo' AS feature_ids, '::column' AS search_pattern), 332 STRUCT('has-slotted' AS observable, 'has-slotted' AS feature_ids, ':has-slotted' AS search_pattern), 333 STRUCT('selection' AS observable, 'text-decoration-selection' AS feature_ids, '::selection' AS search_pattern) 334 ]) 335), 336 337css_atrule_lookup AS ( 338 SELECT * FROM UNNEST([ 339 STRUCT('media' AS observable, 'forced-colors,prefers-contrast,display-mode,media-query-range-syntax,dynamic-range,prefers-reduced-transparency,device-posture,update,scripting,overflow' AS feature_ids), 340 STRUCT('container' AS observable, 'container-queries,container-style-queries,container-scroll-state-queries' AS feature_ids), 341 STRUCT('view-transition' AS observable, 'cross-document-view-transitions' AS feature_ids), 342 STRUCT('font-face' AS observable, 'font-metric-overrides,font-size-adjust' AS feature_ids), 343 STRUCT('property' AS observable, 'registered-custom-properties' AS feature_ids), 344 STRUCT('import' AS observable, 'cascade-layers' AS feature_ids), 345 STRUCT('layer' AS observable, 'cascade-layers' AS feature_ids), 346 STRUCT('starting-style' AS observable, 'starting-style' AS feature_ids), 347 STRUCT('page' AS observable, 'page-orientation' AS feature_ids), 348 STRUCT('position-try' AS observable, 'anchor-positioning' AS feature_ids), 349 STRUCT('font-feature-values' AS observable, 'font-variant-alternates' AS feature_ids), 350 STRUCT('counter-style' AS observable, 'counter-style' AS feature_ids), 351 STRUCT('scope' AS observable, 'scope' AS feature_ids), 352 STRUCT('font-palette-values' AS observable, 'font-palette' AS feature_ids) 353 ]) 354), 355 356html_element_lookup AS ( 357 SELECT * FROM UNNEST([ 358 STRUCT('slot' AS observable, 'slot' AS feature_ids), 359 STRUCT('canvas' AS observable, 'canvas' AS feature_ids), 360 STRUCT('a' AS observable, 'referrer-policy,attribution-reporting,fencedframe,scroll-to-text-fragment' AS feature_ids), 361 STRUCT('area' AS observable, 'referrer-policy,attribution-reporting' AS feature_ids), 362 STRUCT('iframe' AS observable, 'referrer-policy,attribution-reporting,storage-access,screen-wake-lock,compute-pressure,accelerometer,window-management,iframe-credentialless,idle-detection,web-otp,picture-in-picture,web-midi,webusb,serial,webhid,local-fonts,gamepad,web-bluetooth' AS feature_ids), 363 STRUCT('img' AS observable, 'referrer-policy,fetch-priority,aspect-ratio,attribution-reporting,sizes-auto' AS feature_ids), 364 STRUCT('link' AS observable, 'referrer-policy,fetch-priority,manifest,blocking-render,link-rel-expect,compression-dictionary-transport' AS feature_ids), 365 STRUCT('script' AS observable, 'referrer-policy,fetch-priority,js-modules,attribution-reporting,speculation-rules,blocking-render,import-maps' AS feature_ids), 366 STRUCT('video' AS observable, 'aspect-ratio,remote-playback,picture-in-picture' AS feature_ids), 367 STRUCT('template' AS observable, 'template,declarative-shadow-dom' AS feature_ids), 368 STRUCT('meta' AS observable, 'color-scheme,meta-application-title' AS feature_ids), 369 STRUCT('style' AS observable, 'blocking-render' AS feature_ids), 370 STRUCT('dialog' AS observable, 'dialog,dialog-closedby' AS feature_ids), 371 STRUCT('button' AS observable, 'popover,anchor-positioning' AS feature_ids), 372 STRUCT('input' AS observable, 'popover,anchor-positioning' AS feature_ids), 373 STRUCT('datalist' AS observable, 'datalist' AS feature_ids), 374 STRUCT('fencedframe' AS observable, 'fencedframe' AS feature_ids), 375 STRUCT('audio' AS observable, 'remote-playback' AS feature_ids), 376 STRUCT('search' AS observable, 'search' AS feature_ids), 377 STRUCT('details' AS observable, 'details-name' AS feature_ids), 378 STRUCT('selectedcontent' AS observable, 'customizable-select' AS feature_ids) 379 ]) 380), 381 382-- ============================================================================= 383-- SINGLE SCAN of parsed_css: extract properties, selector blocks, and at-rule types 384-- Converts the css JSON column to a string ONCE per row, then extracts all three 385-- categories in a single pass over the table. 386-- ============================================================================= 387css_raw AS ( 388 SELECT 389 page, 390 TO_JSON_STRING(css) AS css_str 391 FROM `httparchive.crawl.parsed_css` 392 WHERE date = crawl_date 393 AND client = 'desktop' 394 AND is_root_page = TRUE 395), 396 397-- Extract distinct CSS properties per page 398page_css_properties AS ( 399 SELECT page, prop 400 FROM css_raw, UNNEST(REGEXP_EXTRACT_ALL(css_str, r'"property":"([^"]+)"')) AS prop 401 GROUP BY page, prop 402), 403 404-- Extract selector blocks per page (the content inside "selectors":[...]) 405-- Each sel_block is a string like '"h1","h2",".foo:not(.bar)"' 406page_css_selectors AS ( 407 SELECT page, sel_block 408 FROM css_raw, UNNEST(REGEXP_EXTRACT_ALL(css_str, r'"selectors":\[([^\]]+)\]')) AS sel_block 409 GROUP BY page, sel_block 410), 411 412-- Extract distinct at-rule types per page 413page_css_atrules AS ( 414 SELECT page, atrule 415 FROM css_raw, UNNEST(REGEXP_EXTRACT_ALL(css_str, r'"type":"([^"]+)"')) AS atrule 416 GROUP BY page, atrule 417), 418 419-- ============================================================================= 420-- CSS PROPERTY RESULTS: join extracted properties with lookup 421-- ============================================================================= 422css_property_results AS ( 423 SELECT 424 lk.feature_ids, 425 lk.observable, 426 'css_property' AS type, 427 COUNT(DISTINCT pcp.page) AS pages_using 428 FROM css_property_lookup lk 429 LEFT JOIN page_css_properties pcp ON pcp.prop = lk.observable 430 GROUP BY lk.feature_ids, lk.observable 431), 432 433-- ============================================================================= 434-- CSS SELECTOR RESULTS: search selector blocks for patterns 435-- For each page, check if any selector block contains the search pattern 436-- ============================================================================= 437css_selector_results AS ( 438 SELECT 439 lk.feature_ids, 440 lk.observable, 441 'css_selector' AS type, 442 COUNT(DISTINCT pcs.page) AS pages_using 443 FROM css_selector_lookup lk 444 LEFT JOIN page_css_selectors pcs 445 ON pcs.sel_block LIKE CONCAT('%', lk.search_pattern, '%') 446 GROUP BY lk.feature_ids, lk.observable 447), 448 449-- ============================================================================= 450-- CSS AT-RULE RESULTS: join extracted at-rule types with lookup 451-- ============================================================================= 452css_atrule_results AS ( 453 SELECT 454 lk.feature_ids, 455 lk.observable, 456 'css_atrule' AS type, 457 COUNT(DISTINCT pca.page) AS pages_using 458 FROM css_atrule_lookup lk 459 LEFT JOIN page_css_atrules pca ON pca.atrule = lk.observable 460 GROUP BY lk.feature_ids, lk.observable 461), 462 463-- ============================================================================= 464-- HTML ELEMENTS: extract from custom_metrics.element_count in pages table 465-- element_count is a JSON object like {"div": 500, "span": 200, "dialog": 1} 466-- ============================================================================= 467page_html_elements AS ( 468 SELECT 469 page, 470 LOWER(elem_name) AS elem_name 471 FROM 472 `httparchive.crawl.pages`, 473 UNNEST( 474 REGEXP_EXTRACT_ALL( 475 TO_JSON_STRING(custom_metrics.element_count), 476 r'"([^"]+)"\s*:' 477 ) 478 ) AS elem_name 479 WHERE date = crawl_date 480 AND client = 'desktop' 481 AND is_root_page = TRUE 482 GROUP BY page, elem_name 483), 484 485html_element_results AS ( 486 SELECT 487 lk.feature_ids, 488 lk.observable, 489 'html_element' AS type, 490 COUNT(DISTINCT phe.page) AS pages_using 491 FROM html_element_lookup lk 492 LEFT JOIN page_html_elements phe ON phe.elem_name = lk.observable 493 GROUP BY lk.feature_ids, lk.observable 494), 495 496-- ============================================================================= 497-- TOTAL PAGES: for computing percentages 498-- ============================================================================= 499total_css_pages AS ( 500 SELECT COUNT(DISTINCT page) AS total_pages 501 FROM `httparchive.crawl.parsed_css` 502 WHERE date = crawl_date 503 AND client = 'desktop' 504 AND is_root_page = TRUE 505), 506 507total_html_pages AS ( 508 SELECT COUNT(DISTINCT page) AS total_pages 509 FROM `httparchive.crawl.pages` 510 WHERE date = crawl_date 511 AND client = 'desktop' 512 AND is_root_page = TRUE 513), 514 515-- ============================================================================= 516-- COMBINE all results 517-- ============================================================================= 518all_results AS ( 519 SELECT feature_ids, observable, type, pages_using FROM css_property_results 520 UNION ALL 521 SELECT feature_ids, observable, type, pages_using FROM css_selector_results 522 UNION ALL 523 SELECT feature_ids, observable, type, pages_using FROM css_atrule_results 524 UNION ALL 525 SELECT feature_ids, observable, type, pages_using FROM html_element_results 526) 527 528SELECT 529 r.feature_ids, 530 r.observable, 531 r.type, 532 r.pages_using, 533 CASE 534 WHEN r.type = 'html_element' THEN th.total_pages 535 ELSE tc.total_pages 536 END AS total_pages, 537 SAFE_DIVIDE(r.pages_using * 100.0, 538 CASE 539 WHEN r.type = 'html_element' THEN th.total_pages 540 ELSE tc.total_pages 541 END 542 ) AS pct 543FROM all_results r 544CROSS JOIN total_css_pages tc 545CROSS JOIN total_html_pages th 546ORDER BY pct DESC;