Picture element display values

Recently there is a question, from a standards and implementation perspective about how often the display value is set by authors for the picture element because of interest in changing something, for example, in a UA default stylesheet and what the practical impact on websites would be: do people actually set these on picture elements? Having some kind of insight into this would be very helpful.

This isn’t a new or infrequent sort of ask so while we’re looking for an answer to this question today, it would be helpful if we could frame this as a somewhat generic problemset: how many sites do these tag selectors appear in with these properties/values?

An index, created similar to the one we made recently for markup for tag names would actually be helpful here, perhaps, ultimately… but we’d need to also figure out what to collect here… just display values seems big enough to be a worthwhile breakdown as it affects a lot.

1 Like

There is a proposal to change the UA stylesheet to include picture { display: contents; }. What we don’t know is whether doing so is web compatible.

If a page does set display explicitly, then there’s no difference from today. So we don’t need to query for which display values people use. (It can be interesting, but doesn’t answer “is it web compatible?”.)

Instead, we need to look for pages that would have different rendering with the UA change:

  • does NOT set display explicitly, and:
  • at least one of:
    • float
    • position
    • is a flex item (style on parent!)
    • is a grid item (style on parent!)
    • any other property that affects rendering for a non-replaced inline (many properties!)

A completely different approach could be to collect screenshots with and without the UA style, with cluster telemetry or so, but, a query in httparchive is probably simpler and faster.

1 Like

These would be hard to impossible to implement using only BigQuery. For truly accurate results I think we’d need a custom metric.

For starters I wrote a query to count the number of pages that include a stylesheet that selects picture elements:

#standardSQL
CREATE TEMPORARY FUNCTION stylesPicture(css STRING)
RETURNS BOOLEAN LANGUAGE js AS '''
try {
  function selectsThePictureElement(selectors) {
    return !!selectors.find(selector => {
      return selector.split(' ').reverse()[0].toLowerCase().startsWith('picture');
    });
  }

  var reduceValues = (values, rule) => {
    if ('rules' in rule) {
      return rule.rules.reduce(reduceValues, values);
    }
    if (!('declarations' in rule)) {
      return values;
    }
    
    return values || selectsThePictureElement(rule.selectors);
  };
  var $ = JSON.parse(css);
  return $.stylesheet.rules.reduce(reduceValues, false);
} catch (e) {
  return false;
}
''';

SELECT
  client,
  COUNTIF(num_stylesheets > 0) AS freq,
  total,
  ROUND(COUNTIF(num_stylesheets > 0) * 100 / total, 2) AS pct
FROM (
  SELECT
    client,
    page,
    COUNTIF(stylesPicture(css)) AS num_stylesheets
  FROM
    `httparchive.almanac.parsed_css`
  GROUP BY
    client,
    page)
JOIN
  (SELECT _TABLE_SUFFIX AS client, COUNT(0) AS total FROM `httparchive.summary_pages.2019_07_01_*` GROUP BY client)
USING
  (client)
GROUP BY
  client,
  total
client freq total pct
desktop 21042 4371973 0.48
mobile 23754 5297442 0.45

~20K pages.

I can refine the query to account for these particular conditions if needed:

Can we just include the value as well and group by as a secondary? It seems this would give you most of what you need and be basically the pattern I described if we could just pattern the selectors

I queried the httparchive.almanac.parsed_css table (7,499,763 sites), looking for rules including a selector picture and excluding rules with a display declaration.

15,900 results, from 14,718 pages, i.e. 0.19% of pages.

Full results: bq-results-20220218-133704-r89xgipo6zsc - Google Sheets

I see some stuff like float: left, background: #333, padding: 8px, position: relative, etc., which seems like they would break if we switched to display: contents.

My conclusion is that the breakage would be non-zero and on the order of 0.1% of pages, which doesn’t seem worth it for this change. Also, since authors have gone ahead and styled picture in ways that assume it generates a box, arguably a default of display: contents would be more confusing than helpful in those cases.

Query:

SELECT
  *
FROM (
  SELECT
    page,
    url,
    REGEXP_EXTRACT(css, r'({"type":"rule","selectors":.(?:"[^"]+",)*"picture"(?:,"[^"]+")*.,"declarations":.(?:[^\]]+).})') AS picture_css
  FROM
    `httparchive.almanac.parsed_css`
  WHERE
    date = "2021-07-01"
    AND (client = "mobile"
      OR client = "mobile_10k") )
WHERE
  picture_css IS NOT NULL
  AND NOT REGEXP_CONTAINS(picture_css, r'"property":"display"')

See Consider PICTURE { display: contents; } · Issue #4995 · whatwg/html · GitHub

1 Like

Nice use of parsed_css to answer a web compat question! Thanks for sharing.

I’m always wary of relying on using regex for parsing like this, but since the JSON is well-formatted it seems to have worked well here. The alternative would be to parse the whole object in a JavaScript UDF, similar to the Web Almanac CSS queries, but that takes a lot longer to process.

We plan to eventually make the parsed_css data available in all monthly crawls, rather than only in the annual Web Almanac tables, so if use cases like this come up more frequently we may want to consider maintaining more standardized ways of working with the data. For example, calling a project-level function like GET_DECLARATIONS_FOR_SELECTOR(css, 'picture') to abstract away the parsing.

Another idea, if turnaround time isn’t a factor, would be to augment or add a new custom metric to call getComputedStyle on each picture element and extract a few property values of interest. There are tradeoffs to that approach too, since it would only work for picture elements on the page, but it might be more reliable than parsing the CSS.

In any case, glad you were able to use HTTP Archive data to assist with a standards decision. :tada:

1 Like