Position fixed with flexbox - css

I am having a bit of an issue understanding the behaviour of flexbox with position fixed divs.
I am trying to get my nav to stick to the bottom but retain the flex styling I have used.
Basically the icons need to be evenly spaced along a row with a bit of margin to pull in the left and right.
This works absolutely fine but as soon as apply position fixed, bottom 0 the icons get squashed together on the bottom left of the screen can someone please explain.
const FooterNav = () => {
return (
<div className="FooterNave__div">
<HomeIcon />
<SearchOutlinedIcon />
<LocalHospitalOutlinedIcon />
<FavoriteBorderOutlinedIcon />
<PersonOutlineOutlinedIcon />
</div>
);
};
<footer className="app__footer">
<FooterNav />
</footer>
.app__footer {
margin: 0 4vw;
}
.FooterNave__div {
display: flex;
flex-direction: row;
justify-content: space-between;
}

Related

how to align flex box vertical using flex-wrap: wrap

enter image description here
I'm currently making a to-do-list thing.
When I add a folder, the folder is aligned vertically.
(click /Bottom bar/ button -> it shows a /Homecomponent/ folder)
If i add a folder, it keeps going down
but I want the folder aligned like image on the right
I did use flex-wrap css all the div.. but couldn't figure out
this is a code
const CreateFolder = () => {let space = <div>
<img className="space" alt="" src="/image/folder-icon.png" /> Adrina <img className="dwarrow" alt="" src="/image/dwarrow_icon.png"/> </div>
const [createFolder, setCreateFolder] = useState([])
const addItem = (e) => {setCreateFolder([...createFolder, space])}
return (
<div><Bottombar submit={addItem}/>
<Homecomponent createFolder={createFolder}/>
</div>
)}
export default CreateFolder
So if you want to keep the todo list vertically aligned you can try this approach:
{
display: flex;
flex-direction: column;
max-height: 600px; // you must set in order to apply the flex wrap
flex-wrap: wrap;
gap: 9px;
}

CSS either show all elements in a single row or each element on a new row

