Inertia.js and scroll management of scrollable divs - css

I think I may misunderstand scroll management with Inertia.js and scrollable divs.
Maybe somebody can point me in the right direction.
I started off without scrollable divs. And using "preserve-scroll" on links works fine and remembers the scroll position in the document body.
Then I switched to a new layout where the height is always 100% of the screen.
And the logical columns of the application scroll automatically vertically. Slack-app style.
Clicking on Inertia links with preserve-scroll now does not restore the scroll position of the scrollable elements.
I tried a couple of things like using "scroll-region" but in the documentation it sounds as if scroll-region is not meant for preserving the scroll position but for resetting it.
This is a simplified example of my code (with Vue and Tailwind):
<template>
<div class="flex h-screen overflow-hidden">
<ul class="w-1/4 bg-teal-100 divide-y max-h-screen overflow-y-auto">
<li v-for="(item, idx) in listItems" :key="idx" class="p-2">
<Link href="/" class="block" preserve-scroll>{{ item }}</Link>
</li>
</ul>
<div class="flex-1 bg-indigo-100 p-2 max-h-screen overflow-y-auto">
<p class="mb-2">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nec
interdum turpis. Curabitur et lectus mollis libero placerat hendrerit
eget vel ipsum. Morbi eu diam id justo interdum condimentum a vel dolor.
In hac habitasse platea dictumst. Etiam imperdiet dolor laoreet placerat
laoreet. Nulla erat lacus, facilisis quis nulla in, dignissim lobortis
augue. Cras viverra diam diam, et commodo augue rhoncus non. Vestibulum
pretium luctus justo, at lobortis odio vestibulum sed. Nulla facilisi.
</p>
<!-- long content here -->
</div>
</div>
</template>
<script>
import { Link } from '#inertiajs/inertia-vue'
export default {
components: {
Link,
},
props: {
user: Object,
},
computed: {
listItems() {
let items = [];
for (let i = 0; i <= 50; i++) {
items.push(`ListItem ${i}`);
}
return items;
},
},
};
</script>
I also tried to add "scroll-region" to the "ul" tag.
Using "preserve-state" in the s kind of does the trick but I would like to only preserve the scroll positions of all the scrollable elements after any click.
Any tipps appreciated.

Related

Flexbox: variable/dynamic height items with column wrap

