taeo920
taeo920

Reputation: 41

Is it possible to build this layout with no JS and no duplication of elements - only CSS?

I've been struggling to find a way to build this layout. All elements have unknown heights except for the social elements. The related and latest elements are optional.

I'd like to do it without resorting to JS or duplicating elements but I'm actually not sure if it's even possible.

Mobile and tablet are very easily handled with flexbox and the "order" property. I thought I could handle the desktop layout by reverting to floats but since the element heights are unknown this isn't guaranteed ( i.e. the latest and/or related elements might float over to the left if the body copy is short ).

Any ideas? Or should I just suck it up and dynamically add a sidebar to the DOM with JS for the desktop breakpoint?

Edit: Note the order of the elements! If I place the desktop sidebar elements in a container I can no longer re-order them on mobile/tablet with flexbox. Also, I don't believe grid-layout applies since the desktop layout does not follow a grid pattern.

image of layout

Upvotes: 1

Views: 104

Answers (1)

Vincent Smedinga
Vincent Smedinga

Reputation: 193

Two-dimensional page layout like this is what CSS Grid was designed for. Flexbox is more suitable to arrange items in one dimension (although a second dimension will easily follow when nesting or wrapping). As others have mentioned, this layout should be totally accomplishable with CSS only.

One approach using CSS Grid is having three template area definitions that change on each breakpoint, as demonstrated here.

Part of the HTML and SCSS for that:

<div class="grid">
    <div class="area social"></div>
    <div class="area body-social"></div>
    <div class="area categories"></div>
    <div class="area related-latest"></div>
</div>

.area {
    &.social { grid-area: social; }
    &.body-social { grid-area: body-social; }
    &.categories { grid-area: categories; }
    &.related-latest { grid-area: related-latest; }
}

@media (min-width: 64em) {
    .grid {
        grid-template-areas: 
            "body-social social"
            "body-social categories"
            "body-social related-latest";
    }
}

I took the liberty of combining some of your sections into areas, as I’m unaware whether the visual design would disallow it. You might have to manage some additional gutters if it does. Also note that the right column in the wide layout is currently only sized to the length of the text inside, which will probably not hold with real content. There will be more use cases I haven’t addressed, but if anything my example can be a starting point for you to work from.

A slightly different approach would be to define grid-template-columns and grid-template-rows for each breakpoint, and configure the correct grid-columns and grid-rows for each area or section. This would imply some more explicit sizing, which has pros and cons in itself.

Furthermore, you would need to think about which layout you want to present to people using a browser without support for CSS Grid.

To learn more about modern layout techniques in CSS, I recommend checking out the articles and videos by Rachel Andrews and Jen Simmons.

Let me know if you have additional questions or remarks.

Upvotes: 1

Related Questions