Images in CSS Grid - css

I can't figure out how to go about resizing images within CSS Grid.
I don't mind if the image is clipped at all but I would like my aside item to resize the image so that it shrinks/grows to fill the item as best as possible as the webpage is resized.
The grid layout is adjusting with #media (min-width: 600px) { /* tablet */ and #media (min-width: 1600px) { /* desktop */.
HTML:
<body>
<div class="container">
<header>
Home
Getting Started
Tracks
Contact Us
</header>
<main>Content</main>
<advert>Advert</advert>
<aside>
<img src="https://jagrotax.co.uk/wp-content/uploads/2013/01/mojo-tyres-rotax-max.jpg" alt="Mojo Kart Tyre list">
</aside>
<footer>Maximilian Crosby ©</footer>
</div>
</body>
CSS:
.container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 8% 10% 70% 10% 2%;
grid-gap: 10px;
grid-template-areas: /* mobile */
"header"
"advert"
"main"
"aside"
"footer";
font-family: 'Comfortaa', cursive;
min-height: 1000px;
background: #BCF9FF;
text-align: center;
}
header {
background: #A6CFFF;
grid-area: header;
display: flex;
flex-wrap: wrap;
font-size: 26px;
justify-content: space-evenly;
align-items: center;
padding: 0px 40px 0px;
}
main {
background: #A6CFFF;
grid-area: main;
}
advert {
background: #A6CFFF;
grid-area: advert;
}
aside {
background: #A6CFFF;
grid-area: aside;
}
footer {
grid-area: footer;
}

you only need to add this to your css:
aside img {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
The Img inside your aside need to use 100% of the space (inside the aside area) that's why you need the width and the height to be 100%. Also by using the object-fit: cover, the img will preserve the aspect ratio.
Here is a fiddle:
https://jsfiddle.net/cisco336/n5dzte8m/

Related

how can i make dynamic layout using media query?

I've been trying to make a few layouts for specific sizes.
As shown in the picture above, I tried to create two layouts, PC and mobile.
Making a PC was easy. SectionA and SectionB were configured through the flex layout, and SectionC was configured below it.
The problem was with Mobile. SectionA and SectionB are tied together in a flex layout, so I couldn't think of a way to put SectionC between A and B.
This is because, in the html structure, sectionC already exists below. Is it possible to configure only with CSS without using Javascript?
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
/*only for ilustration*/
background-color: #d7d7d7;
}
.bottom {
display: flex;
flex-direction: row;
/*only for ilustration*/
background-color: #ffd5d5;
}
#media screen and (max-width: 760px) {
.header {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.bottom {
flex-direction: column;
border: none;
}
}
<div>
<div class="header">
<div>
SectionA
</div>
<div>
SectionB
</div>
</div>
<div class="bottom">
SectionC
</div>
</div>
I have just made a change in your HTML.
So I wrapped all div inside of .header.
Then, to give 50% width for first to direct child I have just added class .hlalf and set this class CSS to flex:1 0 50%, which means take 50% width of flexbox.
Now to achieve bottom div in center in responsive we use order property of flexbox. and for that I have just added class to all 3 div according to their order. I have used sm keyword just for understanding as small screens.
#media screen and (max-width: 560px) {
.order-sm-1 {
order: 1;
}
.order-sm-2 {
order: 2;
}
.order-sm-3 {
order: 3;
}
}
.header {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.header>div {
flex: 1;
}
.header>div.half {
/*This css tells all the direct div of header class to take 50% of the space*/
flex: 1 0 50%;
}
.bggreen {
background: green;
}
.bgblue {
background: blue;
}
.bottom {
background-color: #ffd5d5;
}
#media screen and (max-width: 760px) {
/*This will change flex-direction to column which is by default row*/
.header {
flex-direction: column;
}
.order-sm-1 {
order: 1;
}
.order-sm-2 {
order: 2;
}
.order-sm-3 {
order: 3;
}
}
<div>
<div class="header">
<div class="bggreen half order-sm-1">
SectionA
</div>
<div class="bgblue half order-sm-3">
SectionB
</div>
<div class="bottom order-sm-2">
SectionC
</div>
</div>
You can wrap all your section in a flex container and play with the flex-order properties
I'm late to the party with this one but Grid's the way to go in my opinion as you get complete control over where you put items. It's much more versatile than flexbox but it is a steep learning curve initially as there are so many options. Kevin Powell has a good introductory video to grid and this is also a good, clearly-written resource from css tricks.
.container {
display: grid;
grid-template-columns: 3fr 1fr;
grid-template-areas: "a b" "c c";
border: 2px solid #285DBB;
row-gap: 0.25rem;
column-gap: 2rem;
padding: 0.35rem;
}
.container>div {
background-color: #92D050;
color: white;
display: grid;
place-content: center;
padding: 0.75rem 2rem;
}
.zoneA {
grid-area: a;
text-decoration: underline wavy red;
}
.zoneB {
grid-area: b;
}
.zoneC {
grid-area: c;
}
.footer {
margin-top: 1.5rem;
font-size: 1.25rem;
text-align: center;
}
.mobile {
display: none;
}
.pc {
display: block;
}
#media only screen and (max-width:760px) {
.container {
grid-template-columns: 1fr;
grid-template-rows: 1fr 3fr 1fr;
grid-template-areas: "a" "c" "b";
}
.mobile {
display: block;
}
.pc {
display: none;
}
.zoneB {
text-decoration: underline wavy red;
}
.zoneC {
text-decoration: underline wavy red;
}
}
<div class="container">
<div class="zoneA">
SectionA
</div>
<div class="zoneB">
SectionB
</div>
<div class="zoneC">
SectionC
</div>
</div>
<div class="pc footer">PC</div>
<div class="mobile footer">Mobile</div>
<meta content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>

