My webpage has a 2 column layout, left side is filters and right side is articles, like this:
Goals:
- Fixed width filters (left side) @ big viewport
- Full width filters above articles (one column layout) @ small viewport
- @ big viewport stack articles on right till we get to the height end of 1st column and then full width articles, like this:
I am currently doing this with JS getBoundingClientRect()
but would love to know if there is a CSS solution please?!
As requested, current JS solution via SvelteKit
:
import {
onMount
} from 'svelte';
import type {
PageData
} from './$types'
import Source from '$lib/components/Source.svelte'
import type {
QuoteCategory
} from '$lib/util/types'
import AuthorChips from '$lib/components/chips/AuthorChips.svelte'
import QuoteCategoryChips from '$lib/components/chips/QuoteCategoryChips.svelte'
export let data: PageData
let categories: QuoteCategory[]
if (data.categories) categories = data.categories
onMount(fullSizeSources)
function fullSizeSources() {
let wideDone = false
const scrollTop = document.documentElement.scrollTop
const authors = document.getElementById('author-chips')
const sources = document.getElementsByClassName('source')
const authorBottom = (authors ? .getBoundingClientRect() ? .bottom || 0) scrollTop
for (let source of sources) {
if (wideDone || (source.getBoundingClientRect().top scrollTop) > authorBottom) {
wideDone = true
source.classList.add('full')
} else {
source.classList.remove('full')
}
}
}
.wrapper {
display: flex;
align-items: flex-start;
justify-content: space-between;
.left {
max-width: 36rem;
margin-right: 1.8rem;
display: flex;
flex-direction: column;
}
:global(.source.full) {
margin-left: -37rem;
width: calc(100% 37rem);
}
}
<div >
<div >
{ #if data.categories }
<QuoteCategoryChips categories={ data.categories } location="nav" /> { /if } { #if data.authors }
<AuthorChips authors={ data.authors } /> { /if }
</div>
<div>
{ #if data.sources } { #each data.sources as source }
<Source { source } /> { /each } { /if }
</div>
</div>
CodePudding user response:
If I understand you correctly, you can solve this problem by using float and @media. For small viewport use normal layout with one column. For big viewport you can use float: left;
so that your articles are on the right side and after reaching the height of the left column they become 100% width.
/* Just some styles to visualise. Notice the use of flex, it makes it easier to work with the content of these elements */
.left,
.right-article {
display: flex;
flex-direction: column;
padding: 1rem;
margin: 1rem;
border: 1px solid blue;
}
/* Replace 600px with whatever you need */
@media (min-width: 600px) {
.left {
/* Replace the width with whatever you need */
width: 300px;
float: left;
}
}
<div>
<div >
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
<p>Exercitationem et qui fuga non illo nemo, harum ab, vero in illum maxime, dolore dignissimos velit provident id iure accusantium fugiat amet!</p>
</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit.</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit..</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit.</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit.</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit..</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit.</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit.</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit..</div>
<div >Lorem ipsum, dolor sit amet consectetur adipisicing elit.</div>
</div>