3 colum layout on bootstrap losing its shape - css

I have a 3 columns design where the first column has a fixed width of 630px, the middle column should take all available space and the third column has a fixed width of 200px.
I set it up using bootstrap Flex, with flex-fill in the middle column. It looks all dandy but when I start filling up the middle section, it grows eating the space of the last one.
The code, simplified, looks like this:
//body css: height: 100%, oveflow: hidden
<div class="mainContainer d-flex flex-row w-100"> //css: height 100vh,
<div class="leftColumn d-flex">
//inner content ar boxes with fixed width leaning to the 600px
//this part looks perfect
</div>
<div class="MainArea flex-fill d-flex flex-column">
<div class="MainAreaUpperRowOfCards flex-fill d-flex flex-row flex-wrap">
// here I add cards with fixed size, they are lied down
// in a row, and they wrap nicelly.
// But when they wrap this section starts to grow eating the
// third colum's space
</div>
</div class="MainAreaLowerRow d-flex flex-row justify-content-center">
//css: height: 250px, margin-bottom: -60px
//here are some cards that only show the upper part, hence the -60px
</div>
<div>
<div class="RightColumn d-flex flex-column"> //css: width 220px; background and magins..
//here some cards with players information
//this is the column being eaten.
</div>
</div>
This is what it looks like at the beginning and after adding some cards:
So I have two questions:
How do I fix the width of the right-most column? (green arrow in the picture)
How do I remove the space on the wrapping of the cards? (red arrow in the picture)
I added an animation for convenience:

Change width: 220px; to min-width: 220px;.
It's hard to help you without a live demo. Try to remove flex classes one by one and see if any of these classes are causing this space.

Related

how to place multiple items in a grid column cell using tailwind?

I have a design where I have 3 items. 2 items should be placed vertically and 1 item has to be in it's own cell. So, 2 items should be placed in 1 cell vertically and 1 item takes it's own whole cell. To demonstrate, below is the image
How can I achieve this design using tailwind?
You can make such layout using grid - separate your layout on three columns (sidebar + main content spans on two columns) and 2 rows like #ChenBr did
<div class="border-2 grid grid-cols-3 grid-rows-2">
<div class="border-2 col-span-1">1</div>
<div class="border-2 col-span-2 row-span-2">2</div>
<div class="border-2 col-span-1">3</div>
<div>
However grid-rows-2 will be compiled as
.grid-rows-2 {
grid-template-rows: repeat(2, minmax(0, 1fr));
}
1fr for both rows means 2 rows will be sized equally. So I would recommend to change this class into grid-rows-[min-content_1fr] - that mean first row will take place base on its minimum content
min-content - is a keyword representing the largest minimal content contribution of the grid items occupying the grid track.
and the second one will take the rest - but it's up to your application
Basic example
<div class="grid grid-cols-3 grid-rows-[min-content_1fr]">
<div>1</div>
<div class="col-span-2 row-span-2">2</div>
<div>3</div>
<div>
DEMO
You can achieve this setup using grid/flex. Using one or the other depends on your content.
Grid:
Create a three-by-two grid using grid-cols-3 and grid-rows-2 on the grid's container. Then, set each container's span to fit your structure (using col-span-n row-span-n).
Read about grid-cols here and about grid-row here.
<div class="border-2 grid grid-cols-3 grid-rows-2">
<div class="border-2 col-span-1">1</div>
<div class="border-2 col-span-2 row-span-2">2</div>
<div class="border-2 col-span-1">3</div>
<div>
Tailwind-play
Flex:
We are going to have two containers. The main container will wrap all the elements (including the second container), and the inner container will wrap your first two elements. Each of those containers will have a flex utility applied to it.
Then, we will apply flex-col on the second container. This way, the container will place its children on top of each other, just like the first column of your image.
The first container's default flex-direction is flex-row which is why the inner container and the third element will be positioned next to each other, just like a row.
To give the structure a proportion similar to your image, we can set the inner container's width to 30% (w-[30%]), and the third element to 70% (w-[70%]).
Read about flex-direction here.
<div class="flex border-2">
<div class="flex w-[30%] flex-col">
<div class="border-2">1</div>
<div class="border-2">2</div>
</div>
<div class="w-[70%] border-2">3</div>
<div></div>
</div>
Tailwind-play

Give column the width of container