Css-Grid / Flexbox aside and main not growing 100%

I am creating a css-grid / flexbox template and it's all working as it should.
It has a header, aside, main and footer.
I just need the asign and main row to stretch so it takes the whole page minus the header and footer height.
I want to do this without having to use the "vh"
Here is the full current code:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 30% auto;
grid-template-rows: auto 1fr auto;
grid-template-areas: "header header"
"sidebar main"
"footer footer"
}
header,
aside,
main,
footer {
padding: 16px;
text-align: center;
}
header {
background: purple;
grid-area: header;
}
aside {
background: blue;
grid-area: sidebar;
}
main {
background: green;
grid-area: main;
}
footer {
background: orange;
grid-area: footer;
}
How can I get the asign and main to auto stretch?
You can use :root{} for that and calc() with variables to calculate the height. Sorry for re-coding your attempt, but I think it was better to start from zero to show you a new approach.
Try the following snippet
* {box-sizing: border-box;padding: 0;margin: 0}
:root{
--nav-height: 80px;
--footer-height: 80px;
}
.grid-container{
display: grid;
grid-template-columns: 30% 70%;
height:calc(100vh - var(--nav-height) - var(--footer-height));
}
.grid-item{
border:1px solid black;
padding:10px;
}
.nav{
width:100%;
height:var(--nav-height);
border:1px solid black;
padding:10px;
}
footer{
width:100%;
height:var(--footer-height);
border:1px solid black;
padding:10px;
}
<body>
<div class="nav">nav content</div>
<div class="grid-container">
<div class="grid-item">body content one</div>
<div class="grid-item">body content two</div>
</div>
<footer>footer content</footer>
</body>
In order to make it the correct browser height, the view height (vh) property would be required.
You could alternatively use a fixed pixel height, or make it relative to the width for a specific aspect ratio, but neither of these would be responsive to 100% browser height.
Is there any reason you don't want to use vh?
One way to do it strictly with flex-box would be to wrap both the aside and main in a div, and set flex property of the div to 1
<div class="container">
<aside>aside</aside>
<main>main</main>
</div>
.container {
display: flex;
flex: 1;
}
but in order for that to work you would probably have to make the entire body a flex-box
body {
display: flex;
flex-direction: column;
}

How do you adjust image size to its container with css?

I have a logo on my website which lies in a specific grid-area.
I want it to be responsive in size and to maximum the respective grid-area.
I tried it with the following css, but it doesn't work:
.logo {
grid-area: im;
text-align: center;
}
.logo-img {
max-width: 50%;
height: auto;
position: relative;
}
Here is a link to the GitHub file: https://github.com/toniFET/WXApp.git
print screen of website
Use a background image:
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
}
.grid > div {
border: solid 1px #333;
min-height:200px;
}
.grid > div.img{
background-image:url(https://placekitten.com/200/200);
background-size:cover;
background-position:center center;
}
<div class='grid'>
<div class='img'></div>
<div></div>
<div></div>
<div></div>
</div>

Responsive design with CSS Grids

I'd like to have responsive version to this code.
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"navigation-bar content content content";
margin: 0; padding: 0;
}
.navigation-bar {
grid-area: navigation-bar;
height: 100vh;
background-color: #1a1b20;
}
.content {
grid-area: content;
background-color: #202127;
}
<body>
<div class="navigation-bar"></div>
<div class="content"></div>
</body>
What I have:
#media only screen and (max-width: 600px) {
body {
}
.navigation-bar {
}
.content {
}
}
I'd like to have navigation-bar on the top of the website and content below it.
It means:
grid-template-columns should be 1fr
height of navigation-bar should be about 25vh
But I don't know, what grid-template-rows should be.
It depends on content, but if there is no content in content, it should fill whole screen (navigation-bar and content is a rest).
May you help me with responsive desige, please?
EDIT:
On mobile phone:
I would write the base styles using columnar flex and then a use grid when the screen is larger than 600px. Note that in mobile, .content uses flex-grow: 1, which means it will fill all the remaining vertical space.
.navigation-bar {
height: 15vh;
background-color: #1a1b20;
}
.content {
flex-grow: 1;
background-color: #202127;
}
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
color: white;
}
#media only screen and (min-width: 600px) {
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"navigation-bar content content content";
}
.navigation-bar {
grid-area: navigation-bar;
height: 100vh;
}
.content {
grid-area: content;
}
}
<div class="navigation-bar">navbar</div>
<div class="content">content</div>
jsFiddle

