Skip to content

Commit 76c9fd5

Browse files
committed
WIP posts
1 parent 606dfff commit 76c9fd5

File tree

4 files changed

+244
-1
lines changed

4 files changed

+244
-1
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ DEPENDENCIES
6868
jekyll-sitemap
6969

7070
BUNDLED WITH
71-
1.17.2
71+
2.0.2
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
layout: post
3+
title: "Using CSS Grid for Gutenberg Columns"
4+
permalink: "blog/converting-gutenberg-columns-to-use-css-grid"
5+
categories:
6+
- WordPress
7+
comments_id: 12
8+
---
9+
10+
The Gutenberg editor allows you to create columns and each column can have its own width. By default all columns are the same width, but you can define if for example you want the to be 1/3 - 2/3 etc.
11+
12+
## What Gutenberg Generates
13+
14+
The default HTML generated by the WordPress editor looks something like this:
15+
16+
```html
17+
<div class="wp-block-columns">
18+
<div class="wp-block-column" style="flex-basis:33.33%">
19+
<p>Column 1</p>
20+
</div>
21+
22+
<div class="wp-block-column" style="flex-basis:66.66%">
23+
<p>Column 2</p>
24+
</div>
25+
</div>
26+
```
27+
28+
The accompanying styles relevant to what we want to do here:
29+
30+
```css
31+
.wp-block-columns {
32+
display: flex;
33+
}
34+
```
35+
36+
What it does is pretty clever and elegant(ish), but depending on what you're working on it may not always be the best solution. If the theme you're working on has a relatively simple layout then getting things to work properly is a piece of cake. However if you have a more complex layout then `flex` may not be the best choice, and the reason is padding. If columns don't have a padding, then there will not be any space between columns. I've seen themes use padding, margins, for a while I even user this:
37+
38+
```css
39+
.wp-block-column {
40+
border-left: 0.5em solid transparent;
41+
border-right: 0.5em solid transparent;
42+
}
43+
```
44+
The above code will add an extra `0.5em` border on the left and right of your columns, therefore separating them and creating a "gap" between them. The problem however with solutions like that is that they add additional space on the left and right of all columns, therefore making the contents of your columns narrower and they don't line up vertically with the rest of your content. If you can add a left margin on the `.wp-block-columns` element and just make it larger by 1em then you're OK. But what if you can't?
45+
See, `flex` is OK, but in some cases using `grid` makes more sense. For columns the benefit of `grid` is the `css-gap` property.
46+
47+
Unfortunately I haven't found a filter or anything like that that would allow me to change the egenerated markup. We're a bit "trapped" by a limited system.
48+
The only available alternative is to use JS to change things.
49+
50+
Here's some code you can use:
51+
52+
```js
53+
function griddConvertColumnsToGridLayout() {
54+
55+
// Get all column-wrappers.
56+
var griddColumns = document.querySelectorAll( '.wp-block-columns' );
57+
58+
// Loop column-wrappers.
59+
griddColumns.forEach( function( columnsWrapper ) {
60+
var columns = columnsWrapper.childNodes,
61+
gridTemplateCols = [];
62+
63+
// Loop columns.
64+
columns.forEach( function( column ) {
65+
if ( column.style.flexBasis ) {
66+
gridTemplateCols.push( 'minmax(300px, calc(' + column.style.flexBasis + ' - 0.5em))' );
67+
} else {
68+
gridTemplateCols.push( 'minmax(300px, 1fr)' );
69+
}
70+
});
71+
72+
columnsWrapper.style.display = 'grid';
73+
columnsWrapper.style.gridTemplateColumns = gridTemplateCols.join( ' ' );
74+
columnsWrapper.style.gridGap = 'calc(1em';
75+
});
76+
}
77+
griddConvertColumnsToGridLayout();
78+
```
79+
80+
The above snippet ([taken from the currently alpha version of the Gridd 2.0.0 theme](https://github.com/wplemon/gridd/blob/92fb296378481d17afd8a0e430414d4661ae7afb/assets/js/convert-columns-to-grid.js)) is vanilla JS and will convert your columns to use a grid layout.
81+
82+
Of course if you use that you'll also have to take into account mobile visitors and make sure that columns collapse by adding some CSS:
83+
84+
```css
85+
@media screen and (min-width:600px) {
86+
.wp-block-columns {
87+
display: flex; /* block also works fine. */
88+
}
89+
}
90+
```
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
---
2+
layout: post
3+
title: "The Gutenberg Layout Problem"
4+
permalink: "blog/the-gutenberg-layout-problem"
5+
categories:
6+
- WordPress
7+
comments_id: 11
8+
---
9+
10+
The Gutenberg editor is amazing. It allows for flexibility that was previously unheard of without a dedicated page builder. And though everyone kept saying "_Gutenberg is not a page-builder_", I think there's no denying it. **It is a page-builder**. You can call it an immersive editing experience for all I care, but the truth is it's a page-builder.
11+
12+
With all the good things it brought, there were (and still are) some difficulties, mostly regarding the way we can style things - both in the editor and the frontend. This post is about one of the many solutions that you can implement, depending on your layouts.
13+
If your theme doesn't have a sidebar and instead the content is the whole viewport-width, then things are pretty simple. In the [Gridd](https://wplemon.com/gridd) however **there is no standard layout**. Users build their own grid. A site may be just a logo on the top and then the content, or it can have 4 widget-areas on the sides. And therein lies the problem:
14+
How can we account for ALL cases?
15+
16+
## What Gutenberg generates
17+
18+
I created a dummy post with all the cases I could think of at the time, so this is what we'll try to accomplish:
19+
20+
<img src="https://aristath.github.io/assets/article_images/screenshot_2019-10-29-test-post-localhost.png" alt="screenshot of a post written in the WordPress editor using a normal paragraph, a wide element, a full-width element, some dummy content and 2 buttons - one of them floating on the left and a 2nd one floating on the right.">
21+
22+
First of all we have the Gutenberg-generated HTML:
23+
24+
```html
25+
<div class="my-container">
26+
<div class="entry-content container">
27+
<p class="has-background has-very-light-gray-background-color">Normal content.</p>
28+
<div class="wp-block-group alignwide has-very-dark-gray-background-color has-background">
29+
<div class="wp-block-group__inner-container">
30+
<p class="has-text-color has-very-light-gray-color">Wide content.</p>
31+
</div>
32+
</div>
33+
<div class="wp-block-group alignfull has-vivid-red-background-color has-background">
34+
<div class="wp-block-group__inner-container">
35+
<p class="has-text-color has-very-light-gray-color">Full-width content.</p>
36+
</div>
37+
</div>
38+
<div class="wp-block-button alignleft">
39+
<a class="wp-block-button__link">button floating left</a>
40+
</div>
41+
<p>Text next to the button.</p>
42+
<p>Some more content here.</p>
43+
<div class="wp-block-button alignright">
44+
<a class="wp-block-button__link">button floating right</a>
45+
</div>
46+
<p>Some more text</p>
47+
<p>and yet some more to show the button float.</p>
48+
</div>
49+
</div>
50+
```
51+
52+
The wrapping `my-container` element there is just our theme's wrapper for the content.
53+
54+
## Styling
55+
56+
In the code above we can see a lot of classes, most of them color-related. I added them when editing the post to make it clear in the screenshot what each element is and what its dimensions are. But here are the important ones and what they should do:
57+
58+
* `.alignwide` makes an element wider than the normal content.
59+
* `.alignfull` makes an element span the full width of its parent container.
60+
* `.alignleft` floats an element to the left - while still keeping it inside the constraints of the "regular" content's width
61+
* `.alignright` - similar to `.alignleft`, but obviously floating on the right side.
62+
63+
What we _need_ to accomplish:
64+
65+
* We want our normal content to have a maximum width of `50em`.
66+
* Elements that have the `.alignwide` class should be 25% wider than normal content.
67+
* Elements with the `alignfull` class should be 100% of their container.
68+
* We also want a padding on 1em on the left & right of our elements, otherwise on mobile they're going to stick to the edges of the window.
69+
70+
Let's start by adding our defining some variables, and add the padding to our container:
71+
72+
```css
73+
.my-container {
74+
--padding: 1em;
75+
--content-width: 50em;
76+
--wide-diff: 25%;
77+
--wide-width: calc(var(--content-width) * 1.25);
78+
79+
padding: 0 var(--padding) 0 var(--padding);
80+
}
81+
```
82+
83+
### Normal elements
84+
85+
Next up, we can start adding styles for elements that should have a normal width:
86+
87+
```css
88+
.entry-content > :not(.alignfull):not(.alignwide):not(.alignleft):not(.alignright) {
89+
max-width: var(--content-width);
90+
margin-left: auto;
91+
margin-right: auto;
92+
}
93+
```
94+
95+
The above is fairly simply: For all elements that are direct children of our main container, if they are not alignfull/alignwide/alignleft/alignright we're adding our content-width css-variable as the element's maximum width.
96+
Once we do that, we notice that the element is on the left of the screen, so we're adding the margin-left and margin-right lines and set them to auto. This way our element gets properly centered.
97+
98+
### `.alignwide` elements
99+
100+
Moving on to the "wide" elements:
101+
102+
```css
103+
.entry-content .alignwide {
104+
width: calc(var(--content-width) + var(--wide-diff) + 2 * var(--padding));
105+
max-width: 100%;
106+
margin-left: auto;
107+
margin-right: auto;
108+
}
109+
```
110+
This here is a bit more complicated: To calculate the width of our element we're adding the `--wide-diff` var to our content-width, and then we also add the padding (doubled since it exists both on the left and right of our container).
111+
112+
### `.alignfull` elements
113+
114+
The "full" elements are not without their difficulties too:
115+
116+
```css
117+
.entry-content .alignfull {
118+
transform: translateX(calc(0px - var(--padding)));
119+
width: calc(100% + 2 * var(--padding));
120+
max-width: calc(100% + 2 * var(--padding));
121+
margin-left: auto;
122+
margin-right: auto;
123+
}
124+
```
125+
For these ones we have to move the element to the left by the amount of our defined padding, and then set its width to be equal to 100% of our available space, plus the padding doubled so there's no space on the left and right.
126+
127+
### `.alignleft` & `.alignright` elements
128+
129+
Now that we're done with the basics let's move on to the hard part: Getting the floats right.
130+
131+
By default these are not restricted by the `50em` we want for our content since they use `float`. As a result they will literally float to the edges of the screen. Well, not quite the edge, `1em` from the edge 'cause that's the padding we have defined. So how do we get them to be within the limits of our invisible and theoretical "normal content" box?
132+
133+
The best solution I could come up with so far is this:
134+
135+
```css
136+
.entry-content .alignleft {
137+
float: left;
138+
margin-left: calc(50% - var(--content-width) / 2);
139+
}
140+
141+
.entry-content .alignright {
142+
float: right;
143+
margin-right: calc(50% - var(--content-width) / 2)
144+
}
145+
```
146+
147+
The above snippet will add a left margin to elements that are floated to the left and a right margin to elements floated to the right, therefore displacing them visually and moving them to the place we need the to be. It's counter-intuitive and I absolutely hate it. It's an ugly hack that makes absolutely no sense. But it works (most of the time).
148+
149+
In some cases you may need to also add something like this:
150+
151+
## Got a better idea?
152+
153+
How do you handle this? Do you have a better idea? If you do, please let me know. I've been banging my head against the wall for a long time trying to find an elegant solution.
225 KB
Loading

0 commit comments

Comments
 (0)