I have four buttons with varying content lengths. I want all buttons to have the same dimensions as the largest button. They should all be displayed in a single row if there is sufficient space otherwise each button should be displayed on a new row. I have attached a diagram below.
My HTML code is
<div class="answers">
<button class="button">A</button><br>
<button class="button">B</button><br>
<button class="button">C</button><br>
<button class="button">D</button><br>
</div>
I have given the following CSS properties to the container
.answers {
display: inline-flex;
flex-direction: column;
justify-content: center;
flex-wrap: wrap;
}
This ensures that all the buttons are the same width but it always displays them on four lines even when there is room to have them all on a single row.
TLDR:
I need a way to make sure all the buttons have the same width as the largest button, I do not know this value as the buttons can be updated with new content.
I then need to calculate if these four buttons can fit horizontally on the screen and if not display them vertically avoiding a situation where I might have a grid of 2x2.
One approach can be like this (you can use jquery to calculate width for all buttons according to the text in the largest button)
let maxWidth = 0;
$('.button').each(function(){
const width = parseFloat($(this).css('width'));
if(width > maxWidth) {maxWidth = width}
})
$('.button').css('width', maxWidth +'px');
.answers {
display: inline-flex;
justify-content: center;
table-layout: fixed;
flex-direction: row;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="answers">
<button class="button">small</button><br>
<button class="button">s</button><br>
<button class="button">large</button><br>
<button class="button">the largest</button><br>
</div>

CSS Grid Ignores Max Height

I have a complex layout grid for a nonogram app, which should be flexible for different sized grids. A nonogram looks like the following, and the inner grid is not guaranteed to be any particular size or column to row ratio. Also, the headers for the rows and columns will have an unknown number of elements
On smaller screens, my app looks fine and the grid scales down; but as you increase the size, once you hit the point that the height should be limited, the grid instead expands to use up all its available width while keeping its other proportions and blowing out the bottom.
GIF of what's happening: https://ibb.co/YfsT8nL
Some additional sketches of the issue:
I've tried and experimented with a ton of different ways to limit the layout, but nothing seems to have any effect. It seems that the elements containing the grid will size to the limitations I want, but then the #cell-container just blows up and then blows up the #grid-container and then blows out and overflows the #game-container.
The only thing I've done that seems to actually do anything is directly size the #cell-container, but this is not a solution because then the outer grid will not size things properly to keep the headers lined up and center the grid.
The behavior I expect is to have the row and column headers size to min-content, then the cells grid area should size the cells inside to be contained.
Code from my app (written with Svelte, TailwindCSS)
// NonoGame.svelte
<div id="game-container" class="flex flex-col px-2 h-screen">
<div id="game-header" class="flex flex-shrink-0 flex-grow-0 items-center justify-end text-3xl">
<GameTimer />
<PauseButton {controller} />
</div>
<div class="flex-shrink my-auto">
<div class="h-auto">
<NonoGrid controller={controller} />
</div>
</div>
<div id="game-footer" class="flex flex-shrink-0 flex-grow-0 justify-center items-center py-2">
<button class="invisible mr-auto ml-16">Submit</button>
<button id="mark-button" class="mx-2" on:click={() => controller.selectionMode = SelectionMode.Marking} class:active={controller.selectionMode === SelectionMode.Marking}><div></div></button>
<button id="cross-button" class="mx-2" on:click={() => controller.selectionMode = SelectionMode.Crossing} class:active={controller.selectionMode === SelectionMode.Crossing}></button>
<button on:click={submitSolution} class="ml-auto mr-16">Submit</button>
</div>
</div>
<style>
#game-header, #game-footer {
height: 10vh;
}
</style>
// NonoGrid.svelte
<div id="grid-container">
<div id="column-headings">
{#each $gridStore as column}
<span>
{#each GridHelper.getColGroups(column[0].x) as groupNum}
{groupNum}<br>
{/each}
</span>
{/each}
</div>
<div id="row-headings">
{#each $gridStore[0] as rowCell}
<div>
<span>
{#each GridHelper.getRowGroups(rowCell.y) as groupNum}
{groupNum}
{/each}
</span>
</div>
{/each}
</div>
<div id="cell-container"
on:mousedown={dragSelector.onMouseDown}
on:touchstart={dragSelector.onTouchStart}
>
{#each $gridStore as column}
<div class="grid-column">
{#each column as gridCell}
<NonoCell gridCell={gridCell} />
{/each}
</div>
{/each}
</div>
</div>
<style lang="postcss">
#grid-container {
display: grid;
grid-template-rows: fit-content(100px) 1fr;
grid-template-columns: fit-content(150px) 1fr;
grid-template-areas: "x col"
"row cells";
}
#column-headings, #row-headings {
#apply text-xl sm:text-3xl md:text-4xl;
}
#column-headings {
grid-area: col;
display: flex;
align-items: flex-end;
}
#column-headings > span {
width: 100%;
text-align: center;
}
#row-headings {
grid-area: row;
display: flex;
flex-direction: column-reverse;
}
#row-headings > div {
height: 100%;
vertical-align: middle;
text-align: right;
display: flex;
justify-content: flex-end;
align-items: center;
}
#cell-container {
grid-area: cells;
display: flex;
flex-direction: row;
}
.grid-column {
display: flex;
flex-direction: column-reverse;
width: 100%;
}
</style>
If necessary, I can add some dynamic CSS styling with Svelte to respond to the size of the grid I'm rendering like so:
#cell-container {
grid-template-rows: var(--template-rows);
grid-template-columns: var(--template-columns);
}
But I really do NOT want to have Svelte be responsible for responding to screen size. That's what Grid and Flexbox are supposed to be for.
I tried restructuring my grid a little bit like so:
<div id="cell-container"
on:mousedown={dragSelector.onMouseDown}
on:touchstart={dragSelector.onTouchStart}
>
{#each $gridStore as column}
{#each column.reverse() as gridCell}
<NonoCell gridCell={gridCell} />
{/each}
{/each}
</div>
...
<style>
...
/* Static for 5x5 grid; can be dynamic with a css var if it worked in the first place */
#cell-container {
grid-area: cells;
display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(5, 1fr);
grid-template-columns: repeat(5, 1fr);
}
...
</style>
But this doesn't really help the situation much; in fact, there are even more odd behaviors happening when I scale this up and down.
I've created a CodePen with simplified code and a 5x5 grid for anyone to test with. Sorry if it's not perfectly neat and formatted; I did my best.
https://codepen.io/brooksvb/pen/eYReGRR
Thanks in advance for any assistance. I've been fighting this issue for over a week.
Bonus points: A feature I wanted to add, but will accept not having for this project for now, was to have a small gap appear between groups of 5 rows/columns, like the following picture. I already did some research into how to have a variable grid gap, but have found that Grid currently has no way to define anything besides a grid-wide gap value. If you have an idea of how to implement this in your solution, I'd love to see anything.
I wanted to leave the solution here that I used; I wrote some Javascript to do the calculation of cell size. G-Cyrillus' comment above also has a good idea of how to restructure the grid to handle it which I may revisit.
// NonoGrid.svelte
<script>
...
// DOM Elements
let gridSlot;
let columnHeadings;
let rowHeadings;
let gridColumns = [];
// This function calculates the size of cells based on screen space
const resizeCells = () => {
// Max height and width available
let maxHeight = gridSlot.clientHeight;
let maxWidth = gridSlot.clientWidth;
// Get height and width occupied by headers
let colHeaderHeight = columnHeadings.clientHeight;
let rowHeaderWidth = rowHeadings.clientWidth;
// Divide remaining space among rows and cols
let availableHeight = (maxHeight - colHeaderHeight) / controller.getRows();
let availableWidth = (maxWidth - rowHeaderWidth) / controller.getCols();
// Choose smallest for both dimensions to make square
let targetCellSize = (availableHeight < availableWidth ? availableHeight : availableWidth) + 'px';
// console.log(`Resizing to target: ${targetCellSize}`);
gridColumns.forEach((colElem) => {
colElem.style.width = targetCellSize;
});
}
onMount(() => resizeCells());
</script>
<svelte:window on:resize={resizeCells}></svelte:window>
<!-- Add grid slot to set max-height and contain the container, centered inside. Also add DOM bindings for above access -->
<div id="grid-slot" class="flex" bind:this={gridSlot}>
<div id="grid-container">
<div id="column-headings" bind:this={columnHeadings}>
...
</div>
<div id="row-headings" bind:this={rowHeadings}>
...
</div>
<div id="cell-container"
on:mousedown={dragSelector.onMouseDown}
on:touchstart={dragSelector.onTouchStart}
>
{#each $gridStore as column, i}
<div class="grid-column" bind:this={gridColumns[i]}>
{#each column as gridCell}
<NonoCell gridCell={gridCell} />
{/each}
</div>
{/each}
</div>
</div>
</div>
<style lang="postcss">
#grid-slot {
height: 80vh; // Set the height limit
}
#grid-container {
width: min-content; // Needed to scale down the column headers when columns shrink
margin: auto; // Centers horizontally and vertically (thanks to flex container)
...
}
...

Wordpress (divi) Flexbox alignment problem

I am using Wordpress (Divi theme page builder) and I'm trying to use flexbox css to horizontally align two image modules each in a separate column within a row, so that one appears on the left and one appears on the right.
I've added custom CSS to the row: 'display: flex; justify-content: space-between' which works for the left image module, but the right image is not being pushed fully to the right.
See the image below for an example. I've tried fiddling about with many settings but nothing is helping.
Example of Problem
The page is currently private on my website (www.mistyricardo.com) but if needed I can make it public for inspection.
Thank you in advance.
following...
Check and apply according to your markup
If the 'Currey at home - Volume 1' and 'Currey at home - Volume 2' books are in the same container:
.book-wrapper {
display: flex;
justify-content: space-between;
}
/* this is for demo only - ignore the below */
img {
height: 150px;
}
<div class="banner-header">
<div class="book-wrapper">
<img src="https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1548876269l/43791788._SY475_.jpg" />
<img src="https://upload.wikimedia.org/wikipedia/en/f/f4/Gangsta_Granny_Cover.png" />
</div>
</div>
If the 'Currey at home - Volume 1' and 'Currey at home - Volume 2' books are not in the same container:
.banner-header {
display: flex;
}
.book-img {
margin-left: auto;
}
/* this is for demo only - ignore the below */
img {
height: 150px;
}
<div class="banner-header">
<div class="book-wrapper">
<img class="book-img" src="https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1548876269l/43791788._SY475_.jpg" />
</div>
<img class="book-img" src="https://upload.wikimedia.org/wikipedia/en/f/f4/Gangsta_Granny_Cover.png" />
</div>

Styling inline within a span

I'm trying to get this.toggleFormatter(task) to float to the right. It currently has display: inline-grid on it so that it is next to the link, but I can't get it to move right and stay inline. Flexbox and float doesn't seem to work... any ideas?
return {
text: (
<span className="tree-toggle-spacing">
<Link to={'/tasks/' + task.id}>
<Label bsStyle="info">T{index+1}</Label>
{task.name}
</Link>
{/*className="tree-toggle-select" */}
{this.toggleFormatter(task)}
</span>
),
nodes: resources
};
You can align elements to the left and right by using the following CSS classes:
.align-left { float: left }
.align-right { float: right }
To keep everything inline, simply add this code outside of both of the elements that have the float classes but inside the div they are both in: <div style="clear: both;"></div>

Resources