TL;DR: Is there anything like table-layout: fixed for CSS grids?
I tried to create a year-view calendar with a big 4x3 grid for the months and therein nested 7x6 grids for the days.
The calendar should fill the page, so the year grid container gets a width and height of 100% each.
.year-grid {
width: 100%;
height: 100%;
display: grid;
grid-template: repeat(3, 1fr) / repeat(4, 1fr);
}
.month-grid {
display: grid;
grid-template: repeat(6, 1fr) / repeat(7, 1fr);
}
Here's a working example: https://codepen.io/loilo/full/ryXLpO/
For simplicity, every month in that pen there has 31 days and starts on a Monday.
I also chose a ridiculously small font size to demonstrate the problem:
Grid items (= day cells) are pretty condensed as there are several hundreds of them on the page. And as soon as the day number labels become too large (feel free to play around with the font size in the pen using the buttons on the upper left) the grid will just grow in size and exceed the page's body size.
Is there any way to prevent this behaviour?
I initially declared my year grid to be 100% in width and height so that's probably the point to start at, but I couldn't find any grid-related CSS properties that would've fitted that need.
Disclaimer: I'm aware that there are pretty easy ways to style that calendar just without using CSS Grid Layout. However, this question is more about the general knowledge on the topic than solving the concrete example.
By default, a grid item cannot be smaller than the size of its content.
Grid items have an initial size of min-width: auto and min-height: auto.
You can override this behavior by setting grid items to min-width: 0, min-height: 0 or overflow with any value other than visible.
From the spec:
6.6. Automatic Minimum Size of Grid
Items
To provide a more reasonable default minimum size for grid items, this
specification defines that the auto value of min-width / min-height also applies an automatic minimum size in the specified axis to grid items whose overflow is visible. (The effect is analogous to the automatic minimum size imposed on flex items.)
Here's a more detailed explanation covering flex items, but it applies to grid items, as well:
Why don't flex items shrink past content size?
This post also covers potential problems with nested containers and known rendering differences among major browsers.
To fix your layout, make these adjustments to your code:
.month-grid {
display: grid;
grid-template: repeat(6, 1fr) / repeat(7, 1fr);
background: #fff;
grid-gap: 2px;
min-height: 0; /* NEW */
min-width: 0; /* NEW; needed for Firefox */
}
.day-item {
padding: 10px;
background: #DFE7E7;
overflow: hidden; /* NEW */
min-width: 0; /* NEW; needed for Firefox */
}
jsFiddle demo
1fr vs minmax(0, 1fr)
The solution above operates at the grid item level. For a container level solution, see this post:
Who does minmax(0, 1fr) work for long elements while 1fr doesn't?
The previous answer is pretty good, but I also wanted to mention that there is a fixed layout equivalent for grids, you just need to write minmax(0, 1fr) instead of 1fr as your track size.
The existing answers solve most cases. However, I ran into a case where I needed the content of the grid-cell to be overflow: visible. I solved it by absolutely positioning within a wrapper (not ideal, but the best I know), like this:
.month-grid {
display: grid;
grid-template: repeat(6, 1fr) / repeat(7, 1fr);
background: #fff;
grid-gap: 2px;
}
.day-item-wrapper {
position: relative;
}
.day-item {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 10px;
background: rgba(0,0,0,0.1);
}
https://codepen.io/bjnsn/pen/vYYVPZv
Related
how do I display the css grid guides, I want to color each column with an overlay color, I saw the source here https://github.com/UseAllFive/css-grid-guides
how to use in plain HTML/CSS/JS
Show grid guide overlay like this
this is my code :
.grid-12 {
width: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 1.5rem;
}
if you want to learn css grid, I recommend that you use mozilla firefox because in the devtools there is a grid, which can display grid lines that can help in learning grids
or you can see my repo, i use css grid
css grid
To describe my issue, I will start from the roots to explain what I am trying to do, and why I decided to use Grid Box for this, let's start off with two wireframes:
My layout is built up from two containers; the body and the sidebar. Don't think of it as this is the whole website, this is just a component.
The sidebar contains two elements, notes and chat.
Notes & chat elements can be mini-sized, but once it is mini-sized, the second part of the left body container will get wide and take the place that the sidebar used to take at it's bottom space, like in the example below:
So after researching a bit I couldn't find any other solution besides having 2 different components for the second-data part that needs to get wider, or just use a Grid Box, however, I must animate the side bar and the second part of the data with a transition of it's width changing.
There is an angular POC example I have created with Grid Box to achieve what I need without animation:
https://stackblitz.com/edit/angular-ivy-7tucsx?file=src/app/app.component.html
Is it possible to achieve this animation with grid box by just adding the .closed class to my .container like in the example POC?
There is a CSS only solution that can help you.
In the snippet, hover the container to make the bottom div expand.
The trick is to use a 3 column grid, and an auxiliar element that grows / shrinks:
In production , the trick element would have an height of 0, and be invisible.
.container {
display: grid;
border: solid 1px red;
grid-template-columns: 1fr auto auto;
grid-template-rows: 100px 100px 10px;
transition: all 3s;
width: 500px;
}
#right {
background-color: yellow;
width: 200px;
grid-column: 2 / span 2;
}
#bottom {
background-color: lightgreen;
grid-column: span 2;
}
#trick {
background-color: tomato;
grid-column: 2 / 3;
width: 0px;
transition: width 3s;
}
.container:hover #trick {
width: 200px;
}
<div class="container">
<div id="left">L</div>
<div id="right">R</div>
<div id="bottom">B</div>
<div id="trick">T</div>
</div>
The idea is to use animations provided by angular. So you need to add following in app.module.ts:
imports:
[
BrowserAnimationsModule,
BrowserModule
]
Add the animations to that #component decorative:
animations: [
trigger('<animationName>' [<definitions>])
]
In html, apply animation to required div:
<div [<#animationName>] = '<state-definitions-name>'></div>
[UPDATED]
The above is abstract code. For detailed code, I'm attaching my stackblitz code: https://stackblitz.com/edit/angular-ivy-zs1x59
Change height, width respectively as required in #component's animations
I am looking at the cdk-virtual-scroll and hoping I can use this in my existing application, where I have a view containing items, who's width varies depending on screen size (eg phone vs tablet etc)
Forking this example, I have a modified version here.
My modifications are on App/cdk-virtual-scroll-overview-example.css, where I have changed the css to contain the following..
.example-viewport {
height: 200px;
width: 90%;
border: 1px solid black;
display: flex;
flex-direction: row;
flex-wrap: wrap
}
.example-item {
height: 50px;
background: red;
margin:0.5px;
width: 33%
}
#media screen and (min-width: 360px) {
.example-item {
width: 45%
}
}
So my aim here is have the items showing either 2 or 3 a row depending on the screen size. However, as can be seen, they do not seems to wrap at all...
I have used flex here (have I done this wrong?), but any css to get it working will do (perhaps flex grid, or other)
Is this possible using the cdk-virtual-scroll?
Thanks in advance
You could workaround it by chunking your items according to the number you want per row and then within the virtual scroll add ngFor to iterate each chunk. Then you can display flex on chunk div.
I'm trying to create a horizontal layout of fixed height, inline-block elements that contain CSS columns in it.
article {
-webkit-column-width: 200px;
-moz-column-width: 200px;
column-width: 200px;
-webkit-column-gap: 1em;
-moz-column-gap: 1em;
column-gap: 1em;
-moz-column-fill: auto;
column-fill: auto;
height: 350px;
display: inline-block;
}
The problem is that the width of inline-block elements is improperly set (columns take up less/more space than container provides) - it seems that the width corresponds to the content before it is being transformed into columns (in Chrome - in result containers are on top of each other) or fits single column (in Firefox and IE - in result containers overlap).
Example (inspect the width of article element):
http://codepen.io/anon/pen/yNQdVE
The only solution I came up with is to make container fit single column and use JS to set width to the scroll width. Is seems to work fine in all 3 browsers I tested.
Example:
http://codepen.io/anon/pen/gpQNWg
Is there any pure CSS solution to this problem?
Changing the display from inline-block to table-cell seems to give you desired results.
Seen in this pen is that style applied along with borders for visual aid.
http://codepen.io/TheLarkInn/pen/jPQjzK
It appears that although it is an inline-block element, that the browser assumes the second column stretches the width of the viewport despite having a width of 300px per column.
You can also wrap all the articles in an element using display: flex; also.
There are a lot of dynamically designed websites out there where there divs or images shrink as the browser size decreases.
An example of this would be http://en.wikipedia.org/wiki/Main_Page
The div in which the text is in shrink as the browser size decreases. This happens up until a certain point, where it just decides to stop shrinking, and just start to cover the text boxes.
I would like to do this effect with a JSFiddle I am working on:
http://jsfiddle.net/MrLister/JwGuR/10/
If you stretch the size of the fiddle, you will see the pictures dynamically adapt.
The goal is to make it just stop shrinking at a certain point, and just start covering or caving in on this pictures. I want to do this because eventually it gets so small that they text on each image overlaps and it looks bad.
Here is the CSS for the Fiddle:
.figure {
position: relative;
display:inline-block;
max-width: 33%;
}
.figure .figcaption {
text-align: center;
height:0;
top: 40%;
width: 100%;
font-size: 55px;
color: white;
position: absolute;
z-index: 1;
}
.figure img {
display: block;
max-width: 100%;
}
Simply add a min-width size to the things you want to stop shrinking :)
Like so:
.figure {
position: relative;
display: inline-block;
max-width: 33%;
min-width: 150px;
}
Here's an updated fiddle: http://jsfiddle.net/jakelauer/JwGuR/13/
min-width:500px;
would cause the window to have a minimum width of 500px.
http://jsfiddle.net/JwGuR/14/ after you reach 500px the images stop resizing.
Here is an example of media queries. You use css to define min and max widths for certain cases. In your case, just give a max-width case and set the css properties there.
http://css-tricks.com/css-media-queries/
img{
width:100%;
}
#media all and (max-width: 699px) {
img{
width:500px;
}
}
This is a basic example. As Jake said, you can also just give it a min-width but in many cases, the layout of the page should change for mobile or tablet view where simply defining a min-width won't suffice