How to properly use media query to achieve this result? - css

I want to build a responsive webpage using Angular 6.I tried to do so using bootstrap but failed miserably.So ultimately I decided to go with media query.
This is my code:
.width {
width: 300px;
height: 300px;
display: inline-block;
border: 1px solid blue;
}
.width1 {
width: 800px;
height: 300px;
border: 1px solid blue;
display: inline-block;
}
#media only screen and (max-width: 600px) {
.width {
background-color: black;
width: 200px;
height: 100px;
}
.width1 {
width: 500px;
}
}
<div class="container-fluid ">
<div class="row">
<div class="badge width col-md-offset-1 col-lg-offset-1 col-xl-offset-1">
Hello I am in component 1.
</div>
<div class="badge width col-md-offset-1 col-lg-offset-1 col-xl-offset-1">
Hello I am in component2.
</div>
<div class="badge width col-md-offset-1 col-lg-offset-1 col-xl-offset-1">
Hello I am in component3.
</div>
</div>
<br>
<br>
<br>
<div class="row">
<div class="badge width col-md-offset-1 col-lg-offset-1 col-xl-offset-1">
Hello I am in component 4.
</div>
<div class="badge width1 col-md-offset-1 col-lg-offset-1 col-xl-offset-1">
Hello I am in component 5.
</div>
</div>
</div>
The result that I am getting for a medium screen is given below and this is the result that I want:
However the problem arises , when I try to increase my browser resolution using 'CTRL +' . The orientation of the boxes gets jumbled up.But I want my result to look the same as it did in the medium settings.
The following is a screenshot of the result on larger screens.
How do I fix this?

I think what you need to do is better achieved using CSS Grid, it will allow you to build the layout with few rules and basically no media queries (if you intend the layout to be exactly the same all the time)... look at this:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(200px, auto);
grid-gap: 20px;
}
.grid-item {
border: 1px solid;
}
.item5 {
grid-column: span 2;
}
section {
background-color: blue;
height: 100%;
color: #FFF;
}
<div class="grid-container">
<div class="grid-item item1">
<section>
Inner Section
</section>
</div>
<div class="grid-item item2">Item 2</div>
<div class="grid-item item3">Item 3</div>
<div class="grid-item item4">Item 4</div>
<div class="grid-item item5">Item 5</div>
</div>

I think the problem you're running into is using Ctrl + in the hopes of increasing your browser width. Ctrl + is just meant to enlarge text for accessibility reasons.
To effectively manage browser/viewport width in Chrome, right click your page, select Inspect. With the Inspect pane open, your browser window will now have the width x height in the top right of the page.
As for your code, I'm not able to reproduce the result in the first image you sent (it has obviously different CSS than in the provided snippet).
To make this work as you are wanting, I would suggest looking into Flexbox, it's relatively new and pretty powerful so definitely worth learning.

Related

How can I have auto-width content in flexbox without destroying the layout? (take as much space as necessary and as little space as possible)

