Bootstrap grid with variable width columns - html

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>

Related

Create a deliberately overflowing css grid

I'm trying to create a horizontally scrolling widget. Much like an image carousel but with text and icons instead.
It will have multiple columns, but only one will be visible at any one time. The rest will have overflow: hidden.
In order to make the columns equal size, I'm looking at css-grid. For example, this makes 3 equal width columns:
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow:column;
However, I wondered if there was a way to constrain the grid itself, to one column wide. so the grid would be one column wide and each column would of course be one column wide.
The result being on a 3 column layout, that 2 columns overflowed and they could be hidden.
Not sure whether this is possible without setting a "px" width on the grid itself.
Simply use 100%
.container {
display: grid;
grid-auto-columns: 100%;
grid-auto-flow: column;
height:100px;
overflow:auto;
}
.container > div {
background:red;
box-shadow:0 0 0 2px inset #000;
}
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
Related in case you want to deal with more columns and gaps: Responsive horizontal scrolling CSS Grid with fixed number of grid-items per breakpoint

how to make an image to fill 2 columns in an image grid

I am new to writing html and css code. I tried to make an image gallery with three column using CSS FlexBox
html:
<div class="row">
<div class="column">
<img src="sea.jpg">
<img src="guns.jpg">
</div>
<div class="column">
<img src="cars.jpg">
<img src="gg.png">
</div>
<div class="column">
<img src="games.jpg">
<img src="games.jpg">
</div>
</div>
css:
.row {
display: flex;
flex-wrap: wrap;
padding: 0 4px;
}
.column {
flex: 33.33%;
padding:10,10px;
}
.column img {
margin-top: 8px;
vertical-align: middle;
width: 100%;
}
The result of the code above is a normal three column image grid with pictures filled in each column. Is there any way to make the first image in the first row, first column span to first row, second column?
Pretty good for someone new to HTML/CSS! But you probably have never heard about CSS grid.
Flexbox is great for one-column or one-row organization, but lacks in multi-column/multi-row organization. That's where css grid comes in.
To make an object a grid, do
#container {
display: grid;
}
Then, we need to specify the amount of columns and rows. We can use the grid-template-rows and grid-template-columns properties for this. For every extra value you add, you add another row/column. For example, grid-template-columns: 20px 20px;' would generate two columns, each 20px wide. If you specify the width and height of the container, then you can set the value to auto (e.g. grid-template-columns: auto auto;, which creates two columns that are equal size and as wide as possible while still staying in the boundaries of the grid. The same applies for grid-template-rows. So lets assume, for now, you want a 100px by 100px 3x3 grid.
#container {
display: grid;
width: 100px;
height: 100px;
grid-template-rows: auto auto auto;
grid-template-columns: auto auto auto;
}
Great! Now we need to specify where we want the grid items to go. We use the grid-row and grid-column properties for this. Let's take a look at what it looks like.
#image-one {
grid-row: 1 / 2;
grid-column: 1 / 2;
}
So what do those numbers mean?
Well, when we created the 3x3 grid, the actually created 4 vertical lines and 4 horizontal lines. Draw out a 3x3 grid with borders if you are confused, you'll see 4 horizontal lines and 4 vertical lines.
So, the code is saying that the first image should be between horizontal grid lines 1 and 2 and between vertical grid lines 1 and 2. Going back to your drawing, this is the first box!
Now you can do this for every single image. Here's the second image:
#image-two {
grid-row: 1 / 2;
grid-column: 2 / 3;
}
This puts the image on the first row, second column. Remember, draw a picture if you get stuck! This is hard because we are describing visual instructions with text, so using a drawing to help translate is super helpful.
Also, the images do not have to take up a 1 by 1 space on the grid. For example, you could make a 2x2 image that starts at the very first box by doing...
#test-image {
grid-row: 1 / 3;
grid-column: 1 / 3;
}
...which puts the image between horizontal grid lines 1 and 3 and vertical grid lines 1 and 3, a.k.a. making a 2x2 box! Again, draw a diagram if you're confused.
Also, for further reading and helpful diagrams, check out https://css-tricks.com/snippets/css/complete-guide-grid/. They do a better job explaining than I ever could. Also, they have an excellent tutorial/review/documentation on flex-box, if you're curious: https://css-tricks.com/snippets/css/a-guide-to-flexbox/.
Good luck and happy coding! :)

Control size of images in nested grid layouts

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.

Alternating CSS Grid columns and mobile view