Is there a possibility to give a bootstrap 4 col the width of its child, which is a container class?
<div class="container-fluid">
<div class="row">
<div class="col bg-secondary m-0 p-0">
text left
</div>
<div class="col-auto bg-primary">
<div class="container bg-primary m-0 p-0">
text mid
</div>
</div>
<div class="col bg-secondary m-0 p-0">
text right
</div>
</div>
</div>
I basically want to be able to put content on the left and right of a container, but I don't want my container to change in size because of this, because this left and right content won't be present on every page, and I want a consistent container width cross pages.
https://jsfiddle.net/5gt9uoqb/
Update:
Here's an image of what I would like to achieve: ibb.co/tcKM6S0 . At the bottom is a 'normal' page, with a centered container. This is a div with the standard container class that ships with bootstrap. At the top is a new page type I would like to create. It should have the exact same container like the other page, but I want to be able to put content in the grey zones, like, for example, some social icons (blue in the img). Wrapping the normal pages in a column too is not an option in my set up because of other stuff.
if you know about position property, then you can handle this issue without touching the container class.
For that, you need to a parent class of all child element. I mean after the body tag you take a class and give it position relative the which content you want to be left give it position absolute and left:0px;(you can space from left according to your), and if you want content right then you give it right:0px;

Flexbox column vertical align a child at the top and a child at the center of the column

Currently I'm struggling with flexbox column. Checked so many websites, but still no solutions to be found on the internet for this problem.
The case:
On the right side of my viewport I've got a full-height flex-column, containing 2 elements (see headset icon and hangup button). I used flex-column to vertically align my elements.
The first element should be on the top right corner, the second element should be at the center right.
Since it's a flex-column I can't use align-self-center on the second element, because it will be centering on the x-axis instead of the y-axis.
I was wondering if this is even solvable with just flexbox or if I need to position this centered element a different way?
I'm using the bootstrap 4 flex classes to apply flexbox.
Code example: https://jsfiddle.net/mv1e7py0/18/
<div class="flex-container flex-column main-containere video-container">
<div class="communication-controls d-flex justify-content-between">
<div class="left-controls d-flex flex-column justify-content-between">
<button class="chat-toggle">
Chat
<div class="indicator bg-red"></div>
</button>
<button class="mic-toggle">
Mic
</button>
</div>
<div class="right-controls d-flex flex-column justify-content-between">
<button class="speaker-toggle">
Headset
</button>
<button class="dismiss-call red align-self-center">
<span>Hang up</span>
</button>
</div>
</div>
</div>
What I want it to look like:
#miranda-breekweg here are 2 quick solutions that I hope you'll find helpful:
In both cases we'll keep justify-content set to space-between.
the first thing that comes to mind is to simply set the height of the right column to 50% (+ half the height of that button you want to center)
.right-controls {
height: calc(50% + /half the height of your button/);
}
the second and probably the easiest solution is to simply add auto margins (top and bottom) to the targeted button. This way, you don't have to worry about calculations:
.dismiss-call {
margin: auto 0;
}
Fiddle:
https://jsfiddle.net/mv1e7py0/39/

Is it possible to put "row"-s inside "d-flex" in Bootstrap 4?