I'm struggling with creating a dynamic layout which is different for mobile and desktop. The items should be different sorted based on the screen width and the layout should change.
Below is the main objective, where the left layout is for mobile and the right one is desktop:
The content of the blue, purple and yellow div can vary so the height is adjustable. The purple and yellow block must always be on the side of the gray + blue block on desktop.
Right now I have it working for only 3 columns but the 'dynamic' height is duplicated on all columns: Bootstrap 4: sidebar between columns on mobile. Columns under each other layout
To give you a clear idea of the possibilities here are some desktop variations:
I've managed to get it working with floats but the columns align on each other. Also have fixed it with a static max-height for the parent and use column wrap but I don't want to use a static max-height since the content should have a dynamic height..
I don't want to use some glitchy javascript or unsupported grid-css.
Looking forward to ideas/suggestions! Cheers.
You should be able to get this layout to work with a combination of CSS columns (not CSS grid) on "desktop", and flexbox on "mobile".
<div class="container">
<div class="d-flex d-md-columns flex-column min-vh-100">
<div class="d-md-inline-block light order-0">
light
</div>
<div class="d-md-inline-block blue order-2">
blue
</div>
<div class="d-md-inline-block purple order-1">
purple
</div>
<div class="d-md-inline-block yellow order-3">
yellow
</div>
</div>
</div>
The only extra CSS you'll need is a media query for the columns on larger (md) desktop widths. The the flexbox ordering will kick-in on mobile..
#media (min-width: 768px) {
.d-md-columns {
display: inline-block !important;
column-count: 2;
-webkit-column-gap: 0
-moz-column-gap: 0;
column-gap: 0;
}
}
https://codeply.com/go/QWIlredUTk
This works specifically for this 4 column layout. However, generally speaking flexbox columns do NOT fit together vertically like a "masonry" layout: Is it possible for flex items to align tightly to the items above them?
I think there is no pure CSS solution for this (at least without using CSS-grid or display:contents). Every CSS way I thought had bugs: float & column flexbox simple don't work in this particular case.
Column flexbox cannot wrap correctly an item if we work with a content without fix height and float can't create a "masonry" layout. Also Bootstrap card-columns are not a solution because your main objective is to align left and right column in height.
I know, you don't want glitchy javascript, but I think it is necessary to create your layout. So, I post you my solution (a jquery solution) without use any d-none class to prevent duplicate HTML & SEO problems.
Moreover, you are using Bootstrap and this framework makes extensive use of jQuery so, I think, it not a problem to ask jQuery for a little help. This help:
function move(){
if($(".main .col-lg-8").css('display')=='block'){
$('.purple').insertAfter('.gray');
} else {
$('.purple').insertBefore('.yellow');
}
}
$(window).resize(function(){move()})
$(document).ready(function(){move()})
To move our purple div in second position when .col-lg-8 have display:block
This is all code in action:
function move(){
if($(".main .col-lg-8").css('display')=='block'){
$('.purple').insertAfter('.gray');
} else {
$('.purple').insertBefore('.yellow');
}
}
$(window).resize(function(){move()})
$(document).ready(function(){move()})
.gray{
background-color: gray;
}
.blue{
background-color: blue;
}
.purple{
background-color: purple;
}
.yellow{
background-color: yellow;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<div class="container mt-5">
<div class="row main">
<div class="col-lg-4 d-lg-flex flex-lg-column">
<div class="gray mb-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sodales finibus faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec, feugiat eget justo. Ut aliquam quis velit non euismod. Ut vehicula, sem quis cursus pretium, purus libero tincidunt eros, vitae hendrerit nisi mi vitae erat. Curabitur augue purus, sagittis tempor volutpat quis, congue sed mi. Sed gravida odio sed orci iaculis tincidunt. Etiam ac mauris sit amet turpis consequat fermentum ut vitae sem. Aliquam tincidunt convallis sem.</div>
<div class="blue flex-fill mb-4 mb-lg-0">
Lorem ipsum dolor sit amet, consectetur.Quisque sodales finibus </div>
</div>
<div class="col-lg-8 d-lg-flex flex-lg-column">
<div class="purple mb-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec, feugiat eget justo. Ut aliquam quis velit non euismod. Ut vehicula, sem quis cursus pretium, purus libero tincidunt eros, vitae hendrerit nisi mi vitae erat. Curabitur augue purus, sagittis tempor volutpat quis, congue sed mi. Sed gravida odio sed orci iaculis tincidunt. Etiam ac mauris sit amet turpis consequat fermentum ut vitae sem. Aliquam tincidunt convallis sem. </div>
<div class="yellow flex-fill">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
</div>
</div>
</div>
Waiting a pure CSS solution, this could be a way.

Why is this image resized inside container with flex-wrap value different than wrap?

I am playing with Bootstrap 4 and I have noticed that when I put <img> inside <div class="row"> that has flex-wrap: nowrap, Firefox will automatically resize the image. Code and link to pen is below.
Why does Firefox do that, how does it calculate resizing ratio and how can I make it stop?
Codepen with issue (compare upper and lower image)
Screenshot on Firefox 59
.nowrap {
flex-wrap: nowrap;
}
<div class="container">
<div class="row nowrap">
<img src="https://www.w3schools.com/howto/img_fjords.jpg">
Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse
a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada
ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna.
Vestibulum commodo volutpat a, convallis ac, laoreet enim.
</div>
</div>

Bootstrap: Background colour 100% screen width?

I'm trying to create a fairly simple website in bootstrap. I'd like each section to have its own background colour similar to what is done here: https://flaticons.co/. Do you happen to know if there's a class or css styling that will allow the background to be 100% width?
<div id="main" class="container">
<section class="row">
<p class="col-md-4 col-sm-6" col-sm-push-7><img src="images/an_image.gif"></p>
<h1 class="col-md-8 col-sm-6" col-sm-pull-7>Some content...</h1>
</section>
<!-- ===== background colour wanted here 100% window width===== -->
<section id="about" class="row">
<div>
<p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Maecenas faucibus mollis interdum. Donec id elit non mi porta gravida at eget metus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Etiam porta sem malesuada magna mollis euismod. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Donec ullamcorper nulla non metus auctor fringilla. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.</p>
</div>
</section>
</div>
-----------This works:
Guys! Guys!
Thanks for those answers. They're great for when bootstrap isn't involved. When bootstrap IS involved... this works. So many divs :( But it's working great!
<div class="secondary">
<section class="row container">
<div class="row">
<p class="col-md-4 col-sm-6" col-sm-push-7><img src="images/temp_riley.gif"></p>
<h1 class="col-md-8 col-sm-6" col-sm-pull-7>Hi. I'm Riley: a problem solving UX designer (and front-end developer) who is intrigued by change and loves a good challenge. </h1>
</div>
</section>
css:
.secondary {
background: green;
}
To make an element 100% the screen width in CSS you can use the following:
width: 100vw;
The vw stands for view width. This is new to CSS3. See here for compatibility in browsers (Current browsers almost universally support it).
In your simple example, setting the width of each section and div to 100% will stretch them across your browser's window. Here's a fiddle showing what you're looking for, http://jsfiddle.net/MPQVu/, but the basic idea at play is:
.parent_div { width: 100%; }
.child_div { width: 100%; }

Always content to stay in middle of next child?

I am using Boostrap 3 for some website I am creating, what i want to make i next.
Here is a code
<section class="container-fluid">
<div class="container">
<div class="row">
<div class="col-md-6"><img class="img-responsive" src=
"http://webdesignledger.com/wp-content/uploads/2009/09/logo_design_4.jpg" /></div>
<div class="col-md-6">
<h2">Lorem ipsum dolor</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean eu sollicitudin felis. Vestibulum vitae imperdiet nibh. Curabitur euismod
auctor libero sit amet varius. Maecenas eu porta libero. Pellentesque et sem et
turpis scelerisque hendrerit vel ac nibh. Nam tempor ullamcorper scelerisque.
Aenean accumsan ac justo ac laoreet. Aliquam eu libero</p>
</div>
</div>
</div>
<section>
Here is working fiddle
http://jsfiddle.net/gSmRw/
On big screen text always to be allign in the middle of the picture, i dont know how big picture will it be, maybe small maybe big, any idea, or help.
Here is picture what i want to make and how it has to look up
http://jsfiddle.net/gSmRw/3/
I've basically added a calss table to the .container element and changed the CSS of this container to be styled as table.
it's important to give the image div wrapper a width of 1% so the cell will not be wider than the image.

Twitter Bootstrap Preferred Way to Align Span Content

So this might seem like an obvious question to some, but what is the best practice for aligning versatile span content in a responsive grid? I know you could simply set a pixel height, but wouldn't that kind of defeat the purpose of keeping things responsive?
Take the below screenshot for instance:
<div class="container">
<div class="row">
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero, vel fringilla neque euismod vitae. Nullam justo mi, faucibus sagittis pharetra non, egestas sit amet nulla.</p></div>
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero, vel fringilla neque euismod vitae. Nullam justo mi, faucibus sagittis pharetra.</p> </div>
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero.</p> </div>
</div>
</div>
You can find the relevant JSfiddle here.
Note: Responsiveness seems to be broken in this JSFiddle for some reason, works fine in my own Twitter Bootstrap application however.
If you take a look on DigitalLabs which is a website I worked on then if you look at the profiles I came across a similar error - i wanted them all to be the same height.
See my JSFiddle here:
http://jsfiddle.net/LDtRr/2/
(scroll down to the bottom and press resize to see them all dynamically resize)
I used some javascript to fix the heights - I will show you the code that I used.
function resize(resize, resizeinner) {
var max = 0;
//reset height back to 0
$(resize).each(function(index, element) {
$(element).css({ 'height' : '0' });
});
//find height of the profiles
$(resizeinner).each(function(index, element) {
var height = $(element).height();
console.log(' height=' + height);
if(height > max) {
max = height;
}
});
//set the height dynamically based on the maximum so they are all uniform
$(resize).each(function(index, element) {
$(element).css({ 'height' : max });
console.log(' resizedTo=' + $(element).height());
});
console.log('max - ' + max);
}
Then for the html i used
<div class="span4">
<div class="well profile">
<div class="profile-resize">
<!-- content -->
</div>
</div>
</div>
What the code does is it gets the maximum height for the divs with the profile class, then sets all of the divs with that class to the maximum height - you can also bind this to the window resize so it automatically resizes the heights with the window.
$(window).load(function() {
//initially size the elements
resize('.profile', '.profile-resize');
});
Maybe not the most elegant solution but I couldnt think of a better one at the time.
Although your markup doesn't keep the hierarchy recommended by the bootstrap doc (.container > .row > .span > .well), have you thought about absolute positioning ? No JS involved.
Demo (jsfiddle)
<div class="container" style="position: relative;">
<div class="row faux-row">
<div class="span3 well"></div>
<div class="span3 well"></div>
<div class="span3 well"></div>
</div>
<div class="row vrai-row">
<div class="span3"><p>...</p></div>
<div class="span3"><p>...</p></div>
<div class="span3"><p>...</p></div>
</div>
</div>
.vrai-row { position: relative;z-index: 101; }
.faux-row { position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 100; }
.faux-row .well {
height: 100%;
/* The following is because .span* elements should not have paddings, margins nor borders see http://stackoverflow.com/a/11299934/1478467 */
box-sizing: border-box;
}
If you want to set padding, margin, borders (styling that actually take space), it should be applied to the real one and the faux one - not the columns themselves, but their children for example.
The downside is that (as it is in the demo) you have to stick to the non-responsive grid (fluid or static). But it should work with a few more rules encapsulated in media queries.
Update
Responsiveness is actually not so hard to get, if you keep the .well class on all spans :
Demo responsive (jsfiddle)
#media (max-width: 767px) {
.faux-row { display: none!important; }
}
#media (min-width: 768px) {
.vrai-row .well { /* Deactivate well styles */
background-color: transparent;
border-color: transparent;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}

Resources