I am building a list of services for my website using CSS Grid. One of the rows in that overall website grid is broken into two CSS Grid columns.
In the first column of the first row, there is a description of a service. In the second column, there is an image that represents the service.
With each row, the description and image alternate, so on the second row, first column, there is an image, and in the second column, there is a description. Check out the attached image to see what I have working so far (note: I re-sized images to make it easier to take a screenshot).
The mobile version of the CSS Grid is a single column. When I display the same content in the mobile version, the layout no longer works. Since my layout is determined by the HTML content (probably a bad thing, I know), the titles will not always show up above the image, which is what I want. See attached to see the issue.
I believe the answer to solving this problem lies in using flex-direction: row-reverse; however, it is quite hard to come across some good examples (maybe I am just searching the wrong way). The best Codepen I could find does what I want using flex-direction, but it does not nicely place the description in one CSS Grid box and the image in another CSS Grid box, so when resizing the browser, the images overlap the text.. that is probably due to my lack of knowledge using Flexbox (still learning).
Could you help me figure out how to properly create an alternating 2-column list of items that also displays the text and image properly when in a 1-column list?
I would prefer to stay within the CSS Grid/Flexbox/no script world, but I am happy to entertain other ideas.
Thank you very much for any help you can provide!
HTML
<!-- Services area -->
<div class="services-area">
<div class="services-text">
<h3>This is service 1</h3>
</div>
<div class="services-div">
<img class="services-image" src="images/home/home-agile-transformation.png" alt="Agile transformation image.">
</div>
<div class="services-div">
<img class="services-image" src="images/home/home-agile-coaching.png" alt="Agile transformation image.">
</div>
<div class="services-text">
<h3>This is service 2</h3>
</div>
<div class="services-text">
<h3>This is service 3</h3>
</div>
<div class="services-div">
<img class="services-image" src="images/home/home-agile-sw-implementation.png" alt="Agile transformation image.">
</div>
</div>
CSS
// layout for services
// display a stacked grid <767 pixels
.services-area {
grid-area: svcs;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
#if $debug { background-color: $debugServicesArea; }
}
// display a 2-column grid >768
#include for-size(full-size) {
.services-area {
grid-area: svcs;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
margin-left: $gridMarginLeft;
margin-right: $gridMarginRight;
#if $debug { background-color: $debugServicesArea; }
}
}
.services-text {
display: grid;
align-items: center;
justify-content: center;
}
.services-image {
max-width: 100%;
height: auto;
}
For accessibility concerns and better SEO keep the markup in the logical order (title, image).
On mobile, you do not need a grid at all, use display:block for the container. Use grid-auto-flow: row dense to fill the grid as densely as possible following the row order. This ensure no grid cell will be empty.
Then alternate the title elements by specifying the column they need to start from. You can use the :nth-child() sibling selector to pick the titles, starting from the 3rd and then every 4 (4n - 1 means 4 * 0 - 1 = -1 (invalid sibling, skipping); 4 * 1 - 1 = 3; 4 * 2 - 1 = 7; ...).
/* display a stacked grid <767 pixels */
.services-area {
display: block;
}
/* display a 2-column grid >768 */
#media (min-width: 768px) {
.services-area {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
justify-content: center;
grid-auto-flow: row dense;
}
}
.services-area > :nth-child(4n - 1) {
grid-column-start: 2;
}
.services-image {
max-width: 100%;
height: auto;
}
This helped me:
For example, if you want to reverse the columns on screen lower than 1200px, then in your parent div, use this instead
#media (max-width:1200px) {
.services-area {
display: flex;
flex-flow: column-reverse;
}
}

Responsive grid with fixed column width

I guess I have the simplest problem ever and cannot find a ready solution.
I need to make a grid with fixed widths and fixed distance between them.
I need x columns a 400px (x = total width/400), and during browser resizing I would need this grid to shrink, column by column (columns must always keep their width size and distance between them).
The content flows over all columns and should spread out over all columns.
That's why I don't like any open source grid system (Boostrap, Skeleton, etc.) they all use %width, and columns always change width on resizing.
What would be the simplest way?
Edit/Clarification:
This is how it looks without columns: http://jsfiddle.net/xjrt8qrm/16/show/
<div>See the fiddle</div>
I want it to have x columns. x is the maximum possible amount of 400px columns, depending on the users resolution. I want only one row of columns, so the content spreads like on a newspaper from top to bottom.
So it will look somehow like this on a PC: http://i.imgur.com/kmd620p.png (You can ignore the text/comments there).
It's pretty simple. The container holds the contents together. Float left will cause them to line up left to right. When the container runs out of space to hold them, they'll drop from the right to a row below one at a time. The clear div clears out the float so that it doesn't propagate to other nearby classes. Obviously, you'll have to handle padding, margins, etc as your style dictates.
If you needed newspaper like vertical layout, you could try a solution like this one
You could use media queries in this manner or even overflow:none to hide columns that didn't fit if that was your desired behavior.
Here's a simple solution:
HTML:
<div class="container">
<div class="fourhundred">
Div 1
</div>
<div class="fourhundred">
Div 2
</div>
<div class="fourhundred">
Div 3
</div>
<div class="clear"></div>
</div>
CSS:
.fourhundred {
width: 400px;
margin: 10px;
float: left;
}
.clear { clear:left }
.container { width: 100% }
This is why flexbox have been designed. Add to your container:
.container {
display: flex;
justify-content: space-between;
align-content: space-between;
width:100%;
}
as in this Fiddle
Simply used width: calc(100% / 3); you can use any value instead of 3. Divided the whole width into 3.
here is the Fiddle Demo
<div id = "main">
<div id ="sub">One
</div>
<div id ="sub">Two
</div>
<div id ="sub">Three
</div>
</div>
CSS Part
#main{
border: 2px solid black;
height:100px;
width:100%;
position: relative;
display:flex;
}
#sub{
border:1px solid red;
width: calc(100% / 3);
height: calc(100% - 40px);
padding:10px;
margin : 5px;
display:inline-block;
}