I'm trying to get into the grid layout system and I'm really struggling with image-sizes inside grid containers. I just want to create a simple page with a navbar. The navbar should contain a logo, icons and text. It is divided into three parts:
A left part, containing the logo (aligned to the left side)
A center part, containing a title (aligned to the center)
A right part, containing an image and text (aligned to the right side)
Because I want to work with grid whenever possible my planned structure looks like this: https://codepen.io/Nicolas_V/pen/QWbvxoW
HTML:
<div class="site">
<div class="navbar">
<div class="navbar__area--left">
<div>Logo</div>
</div>
<div class="navbar__area--center">
<div>Admin Page</div>
</div>
<div class="navbar__area--right">
<div>Text</div>
<div>Image</div>
</div>
</div>
<div class="content">Content</div>
</div>
CSS:
html, body{
margin: 0;
padding: 0;
}
.site{
display: grid;
grid-template-rows: 1fr 9fr;
height: 100vh;
}
.navbar{
display: grid;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
background-color: green;
}
.navbar > div > *{
display: inline;
margin-right: 2rem;
margin-left: 2rem;
}
.navbar__area--left{
text-align: left;
}
.navbar__area--center{
text-align: center;
}
.navbar__area--right{
text-align: right;
}
I created three containers for each part, so I can align their contents separately. So far so good.
Now I added a test image to the left part and expected it to fit to the containers height. But it doesn't.
https://codepen.io/Nicolas_V/pen/XWbRYLR
What i don't understand is, that if I REMOVE the enclosing container from the left side, the image perfectly fits to the height of the navbar as expected previously.
https://codepen.io/Nicolas_V/pen/rNVmrNm
But I need to have this container, because for the right part I want multiple items in the container, all aligned to the right side.
I know, that I can set fixed heights for images and so on, but I want to dig into the grid system and I'm sure there is a way to solve my problem.
Related
currently I’m struggling with positioning these 3 text columns just like in picture. Each column contains 3 patagraphs.
Problem is, paragraph’s width is not equal, so grid-template-columns:repeat(3, 1fr) is not ideal solution because second and third paragraph will have unnecessary big white-space and that’s the problem when responsibility comes in. (Layout will break very soon because of that white-space).
I’ve tried min-content or max-content atributes but still I can’t figure it out, so it will look just as in the picture.
So goal is to align columns and paragraphs in it just like in the picture but without unwanted whitespace so work with responsibility will be easier.
Is there any better solution for it?
I have tried my best, here’s codepen
Thank you!
You can use minmax in your grid-template-column property, minmax(5rem, 10rem) minmax(3rem, 5rem) auto;, this will set the minimum width of the first column to 5rem and the maximum width to 10rem, the second to min of 3rem and max of 5rem, then the last columns width will be the width of its content => auto.
css-grid-layout-minmax ~ MDN
.card {
background: silver;
padding: 0 1rem;
border-radius: 12px;
}
.column {
display: grid;
grid-template-columns: minmax(5rem, 10rem) minmax(3rem, 5rem) auto;
justify-content: flex-start;
}
p:nth-of-type(3),
p:nth-of-type(4),
p:nth-of-type(2) {
text-align: right;
}
p + p {
margin-left: 1rem;
}
<div class="card">
<div class="column-wrapper">
<div class="column">
<p>lorem:</p>
<p>282726€</p>
<p>28%</p>
</div>
<div class="column">
<p>lorem ipsum:</p>
<p>287€</p>
<p>10%</p>
</div>
<div class="column">
<p>lorem:</p>
<p>19118€</p>
</div>
</div>
</div>
i have 3 div for navbar and using flexbox i want to keep my middle div at center no matter how much i put content at the right div or left div
:- right now the content inside left and right div is just text
but i want to put logo and other stuff
but the middle div keep moving as my right div keeps growing
here is the code
<div class="header__div">
<!-- Left Button -->
<div class="left__header">
a
</div>
<!-- Left Button End -->
<!-- middle button -->
<div class="middle__header">
a
</div>
<!-- middle button end -->
<!-- Right Logo -->
<div class="right__header">
a
</div>
<!-- Right Logo end -->
</div>
Flexbox is designed to have even spacing between it's children depending on how you justify the content. If one side is bigger the centre child will move to keep even spacing between the children.
If you want to ensure that the centre child is always in the centre, I would suggest using grid as this will ensure they have their own columns and they stick to them.
.header__div {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
Try doing this in CSS Grid:
.header__div{
display: grid;
grid-template-columns: repeat(3, 1fr);
}
One way to do this with flexbox is have 3 divs inside the header and give them all a flex value of 1 (You can change the proportions as you add content). Make the nested div in the center have "justify-content: center" and then you can place any other tags in the divs on the right and left of the center.
.header__div {
display: flex;
width: 100%
}
.div__1 {
flex: 1;
}
.div__2 { // Logo goes in this one
flex: 1;
justify-content: center;
align-items: center;
}
.div_3 {
flex: 1;
}
This question already has answers here:
Center one and right/left align other flexbox element
(11 answers)
Closed 2 years ago.
Right now I have
<p style="text-align: center">Hello world</p>
<p style="text-align: right">Hello world</p>
which gives me
Hello world
Hello world
I'd like them to be on the same line. I've tried using float such as
<div style="float: left">This is on the left </div><div style="float: right">This is on the right</div>
But they both end up on the left on top of each other
This is on the left
This is on the right
Is there a way to get them aligned where I want on the same line?
#dgknca you can use flex
.container {
display: flex;
justify-content: flex-end;
}
.item-center {
margin: auto;
}
<div class="container">
<div class="item-center">Item center</div>
<div>Item right</div>
</div>
You can use CSS Grid to divide a parent element evenly into columns and then flow content into each grid cell.
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.center {
text-align: center;
}
.right {
text-align: right;
}
<div class='grid'>
<p class='left'>This is on the left </p>
<p class='center'>This is in the center</p>
<p class='right'>This is on the right</p>
</div>
Following your first example, you have "center" and "right" so I'm inferring from that what you want, the rest of OP isn't quite clear to me.
The tricky part is actually having one be perfectly center, and one be on the right, and nothing on the left. Usually for stuff like this I'd use flexbox and put an extra container on the left to get the centering to work.
Here it is - just have your container be flex. Then set items to grow using 0 as basis (this is important so content width does not shift the centering and you get 3 equal width containers regardless of content). Then just wrap the one you want on the right in another div and justify-content: flex-end to get it on the right.
That's the best I know off the top - maybe some better ways...
body { display: flex; }
body div { display: flex; flex: 1 1 0 }
body .f-right { justify-content: flex-end }
/* center line/decoration */
.center-line {
position: absolute;
left: 50%;
transform: translateX(-50%);
height: 100%;
width: 1px;
background: blue;
opacity: .3
}
body { margin: 0 }
<div></div>
<p>Hai from center</p>
<div class="f-right">
<p>Hai from right</p>
</div>
<!-- just showing center -->
<div class="center-line"></div>
For this to work you have to put them both in the same p element. Using two separate p elements will cause them to be on different lines. The example code you gave works because both the left and right side are in the same block element. Separating them into two block elements will cause them to stack on each other.
Is there a way in Boostrap to make grid columns adjust according to the width of the viewport? I have the following page, where the first column is col-md-3 and the second col-md-9:
The right hand column is supposed to show a list of files when the user selects a folder in the left hand column. Yet the column widths stay fixed, and if I reduce the screen width just the tiny bit, the right-hand column is moved to below the left-hand column. The left hand column then fills the height and width of the screen, and the file list column is invisble below it, making for a very bad UX.
Is there some way, preferably in Bootstrap, to have the columns adjust their width in proportion to the screen width, or is there some alternative to Bootstrap with a grid that can work like that?
You can simply achieve this using css grid.
body{
margin:0;
}
.container{
display:grid;
grid-template: 100vh / repeat(12, 1fr);
color:#fff;
}
.container > div{
display: flex;
justify-content: center;
align-items:center;
font-size: 2em;
}
.left-panel{
grid-column: 1 / 4;
background: #F7A072;
}
.right-panel{
grid-column: 4 / -1;
background: #0FA3B1;
}
<body>
<div class="container">
<div class="left-panel">Left</div>
<div class="right-panel">Right</div>
</div>
</body>
I am making a fairly simple responsive website. I have a logo div that keeps the logo centered on small screens, and to the left on big screens. Everything is working how I want it to, (try resizing the jsfiddle) except that I want the logo div to scale down to it's min-width before the links wrap to the next line. I'm not sure how to word this, but I want the logo div to resize based on if the links are pushing it (if they have enough room). When it reaches it's min-width, then the links should wrap. Not sure if this is possible, but I figured I'd ask anyway.
Here is the jsfiddle.
The html:
<div class="header">
<div class="logo">logo</div>
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
The css:
.header {
text-align: center; /* Centers the logo text, and centers the links between the logo div and the other side of the page.*/
}
.logo {
max-width: 300px;
min-width: 100px;
width: 100%; /* It is always the min-width without this*/
background-color: red;
display: inline-block;
float: left;
}
.link {
display: inline-block;
background-color: green;
}
I hope I was clear, I'm still learning. Let me know if I need to add any more details.
I went looking some more and found flexboxes. Got them to do exactly what I wanted.
http://jsfiddle.net/3525C/10/
My new HTML:
<div class="header">
<div class="logo">logo</div>
<div class="nav">
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
</div>
and CSS:
.header {
text-align: center;
display: flex;
flex-flow: row wrap;
}
.logo {
flex: 1 0 auto;
min-width: 100px;
background-color: red;
}
.nav {
flex: 1 1 auto;
background-color: lightgray;
text-align: center;
}
.link {
display: inline-block;
background-color: green;
}
Thanks hexalys for helping me get it working.
The only real thing that responds the way you're talking is a table. Table cells have the capability of being flexible with their width.
You can use CSS to make this happen. It's a more modern display, so not all browsers (looking at you, older IE) will support it. But this should get you started: http://jsfiddle.net/mfvf8/
Here's what I added as a proof of concept:
.header
{
display: table;
width: 100%;
}
.header > div
{
display: table-cell;
}
.header .link
{
white-space: nowrap;
width: 1px;
}
I set the header to be displayed as a table, and gave it full width. I made all of the child divs act like a table cell. I made the links minimum width (1px) and said not to wrap whitespace. With regular divs, that would overflow. With table cells, that means it tries to be 1px wide but will expand to fit its content.
The rest of a table row's width will go evenly to whichever cells are left over that don't have a set width. In this case, it's the logo div. Then, as you shrink the window, it will slowly start to shrink the logo as needed.
You will need to tweak this to fit your design better. If you don't want your nav pushed all the way to the right like it is in the jsfiddle, you might need a "buffer" div to the far right, or different width settings, or a set max-width on the header div.