How can I set the width and max-width of a CSS Grid Column?

Is it possible to limit the width of a CSS grid column?
body {
margin: 0;
padding: 0;
}
.container {
display: grid;
grid-template-columns: minmax(17.5%, 250px) minmax(31.25%, 480px) auto;
grid-template-rows: 100vh;
grid-gap: 0;
}
.menu {
padding-top: 32px;
background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}
.list-view {
background-color: #F5F5FC;
}
<div class="container">
<div class="menu"></div>
<div class="list-view"></div>
<div class="details"></div>
</div>
In the example above it always uses 17.5% width for the menu because:
"If max is smaller than min, then max is ignored and the function is
treated as min."
source: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
What I want is a menu that is 17.5% width with a max of 250px. Is that possible?
One way to do this might be declare:
.container {grid-template-columns: 250px 480px auto;}
as your standard rule.
Then, after considering the narrowest width you would like to apply to your third column, you can apply a #media query.
Let's say you want to ensure your third column is no narrower than 100px.
250px + 480px + 100px = 830px
So you need to write a #media query for 830px:
#media only screen and (max-width: 830px) {
.container {grid-template-columns: 17.5% 31.25% auto;}
}
Working Example:
body {
margin: 0;
padding: 0;
}
.container {
display: grid;
grid-template-columns: 250px 480px auto;
grid-template-rows: 100vh;
grid-gap: 0;
}
.menu {
padding-top: 32px;
background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}
.list-view {
background-color: #F5F5FC;
}
#media only screen and (max-width: 830px) {
.container {grid-template-columns: 17.5% 31.25% auto;}
}
<div class="container">
<div class="menu"></div>
<div class="list-view"></div>
<div class="details"></div>
</div>
You want your column to have a standard width of 17.5%, and a maximum width of 250px.
You can't use grid-template-columns because the minmax() function computes to min anytime max is less than min. This means that 17.5% will override 250px on wider screens.
A clean workaround would be to set grid-template-columns to min-content, which shrink-wraps the column to the length of the content. Then set the width parameters on the grid item.
.container {
display: grid;
grid-template-columns: min-content minmax(31.25%, 480px) auto;
}
.menu {
width: 17.5%;
max-width: 250px;
}
However, the percentage length on the grid item doesn't work in this scenario because the parent reference (the column) is essentially set to a zero width (min-content). (fiddle demo).
Fortunately, in this case, because your container is set to the width of the viewport, you can easily overcome this problem with vw units instead.
.menu {
width: 17.5vw;
max-width: 250px;
}
.container {
display: grid;
grid-template-columns: min-content minmax(31.25%, 480px) auto;
grid-template-rows: 100vh;
grid-gap: 0;
}
.menu {
width: 17.5vw;
max-width: 250px;
padding-top: 32px;
background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}
.list-view {
background-color: #F5F5FC;
}
body {
margin: 0;
padding: 0;
}
<div class="container">
<div class="menu"></div>
<div class="list-view"></div>
<div class="details"></div>
</div>
jsFiddle demo
Am not sure if its feasible in this way, but an alternative is to use flexbox instead of CSS grid and you can easily achieve this:
body {
margin: 0;
padding: 0;
}
.container {
display: flex;
height: 100vh;
}
.menu {
width: 17.5%;
max-width: 250px;
padding-top: 32px;
background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}
.list-view {
width: 32.25%;
max-width: 480px;
background-color: #F5F5FC;
}
.details {
flex: 1;
}
<div class="container">
<div class="menu"></div>
<div class="list-view"></div>
<div class="details"></div>
</div>

Resources