{"id":561,"date":"2022-11-23T21:29:21","date_gmt":"2022-11-23T21:29:21","guid":{"rendered":"https:\/\/www-users.tebibyte.io\/~yihanwu1024\/?p=561"},"modified":"2023-12-23T19:21:23","modified_gmt":"2023-12-23T19:21:23","slug":"gutenburg-adaptive-column-layout","status":"publish","type":"post","link":"https:\/\/www.tebibyte.io\/~yihanwu1024\/2022\/gutenburg-adaptive-column-layout\/","title":{"rendered":"Gutenburg Adaptive Column Layout<span style='font-size:75%; display: block;'>How This Site is Stylized<\/span>"},"content":{"rendered":"\n<p>Gutenburg is in many ways a step backwards. For example, you now have to use a hack to implement adaptive column layout, as the framework exposes no way to use a <code>@media<\/code> query or even a custom CSS selector. This hack is also extremely funny and exposes some intriguing design in Gutenburg.<\/p>\n\n\n\n<p>All steps are based on the <code>twentytwentythree<\/code> theme, WordPress 6.1.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hack a JSON in a PHP file<\/h2>\n\n\n\n<p>Open <code>templates\/home.html<\/code> or <code>templates\/index.html<\/code>. Each by default contains a query loop we are interested in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- wp:query {\"query\":{\"perPage\":3,\"pages\":0,\"offset\":0,\"postType\":\"post\",\"order\":\"desc\",\"orderBy\":\"date\",\"author\":\"\",\"search\":\"\",\"exclude\":&#91;],\"sticky\":\"\",\"inherit\":true},\"displayLayout\":{\"type\":\"flex\",\"columns\":3},\"align\":\"wide\",\"layout\":{\"type\":\"constrained\"}} --&gt;<\/code><\/pre>\n\n\n\n<p>Note that the number of <code>columns<\/code>, <code>3<\/code>, is hardcoded in this theme template file. You can change it, but it just generates future pages with that fixed number, not the responsive columns we wanted. It is also extremely interesting to see such a customization JSON hardcoded in PHP.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"404\" height=\"112\" src=\"https:\/\/www-users.tebibyte.io\/~yihanwu1024\/wp-content\/uploads\/2022\/11\/image.png\" alt=\"\" class=\"wp-image-563\" srcset=\"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-content\/uploads\/2022\/11\/image.png 404w, https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-content\/uploads\/2022\/11\/image-300x83.png 300w\" sizes=\"auto, (max-width: 404px) 100vw, 404px\" \/><figcaption class=\"wp-element-caption\">The editor only allows you to set a legitimate number, at least on the front end.<\/figcaption><\/figure>\n\n\n\n<p>So I read <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/WordPress\/gutenberg\/blob\/trunk\/packages\/block-library\/src\/post-template\/index.php\" target=\"_blank\">the source code of the page generator<\/a> (<a href=\"https:\/\/github.com\/WordPress\/gutenberg\/blob\/959c00f6eb78965bd1321443732242503a3db1c5\/packages\/block-library\/src\/post-template\/index.php\" target=\"_blank\" rel=\"noreferrer noopener\">snapshot<\/a>). Below line 65:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$classnames = '';\nif ( isset( $block-&gt;context&#91;'displayLayout'] ) &amp;&amp; isset( $block-&gt;context&#91;'query'] ) ) {\n    if ( isset( $block-&gt;context&#91;'displayLayout']&#91;'type'] ) &amp;&amp; 'flex' === $block-&gt;context&#91;'displayLayout']&#91;'type'] ) {\n        $classnames = \"is-flex-container columns-{$block-&gt;context&#91;'displayLayout']&#91;'columns']}\";\n    }\n}<\/code><\/pre>\n\n\n\n<p>This code appends the value of <code>columns<\/code> to the string <code>\"columns-\"<\/code> to form a CSS class name. The CSS class itself is defined in a non-customizable CSS file in Gutenburg, served to the client directly, in order to manipulate the width of child elements.<\/p>\n\n\n\n<p>It is hilarious to see this code. Type checking is not the major point here, but that it concatenates CSS classes together so the client can render a <em>fixed<\/em> count of columns. For modern web applications, the server never decides any adaptive layout; that is the task of the browser.<\/p>\n\n\n\n<p>In order to apply our own style, we just need to change the <code>columns<\/code> value to <code>\"n\"<\/code> (a string!), and the resulting CSS class name becomes <code>columns-n<\/code>. Then we write a custom CSS file to apply desired styles to the target elements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Custom CSS<\/h2>\n\n\n\n<p>You need to add this globally via <code>\/wp-admin\/customize.php<\/code>.<\/p>\n\n\n\n<p>This defines specifically the <code>columns-n<\/code> class.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@media (min-width: 600px) {\n    .wp-block-post-template.is-flex-container.columns-n&gt;li {\n        width: calc(50% - 0.625em);\n    }\n}\n\n@media (min-width: 800px) {\n    .wp-block-post-template.is-flex-container.columns-n&gt;li {\n        width: calc(33.33333% - 0.83333em);\n    }\n}<\/code><\/pre>\n\n\n\n<p>No attribution is needed for this short snippet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Extra<\/h2>\n\n\n\n<p>I also implemented a CSS <code>@media<\/code> query-based dark theme that responds to the system color scheme. Gutenburg cannot do this by itself; there is no way to delegate a color scheme as the dark one. So I wrote my CSS again.<\/p>\n\n\n\n<p>Changes to the Gutenburg theme variable did not apply to the main menu, because the components specify yet another set of colors. It was ultimately overridden.<\/p>\n\n\n\n<p>The code, although trivial:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@media screen and (prefers-color-scheme: dark) {\n    body {\n        --wp--preset--color--base: #000000;\n        --wp--preset--color--contrast: #ffffff;\n    }\n}\n\n.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open {\n    background-color: var(--wp--preset--color--base);\n    color: var(--wp--preset--color--contrast);\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>You now have to use a hack to implement adaptive column layout, as the framework exposes no way to use a @media query or even a custom CSS selector. This hack is also extremely funny and exposes some intriguing design in Gutenburg.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[7],"class_list":["post-561","post","type-post","status-publish","format-standard","hentry","category-systems-administration","tag-en"],"_links":{"self":[{"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/posts\/561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/comments?post=561"}],"version-history":[{"count":0,"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/posts\/561\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/media?parent=561"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/categories?post=561"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tebibyte.io\/~yihanwu1024\/wp-json\/wp\/v2\/tags?post=561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}