I have an example on JSFiddle on how I want to solve my issue with flexbox: I want the left column to fit the width accordingly to the content - break a line if the text is too long. Unfortunately it always takes as little space as possible, which results in breaking the layout.
I have a fiddle below, first you see two blocks with how it looks now, below you see 2 blocks how I want it to look like (I've defined fixed width for visual reasons, but I want it to be dynamically with flexbox, obviously).
I'm pretty sure I can do this easily but I can't see the wood for the trees. Any kind of help is highly appreciated :)
.flex {
display: flex;
background: #333;
max-width: 380px;
}
.first {
flex: 0;
background: #666;
}
.second {
flex: 1;
background: #999;
}
<p>How it looks like with my flexbox approach</p>
<div class="flex">
<div class="first">
Here is my Dynamic Text
</div>
<div class="second">
Next to Text
</div>
</div>
<br />
<div class="flex">
<div class="first">
Here is my Dynamic Text Here is my Dynamic Text
</div>
<div class="second">
Next to Text
</div>
</div>
<hr />
<p>How it should look like</p>
<!-- Ignore all code below, please - everything below is just here for visual reasons -->
<div>
<div style="background: #666; width: 165px; float: left;">Here is my Dynamic Text</div>
<div style="background: #999; float: left;">Next to text</div>
</div>
<div style="clear: both; height: 10px;">
</div>
<div>
<div style="background: #666; width: 302px; float: left;">Here is my Dynamic Text Here is my Dynamic Text</div>
<div style="background: #999;float: left; height: 36px;">Next to text</div>
</div>
Use white-space:nowrap on the second element so it does not collapse.
.flex {
display: flex;
border: 1px solid green;
}
.first {
background: lightblue;
border: 1px solid grey;
}
.second {
white-space: nowrap;
background: lightgreen
}
.narrow {
width: 50%;
<div class="flex">
<div class="first">
Here is my Dynamic Text
</div>
<div class="second">
Next to Text
</div>
</div>
<hr/>
<div class="flex narrow">
<div class="first">
Here is my Dynamic Text Here is my Dynamic Text
</div>
<div class="second">
Next to Text
</div>
</div>

Add a rule between CSS grid columns and rows

Is there a css grid property to add a rule (vertical line) between grid columns, and a rule (horizontal line) between grid rows, in the same way, or similar, that column-rule works?
Is there a css grid property to add a rule (vertical line) between grid columns, and a rule (horizontal line) between grid rows, in the same way, or similar, that column-rule works?
NO
There is no such property.
CSS Grid rows and columns are entirely virtual and only indicate the start and end point of their respective areas for the browser's layout engine.
Another option is to think about the background colors of both your grid and your grid cells. If you can color the background of the grid and apply a neutral white to your elements, the grid background will bleed through the grid-gap. This effectively gets you grid rules.
Example:
.grid-container {
background-color: #111; /* color of the line between cells */
display: grid;
grid-gap: 1px; /* size of the line between cells */
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: minmax(min-content, max-content);
padding: 1px; /* size of the line around the grid */
}
.grid-item {
background-color: #fff; /* cells need a bg color for this to work */
min-height: 100px;
}
<section class="grid-container">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</section>
Downside is that you still need to do a lot of manual padding adjustments around the grid depending on your content and, if you have a grid with weird amounts of content, the background will bleed through.
But, for simple grids, this works more often than I think it should.
As #Paulie_D said, no there isn't. You would have to do something as hideous as this to get something even close it it - you can't even use grid-gap if you do this:
#grid{
display: inline-grid;
grid-template-rows: auto 2px auto 2px auto;
grid-template-columns: auto 2px auto 2px auto;
}
.item{
width: 5rem;
height: 5rem;
background: red;
}
.rule{
background:black;
}
<div id="grid">
<div class="item"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="item"></div>
<div class="rule"></div>
<div class="item"></div>
</div>
Another option you could do would be to target a specific div and designate that as your horizontal rule column by having it span multiple columns.
.wrapper {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
}
.wrapper>div {
background-color: #eee;
padding: 1em;
}
.fullRow {
grid-column: 1/ 4;
}
<div class="wrapper">
<div>
first column
</div>
<div>
second column
</div>
<div>
third column
</div>
<div class="fullRow">
<hr>
</div>
<div>
first column
</div>
<div>
second column
</div>
<div>
third column
</div>
<div class="fullRow">
<hr>
</div>
</div>
No pure grid-* way to do it but you can put borders on the child divs, just don't use grid-column-gap (padding instead). Showing some nth-child cleanups for inside-only rules, and some custom per-column text alignment.
.container {
display: grid;
grid-template-columns:
.15fr
.20fr
.05fr
.15fr
.08fr
.1fr
.20fr;
/*grid-column-gap: 0*/
}
.container>div {
border-top: 1px solid gainsboro;
border-left: 1px solid gainsboro;
padding: .2rem .4rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* get rid of leading border (optional) */
.container>div:nth-child(7n+1) {
border-left: unset;
}
/* get rid of top -most border (optional) */
.container>div:nth-child(-n+7) {
border-top: unset;
/* this is could also be the "header" row, bolding etc. goes here*/
}
/* custom per-column text alignments */
.container>div:nth-child(7n+3),
.container>div:nth-child(7n+5) {
text-align: end;
}
<div class="container">
<div>2019-11-14</div>
<div>Nov 10 - 13, 2019</div>
<div>4</div>
<div>Sun - Wed</div>
<div>669</div>
<div>Likely</div>
<div>North Carolina</div>
<div>2019-11-14</div>
<div>Nov 10 - 13, 2019</div>
<div>4</div>
<div>Sun - Wed</div>
<div>627</div>
<div>Likely</div>
<div>Nevada</div>
<div>2019-11-14</div>
<div>Nov 1 - 7, 2019</div>
<div>7</div>
<div>Fri - Thu</div>
<div>347</div>
<div>Adults</div>
<div>North Carolina</div>
<div>2019-11-13</div>
<div>Nov 1 - 13, 2019</div>
<div>13</div>
<div>Fri - Wed</div>
<div>695</div>
<div>Likely</div>
<div>California</div>
</div>
What about just using ::after selector and absolute position
.grid-container {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
column-gap: 41px;
}
.column {
position: relative;
background: pink;
}
.column::after {
display: block;
content: "";
background: red;
width: 1px;
height: 100%;
position: absolute;
top: 0px;
right: -21px;
}
.column:last-child::after {
display: none;
}
<div class="grid-container">
<div class="column">
Bear claw gingerbread danish chocolate cheesecake icing shortbread.
</div>
<div class="column">
Bear claw gingerbread danish chocolate cheesecake icing shortbread.
</div>
<div class="column">
Bear claw gingerbread danish chocolate cheesecake icing shortbread.
</div>
<div class="column">
Bear claw gingerbread danish chocolate cheesecake icing shortbread.
</div>
</div>
By using "hr" tag you can add horizontal line, but to add vertical line you have to give border using CSS.

A grid layout with responsive squares

I am wanting to create a grid layout with responsive squares.
I feel like I should be able to do this with CSS Grid layout but having trouble setting the height of each square to be equal to the width.
Also having trouble setting a gutter between each square.
Would I be better off using flexbox?
Currently my HTML looks like this but will be dynamic so more squares may be added. And of course it needs to be responsive so will ideally use a media query to collapse it to one column.
<div class="square-container">
<div class="square">
<div class="content">
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
</div>
Using css grid, this is as far as I got
.square-container{
display: grid;
grid-template-columns: 30% 30% 30%;
.square {
}
}
I was able to get a bit further with flexbox and able to use space-between to align squares with a nice gutter but was still struggling to get the height to match the width of each square.
I wasn't able to find any examples of this being done with either flexbox or grid but any examples would be appreciated as well.
Thanks
The padding-bottom trick is the most used to accomplish that.
You can combine it with both Flexbox and CSS Grid, and since using percent for margin/padding gives inconsistent result for flex/grid items (on older browser versions, see edit note below), one can add an extra wrapper, or like here, using a pseudo, so the element with percent is not the flex/grid item.
Edit: Note, there's an update made to the specs., that now should give consistent result when used on flex/grid items. Be aware though, the issue still occurs on older versions.
Note, if you will add content to the content element, it need to be position absolute to keep the square's aspect ratio.
Fiddle demo - Flexbox
Edit 2: In a comment I were asked how to have a centered text, so I added that in below snippet.
.square-container {
display: flex;
flex-wrap: wrap;
}
.square {
position: relative;
flex-basis: calc(33.333% - 10px);
margin: 5px;
border: 1px solid;
box-sizing: border-box;
}
.square::before {
content: '';
display: block;
padding-top: 100%;
}
.square .content {
position: absolute;
top: 0; left: 0;
height: 100%;
width: 100%;
display: flex; /* added for centered text */
justify-content: center; /* added for centered text */
align-items: center; /* added for centered text */
}
<div class="square-container">
<div class="square">
<div class="content">
<span>Some centered text</span>
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
</div>
CSS Grid version
.square-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
grid-gap: 10px;
}
.square {
position: relative;
border: 1px solid;
box-sizing: border-box;
}
.square::before {
content: '';
display: block;
padding-top: 100%;
}
.square .content {
position: absolute;
top: 0; left: 0;
height: 100%;
width: 100%;
}
<div class="square-container">
<div class="square">
<div class="content">
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
<div class="square">
<div class="content spread">
</div>
</div>
<div class="square">
<div class="content column">
</div>
</div>
</div>
Try using viewport percentage units.
jsFiddle
.square-container {
display: grid;
grid-template-columns: repeat(3, 30vw);
grid-template-rows: 30vw;
grid-gap: 2.5vw;
padding: 2.5vw;
background-color: gray;
}
.square {
background-color: lightgreen;
}
body {
margin: 0; /* remove default margins */
}
<div class="square-container">
<div class="square">
<div class="content"></div>
</div>
<div class="square">
<div class="content spread"></div>
</div>
<div class="square">
<div class="content column"></div>
</div>
</div>
From the spec:
5.1.2. Viewport-percentage lengths: the vw, vh, vmin, vmax units
The viewport-percentage lengths are relative to the size of the
initial containing block. When the height or width of the initial
containing block is changed, they are scaled accordingly.
vw unit - Equal to 1% of the width of the initial containing block.
vh unit - Equal to 1% of the height of the initial containing
block.
vmin unit - Equal to the smaller of vw or vh.
vmax unit - Equal to the larger of vw or vh.
You can use the fact that padding is calculated based on the width and set padding-top: 100% directly to the square grid items (the grid items would be square now).
2019 update
Note that for flex items as well as grid items earlier this doesn't used to work - see the post linked in the comments to this answer:
Why doesn't percentage padding / margin work on flex items in Firefox and Edge?
Now that there is a consensus between browsers (newer versions) to have the same behaviour for padding for flex items and grid items, you can use this solution.
See demo below:
.square-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
grid-gap: 10px;
}
.square {
background: cadetblue;
padding-top: 100%; /* padding trick directly on the grid item */
box-sizing: border-box;
position: relative;
}
.square .content { /* absolutely positioned */
position: absolute;
top: 0;
right:0;
left: 0;
bottom: 0;
}
<div class="square-container">
<div class="square">
<div class="content"> some content here</div>
</div>
<div class="square">
<div class="content"> some content here</div>
</div>
<div class="square">
<div class="content"> some content here</div>
</div>
<div class="square">
<div class="content"> some content here</div>
</div>
<div class="square">
<div class="content column">some content here and there is a lot of text here</div>
</div>
<div class="square">
<div class="content spread">text</div>
</div>
<div class="square">
<div class="content column">some text here</div>
</div>
</div>
You can achieve this in all modern browsers using CSS aspect-ratio property.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 5px;
}
.container div {
aspect-ratio: 1 / 1;
/* Styles below just for demo */
background-color: orange;
color: white;
font-family: Arial;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
<div>E</div>
<div>F</div>
<div>G</div>
</div>
For days I was astonished that in 2020 there is no simple solution for this. I was convinced that with CSS grid this is gonna be a piece of cake... Flexbox solution provided by Ason is the only one that works across browsers. On Stack I found one more solution with CSS grid that uses padding-bottom: 100% but it doesn't work in Firefox (you get a lot of white space beneath the footer).
This is my take on the problem, I think it is the simplest solution of all that I have encountered these days.
CSS Grid solution on Codepen:
https://codepen.io/abudimir/pen/ExKqyGp
<div class="square-container">

Overlapping elements within a square grid

I’ve to implement a layout based on a square grid. As shown on the following image, some elements have to overlap responsive within this grid. (The squares are offset on the x-axis and overlap by one grid cell on the y-axis.)
http://i.stack.imgur.com/9bZ5G.jpg
Does anybody know how to achieve this effect? I'm using the framework Foundation 6. I’d prefer a solution without JavaScript. I can’t use the Foundation .#-push-# and .#pull-# classes because they would shift the elements inwards and the two squares have to be in separate rows.
I’ve set up a JSFiddle containing the two squares.
.square {
background: #f00;
position: relative;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.content {
position: absolute;
width: 100%;
height: 100%;
}
.dark {
background: #cbcbcb;
}
.light {
background: #dedede;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.0/foundation.css" rel="stylesheet"/>
<div class="row">
<div class="small-12 columns">
<div class="row">
<div class="small-8 columns end">
<div class="square dark">
<div class="content">test</div>
</div>
</div>
</div>
<div class="row">
<div class="small-6 small-offset-6 columns end">
<div class="square light">
<div class="content">test</div>
</div>
</div>
</div>
</div>
</div>
Many thanks in advance for your help.
I know this question is a little bit old, but for the benefit of all this is now very easily and cleanly possible with CSS Grid. Taking the image posted in the original question we define a container and two squares:
<div class="container">
<div class="content square1">Square 1</div>
<div class="content square2">Square 2</div>
</div>
Then in the CSS define the container as a CSS Grid with 6 columns and 6 rows. In the example below I have used the repeat() CSS Method to have the browser create 6 of the same sized columns and rows.
.container {
display: grid;
grid-column-template: repeat(6, 1fr);
grid-row-template: repeat(6, 30px);
width: 100%;
height: 600px;
}
Then for each item you set where the upper left hand corner will be located on that grid. You can use the long handed properties of grid-column-start, grid-column-end, grid-row-start, and grid-row-end, but I find it's easier to use the short hand properties as shown below:
.square1 {
grid-column: 1 / 5;
grid-row: 1 / 5;
background: #cbcbcb;
}
.square2 {
grid-column: 4 / 7;
grid-row: 4 / 7;
background: #dedede;
}
As far as the placement goes, you specify it based on the grid lines you're invisibly drawing in the container. Position 1 / 1 in this case is the upper left-most corner (or where 0,0 would be if you're talking about coordinates). CSS Grid is now widely supported and I believe there are some JS libraries out there that do create fall backs for this if you don't want to hard code your own with feature queries.
Here's the full block of code with the SO Code Snippet runner:
.container {
display: grid;
grid-column-template: repeat(6, 1fr);
grid-row-template: repeat(6, 30px);
width: 100%;
height: 600px;
}
.square1 {
grid-column: 1 / 5;
grid-row: 1 / 5;
background: #cbcbcb;
}
.square2 {
grid-column: 4 / 7;
grid-row: 4 / 7;
background: #dedede;
}
<div class="container">
<div class="content square1">Square 1</div>
<div class="content square2">Square 2</div>
</div>
It seems to work if you calculate the offset with percent and also mind the column spacing. I therefore adjustet the snippet and added another square with 4 colums:
.square {
background: #f00;
position: relative;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.content {
position: absolute;
width: 100%;
height: 100%;
}
.dark {
background: #cbcbcb;
}
.light {
background: #dedede;
}
/* NEW */
.small-6.columns.overlap-top > .square {
margin-top: calc(-33.3% + 1.33*0.625rem); // one third is 33.3% minus 1.33 times col spacing
}
.small-4.columns.overlap-top > .square {
margin-top: calc(-50% + 1*0.625rem); // one half is 50% minus 1 times col spacing
}
#media screen and (min-width: 40em) {
.small-6.columns.overlap-top > .square {
margin-top: calc(-33.3% + 1.33*0.9375rem);
}
.small-4.columns.overlap-top > .square {
margin-top: calc(-50% + 1*0.9375rem);
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.0/foundation.css" rel="stylesheet"/>
<div class="row">
<div class="small-12 columns">
<div class="row">
<div class="small-8 columns end">
<div class="square dark">
<div class="content">Square 1</div>
</div>
</div>
</div>
<div class="row">
<!-- New class overlap-top -->
<div class="small-6 small-offset-6 columns overlap-top end">
<div class="square light">
<div class="content">Square 2</div>
</div>
</div>
</div>
<!-- New square -->
<div class="row">
<div class="small-4 small-offset-4 columns overlap-top end">
<div class="square dark">
<div class="content">Square 3</div>
</div>
</div>
</div>
</div>
</div>
JSFiddle: https://jsfiddle.net/jwt0k1pw/1/
Hope this helps!

Pixel wide gaps between each <div> with flexbox due to pixel rounding error

How do I remove the black lines that seem to be caused by errors in rounding fractions of a pixel? This appears to be an issue with Chrome only, Firefox seems to be doing more intelligent rounding and renders it perfectly.
Is there an easy solution for this problem?
This is how Chrome renders it:
.container {
height: 100px;
width: 100%;
background-color: black;
display: flex;
flex-flow: nowrap column;
}
.row {
background-color: lightgreen;
flex: 1 1 auto;
}
<div class="container">
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
</div>
you may try to fil the gap(?) with box-shadow
.container {
height: 100px;
width: 100%;
background-color: black;
display: flex;
flex-flow: nowrap column;
}
.row {
background-color: lightgreen;
flex: 1 1 auto;
box-shadow:0 1px lightgreen;
}
<div class="container">
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
</div>
I think I figured out the issue. I have system-wide DPI scaling enabled (for high resolution monitors). When I disabled it (and logged in again), chrome renders it perfectly (at all zoom levels). So this entirely looks like Chrome's fault. I guess there's nothing that can be done about this, so I guess I'll mark it as solved. Thanks for your help guys.

Resources