(There's a similar question here, but I am too much of a noob yet to translate this onto Bootstrap)
What I want is to have an area on the page between "header" and "footer" (let's call it "body"), which may have a
some fixed section, like BS4 "row", put on the top,
some variable content, consisting of several BS "rows", AND aligned
vertically on the middle of what is left of the body (or of the body
itself)
Can it be done in a responsive manner, and without JS (using only Bootstrap 4 CSS) ?
I've tried some stuff:
<body>
<div id="root" class="container">
<div style="height: 100%;">
<div><h1>HEADER</h1></div><hr>
<div style="min-height: 60%;">
<div class="h100">
<div>some badge</div><br>
<div>
<div class="row justify-content-between">
<div class="col-3">Item #2</div>
<div class="col-3 text-right">
<div>some stats</div>
</div>
</div>
<div class="">
<div class="row justify-content-center">
<div class="col text-center"><h3>THIS SHOULD BE IN THE MIDDLE OF A BLANK SPACE</h3></div>
</div>
<div class="row justify-content-center">
<div class="col-4 text-right"><button class="btn btn-link">it's just below and left</button></div>
<div class="col-4 text-left"><button class="btn btn-link">it's just below and right</button></div>
</div>
</div>
</div>
</div>
</div><hr>
<div class="footer">FOOTER</div>
</div>
</div>
</body>
(https://jsfiddle.net/f93mhdbr/) but as long as I add "d-flex" onto "body" div, or any of it's children, all the previous "row"/"col"-based layout turns into horrible mess ! (see https://jsfiddle.net/f93mhdbr/2/)
I suspect this is due to Bootstrap itself using Flexbox for column and rows,
but maybe any solution exists?
I will try to work on improving this question, I know it's very poor, but I right now I am too much in a despair to work it all out...
UPDATE: added links to whatever I was trying to reproduce
You need to use the flex property to achieve it. Using flex-grow here will make your variable element to grow and fill the remaining height of its container, if there is any. Then all is left to do is set align-items-center on the element to align it on the x-axis.
Here is the Fiddle
Please note I added background-colors so it's easier for you to see how much space each element uses, or use an inspector.
You can set any fixed height for the header, footer and content-top. The height of content and content-remaining will adapt responsively, because they have the property flex-grow: 1 set on them. Here's an example.
To explain further, because the container wrap has a min-height: 100-vh, the content element will grow to fill the entire viewport relative to the rest of the flexible items inside the wrap container. The same logic applies to content-remaining, the only difference is that its parent is the content element and not the wrap container.
As last, I added the IE fix for the min-height property on flex-items. It's a known bug and a quick and reliable fix is to wrap it in a separate flex container.
Hopefully this was helpful to you, if you have any questions left please comment on this answer.

Bottom align columns in bootstrap-ui

I'm using angular and bootstrap-ui. I have two columns beside each other, the right one has a larger height then the the left due to the presence of controls. All I want to do is add some text in the right column that is aligned with the bottom of the left column, which should be easy. I will not admit how long I struggled with it.
It looks like the problem is that the left column itself is top aligned. so I have something like this:
*****************
* * * *
* col 1* * col 2 *
******** * *
* *
*********
I would like to cause col 1 to align with the bottom of col 2 within the row. From there aligning text in col 1 with the bottom of the col should be easy.
I've found many supposed solutions, but they don't seem to work. The most common involve overriding the display and vertical-align properties of the CSS, but doing this seems to screw up the rows alignment in odd ways. I've seen col 1 end up after col 2 or the row shrinking to not use it's full width of the page. The point being my attempts to override elements are messing with bootstrap. I believe this is because most suggestions are not actually for angular and bootstrap-ui.
The closest I got to something working was setting display:fluid for the row. This got the columns to be the same size without interfering with the rest of the look and feel. However, I then couldn't use text-right or verticle-align to position the text within col 1 on the bottom right of the column.
How can I get my text in my first column to align with the bottom of col 2?
There are issues that you can have if you try to use vertical-align within a bootstrap container. Even if you also try use (parent) display:table; and then in (child) with display:table-cell;. You lose the height control.
Your best option here is probably as I have set up in this Fiddle.
But saying that... because we use margin-top and when you resize the window to a smaller screen size you still have the problem with the top margin as you will see in the Fiddle.
But you can control this by using Bootstrap's lg, md, sm and xs to keep your text lined up, again this is also set up in the Fiddle to show how you can control this problem.
Resize the window, I have the large view setup in the fiddle.
<html !DOCTYPE html>
<head>
<link rel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" >
<style>
.block{
overflow: visible;
}
.block-a {
margin-top:200px;
height:100px;
}
.block-b {
height:300px;
padding-top:200px;
overflow: visible;
}
</style>
</head>
<body>
<div class="container col-lg-12"><br></div>
<div class="container col-lg-12 bg-warning block">
<div class="col-lg-3 col-lg-offset-2 bg-primary block-a "> Hello</div>
<div class="col-lg-3 col-lg-offset-1 bg-info block-b ">Great, lined up to the left.</div>
</div>
<div class="container col-lg-12"><br></div>
<div class="container col-lg-12 bg-success block">
<div class="col-lg-3 col-lg-offset-2 col-md-3 col-md-offset-2 col-sm-3 col- sm-offset-2 col-xs-3 col-xs-offset-1 bg-primary block-a "> Hello</div>
<div class="col-lg-3 col-lg-offset-1 col-md-3 col-md-offset-2 col-sm-5 col- sm-offset-2 col-xs-7 col-xs-offset-1 bg-info block-b ">Great, lined up to the left.</div>
</div>
</body>
</html>

Resources