I have the following HTML (JSFiddle Example):
<header>
<div class="wrapper">
<p>Header Text</p>
</div>
</header>
<div class="intro">
<div class="frame">
<img src="https://via.placeholder.com/800x240">
</div>
<div class="inner">
<div class="wrapper">
<p>Body text</p>
</div>
</div>
</div>
Objectives
Body Text must be over the Image;
Body Text and Header Text must be left aligned.
The problem is when resizing the screen to a small size Body Text and Header Text are not aligned.
Wrapper class is responsible to keep a center aligned region, with width up to 1024px, where content is placed like "header text" and "body text" ...
How to solve this?
The CSS code is the following:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#media screen and (max-width: 400px) {
.wrapper { padding: 0 40px;}
}
#media screen and (min-width: 401px) {
.wrapper {
margin: 0 auto;
width: 90%;
}
}
img {
height: auto;
max-width: 100%;
outline: 0;
width: 100%;
}
div.intro {
overflow: hidden;
position: relative;
}
#media screen and (max-width: 400px) {
div.frame {
margin: 0 -14rem;
}
div.frame {
margin: 0 -4rem;
}
}
div.inner {
max-width: 600px;
position: absolute;
top: 40px;
}
Try with this css code
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#media screen {
.wrapper { padding: 0 40px;}
}
#media screen {
.wrapper {
width: 90%;
}
}
img {
height: auto;
max-width: 100%;
outline: 0;
width: 100%;
}
div.intro {
overflow: hidden;
position: relative;
}
#media screen and (max-width: 400px) {
div.frame {
margin: 0 -14rem;
}
div.frame {
margin: 0 -4rem;
}
}
div.inner {
max-width: 600px;
position: absolute;
top: 40px;
}
Related
I am learning HTML & CSS from a video step-by-step. In the beginning, we should make a header.
But I don't why the code is not working the same.
The problem is the header must be full width but in my case, it's not. It only became full width when I remove "max-width: 100%" from the .col class
here is my code:
/* app.css */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.body {
font-family: "Nunito Regulsr";
}
.content {
background-color: yellow;
width: 100%;
height: 100px;
}
/* grid.css */
.container {
width: 100%;
margin-left: auto;
margin-right: auto;
padding: 0 15px;
}
#media only screen and (min-width: 576px) {
.container {
max-width: 576px;
}
}
#media only screen and (min-width: 768px) {
.container {
max-width: 768px;
}
}
#media only screen and (min-width: 992px) {
.container {
max-width: 992px;
}
}
#media only screen and (min-width: 1200px) {
.container {
max-width: 1400px;
}
}
.row {
display: flex;
flex-wrap: wrap;
}
.col {
max-width: 100% flex-grow: 1;
}
<div class="container">
<div class="row">
<div class="col">
<div class="content">text</div>
</div>
</div>
</div>
I have a sidebar nav which collapses to make way for more content in a flex layout. When the user clicks to collapse the nav the content area div .ca expands to fill the space and the flex layout reflows using media queries.
See it in action here.
I have applied a CSS transition to each moving element but the .ca div jumps when the nav is opened and closed. This seems to be related to the widths of the units in the flex layout – .songgrid-unit.
The unit has a width value in px but the media queries set a min-width value in % to override this, so as to avoid large empty spaces between break points:
html:
<div class="navbar open ease">
<div class="nav-toggle">
<div class="nt-wrap">
<div class="nt-bar ease" id="ntb-top"></div>
<div class="nt-bar ease" id="ntb-bot"></div>
</div>
</div>
</div>
<div class="ca ease">
<div class="songgrid ease">
<div class="songgrid-unit ease">
<!-- post content -->
</div>
<div class="songgrid-unit ease">
<!-- post content -->
</div>
<div class="songgrid-unit ease">
<!-- post content -->
</div>
</div>
</div>
CSS:
.navbar {
position: fixed;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 214px;
height: 100vh;
left: 0;
top: 0;
box-sizing: border-box;
padding: 48px 8px 48px 32px;
background-color: #282828;
border-right: solid 1px #555;
z-index: 20;
}
.navbar.closed {
left: -214px;
}
.ca {
position: relative;
width: 100%;
padding: 48px 32px 48px 280px;
box-sizing: border-box; /*keep padding inside width*/
}
.ca.fullwidth {
width: 100%;
padding: 48px 32px 48px 64px;
}
.songgrid {
flex: 1;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
}
.songgrid-unit {
width: 280px;
box-sizing: border-box;
padding: 0 16px 48px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
/*adjust no. of cols as per screen width in both container widths*/
#media only screen and (max-width: 623px) {
.ca.fullwidth .songgrid-unit {
min-width: 100%;
}
}
#media screen and (min-width: 624px) and (max-width: 904px) {
.songgrid-unit {
min-width: 100%;
}
.ca.fullwidth .songgrid-unit {
min-width: 50%;
}
}
#media screen and (min-width: 905px) and (max-width: 1184px) {
.songgrid-unit {
min-width: 50%;
}
.ca.fullwidth .songgrid-unit {
min-width: 33%;
}
}
#media screen and (min-width: 1185px) and (max-width: 1464px) {
.songgrid-unit {
min-width: 33%;
}
.ca.fullwidth .songgrid-unit {
min-width: 25%;
}
}
#media screen and (min-width: 1465px) and (max-width: 1744px) {
.songgrid-unit {
min-width: 25%;
}
.ca.fullwidth .songgrid-unit {
min-width: 20%;
}
}
#media only screen and (min-width: 1745px) and (max-width: 1949px) {
.songgrid-unit {
min-width: 20%;
}
.ca.fullwidth .songgrid-unit {
min-width: 16.66667%;
}
}
#media only screen and (min-width: 1950px) {
.songgrid-unit {
min-width: 16.66667%;
}
.ca.fullwidth .songgrid-unit {
min-width: 14.285%;
}
}
.ease {
transition: all 0.4s ease-in 0s;
-webkit-backface-visibility: hidden;
}
jQuery:
$(".nav-toggle").click(function(){
$(".navbar").toggleClass("open closed");
$(".ca").toggleClass("fullwidth");
});
If I remove the media queries the transitions work fine, but the min-width values are breaking the effect.
Why is this happening and how can I fix it? Thanks.
It's hard to tell because the code on the site you linked is a bit different from what you posted here. But it seems to me like the .ca div isn't actually jumping, it just looks like it is because as the items inside the grid change in size the number of items per row changes. The jump happens when the items either take up more space so that one fewer can fit in a row, or take up less space so one more can fit per row.
I played with the code you posted here a bit just to demonstrate what I think is happening. I hid the nav and added some outlines around the songgrid-container & individual songgrid items, and then I slowed down the transition a bit. So you can press the blue box and see what the transition looks like in slow motion. It looks like the widths are all transitioning fine, it just jumps when the layout inevitably changes.
Unfortunately I don't have a super easy solution to this, it's not really something you can control with a basic CSS transition. But maybe look at a library like this: https://isotope.metafizzy.co/
I don't actually think the media queries have anything to do with it, but I may also just be completely misunderstanding the effect you are seeing!
$(".nav-toggle").click(function(){
// $(".navbar").toggleClass("open closed");
$(".ca").toggleClass("fullwidth");
});
.navbar {
position: fixed;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 214px;
height: 100vh;
left: 0;
top: 0;
box-sizing: border-box;
padding: 48px 8px 48px 32px;
background-color: #282828;
border-right: solid 1px #555;
z-index: 20;
left: -214px;
}
.nav-toggle {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
right: -50px;
}
.navbar.closed {
left: -214px;
}
.ca {
position: relative;
width: 100%;
padding: 48px 32px 48px 280px;
background: lightblue;
box-sizing: border-box; /*keep padding inside width*/
}
.ca.fullwidth {
width: 100%;
padding: 48px 32px 48px 64px;
}
.songgrid {
flex: 1;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
outline: 2px solid blue;
}
.songgrid-unit {
width: 280px;
box-sizing: border-box;
padding: 0 16px 48px;
display: flex;
flex-direction: column;
justify-content: space-between;
background: rgba(255,255,255,.5);
outline: 2px solid gray;
}
/*adjust no. of cols as per screen width in both container widths*/
#media only screen and (max-width: 623px) {
.ca.fullwidth .songgrid-unit {
min-width: 100%;
}
}
#media screen and (min-width: 624px) and (max-width: 904px) {
.songgrid-unit {
min-width: 100%;
}
.ca.fullwidth .songgrid-unit {
min-width: 50%;
}
}
#media screen and (min-width: 905px) and (max-width: 1184px) {
.songgrid-unit {
min-width: 50%;
}
.ca.fullwidth .songgrid-unit {
min-width: 33%;
}
}
#media screen and (min-width: 1185px) and (max-width: 1464px) {
.songgrid-unit {
min-width: 33%;
}
.ca.fullwidth .songgrid-unit {
min-width: 25%;
}
}
#media screen and (min-width: 1465px) and (max-width: 1744px) {
.songgrid-unit {
min-width: 25%;
}
.ca.fullwidth .songgrid-unit {
min-width: 20%;
}
}
#media only screen and (min-width: 1745px) and (max-width: 1949px) {
.songgrid-unit {
min-width: 20%;
}
.ca.fullwidth .songgrid-unit {
min-width: 16.66667%;
}
}
#media only screen and (min-width: 1950px) {
.songgrid-unit {
min-width: 16.66667%;
}
.ca.fullwidth .songgrid-unit {
min-width: 14.285%;
}
}
.ease {
transition: all 3s ease-in 0s;
-webkit-backface-visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<div class="navbar open ease">
<div class="nav-toggle">
click
</div>
</div>
<div class="ca ease">
<div class="songgrid ease">
<div class="songgrid-unit ease">
content
</div>
<div class="songgrid-unit ease">
content
</div>
<div class="songgrid-unit ease">
content
</div>
</div>
</div>
</body>
</html>
With some help getting onto the right path from the reply from #sparrow here I've found that the transitions can be rendered much smoother by applying further flex properties to the items creating the columns in the grid.
Updating the CSS for the .songgrid-unit class as follows fixes the issue:
.songgrid-unit {
width: 280px;
box-sizing: border-box;
padding: 0 16px 48px;
display: flex;
flex-grow: 1; /*new line*/
flex-shrink: 1; /*new line*/
flex-basis: auto; /*new line*/
flex-direction: column;
justify-content: space-between;
}
With thanks to #sparrow and the authors over at this thread.
This question already has an answer here:
Change div order with CSS depending on device-width
(1 answer)
Closed 4 years ago.
I have three columns; left, middle and right and they are in a div that is 100% width of the screen. How in a media query, when the screen size is reduced, can I get the middle column to stay on the top, the left column to go underneath and then the right column to go underneath that? I've attached a CodePen as well as displaying the HTML and CSS below: https://codepen.io/Macast/pen/jZworE . Any help will be greatly appreciated! I have no idea how to go about this.
This is what I'm looking for:
HTML:
<body>
<div class="columnContainer">
<div class="leftColumn" style="background-color:#aaa;">
<h2>Left Column</h2>
</div>
<div class="middleColumn" style="background-color:#bbb;">
<h2>Middle Column</h2>
</div>
<div class="rightColumn" style="background-color:#ccc;">
<h2>Right Column</h2>
</div>
</div>
</body>
</html>
CSS:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.columnContainer {
width: 100%;
}
.leftColumn {
float: left;
width: 33.33%;
padding: 10px;
height: 200px;
text-align: center;
}
.middleColumn {
float: left;
width: 33.33%;
padding: 10px;
height: 200px;
text-align: center;
}
.rightColumn {
float: left;
width: 33.33%;
padding: 10px;
height: 200px;
text-align: center;
}
.columnContainer:after {
content: "";
display: table;
clear: both;
}
/* Media Query */
#media (min-width: 320px) and (max-width: 480px) {
/* Column Stacking Here */
}
You can use flex + order;
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.columnContainer {
width: 100%;
display: flex;
}
.leftColumn {
width: 33.33%;
padding: 10px;
height: 200px;
margin: 0 auto;
text-align: center;
}
.middleColumn {
width: 33.33%;
padding: 10px;
height: 200px;
margin: 0 auto;
text-align: center;
}
.rightColumn {
width: 33.33%;
padding: 10px;
height: 200px;
margin: 0 auto;
text-align: center;
}
/* Media Query */
#media (min-width: 320px) and (max-width: 480px) {
/* Column Stacking Here */
.columnContainer {
flex-direction: column;
}
.leftColumn {
order: 2;
}
.middleColumn {
order: 1;
}
.rightColumn {
order: 3;
}
}
<body>
<div class="columnContainer">
<div class="leftColumn" style="background-color:#aaa;">
<h2>Left Column</h2>
</div>
<div class="middleColumn" style="background-color:#bbb;">
<h2>Middle Column</h2>
</div>
<div class="rightColumn" style="background-color:#ccc;">
<h2>Right Column</h2>
</div>
</div>
</body>
</html>
/* Media Query */
#media (max-width: 480px) {
.leftColumn, .middleColumn, .rightColumn {
float: left;
width: 100%;
padding: 10px;
height: 200px;
text-align: center;
}
}
I want to place description under the photo from 768px up, but without white gap between them. Could someone help me.
I note that the HTML order cannot be changed. Eventually element's can be wrapped.
I tried flexbox and grid layout but with no success.
Below is the latest version of what I am trying to achieve.
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
* {
box-sizing: border-box;
}
#media (min-width: 768px) {
.container {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
}
.container div {
padding: 20px;
}
.container .name {
background: orange;
}
#media (min-width: 768px) {
.container .name {
flex-basis: 100%;
}
}
.container .photo {
background: yellow;
}
#media (min-width: 768px) {
.container .photo {
flex-basis: 50%;
padding: 100px 20px;
}
}
.container .price {
background: purple;
}
#media (min-width: 768px) {
.container .price {
flex-basis: 50%;
padding: 150px 20px;
}
}
.container .description {
background: blue;
flex-basis: 50%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="name">name</div>
<div class="photo">photo</div>
<div class="price">price</div>
<div class="description">description</div>
</div>
</body>
</html>
You don't really need flexbox layout for that. A couple of good old-fashioned floats will do.
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
* {
box-sizing: border-box;
}
#media (min-width: 768px) {
.container {
position: relative;
}
}
.container div {
padding: 20px;
}
.container .name {
background: orange;
}
.container .photo {
background: yellow;
}
#media (min-width: 768px) {
.container .photo {
float: left;
width: 50%;
padding: 100px 20px;
}
}
.container .price {
background: purple;
}
#media (min-width: 768px) {
.container .price {
float: right;
width: 50%;
padding: 150px 20px;
}
}
.container .description {
background: blue;
}
#media (min-width: 768px) {
.container .description {
float: left;
clear: left;
width: 50%;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="name">name</div>
<div class="photo">photo</div>
<div class="price">price</div>
<div class="description">description</div>
</div>
</body>
</html>
Why is the text in my <p> element being pushed down because of the existence of the <ins> tag? If you delete the <ins> tag from DOM via developer tools, you will see my text gets put in the position I expect.
main {
max-width: 1000px;
margin: 0 auto;
width: 100%;
box-sizing: border-box;
}
#portal-wrapper {
width: 100%;
padding: 40px 0;
background: #fff;
}
aside {
width: 100%;
padding: 10px 20px 20px;
box-sizing: border-box;
position: relative;
}
#media only screen and (min-width: 795px) {
main {
display: table;
}
#portal-wrapper {
display: table-cell;
min-width: 400px;
max-width: 680px;
width: auto;
}
aside {
width: 300px;
display: table-cell;
padding-right: 0;
padding-top: 41px;
}
}
<main>
<div id="portal-wrapper">
<div id="portal">
<p>
Here's my text. Why am I pushed down so far.
</p>
</div>
</div>
<aside>
<ins style="display: block; height: 600px;"> </ins>
</aside>
</main>
Fiddle here: https://jsfiddle.net/wwvq7net/1/
You could use vertical-align: top property:
main {
max-width: 1000px;
margin: 0 auto;
width: 100%;
box-sizing: border-box;
}
#portal-wrapper {
width: 100%;
padding: 40px 0;
background: #fff;
}
aside {
width: 100%;
padding: 10px 20px 20px;
box-sizing: border-box;
position: relative;
}
#media only screen and (min-width: 795px) {
main {
display: table;
}
#portal-wrapper {
display: table-cell;
vertical-align: top;
min-width: 400px;
max-width: 680px;
width: auto;
}
aside {
width: 300px;
display: table-cell;
vertical-align: top;
padding-right: 0;
padding-top: 41px;
}
}
<main>
<div id="portal-wrapper">
<div id="portal">
<p>
Here's my text. Why am I pushed down so far.
</p>
</div>
</div>
<aside>
<ins style="display: block; height: 600px;"> </ins>
</aside>
</main>
JSFiddle
When you set display:table-cell those elements are automatically starting with vertical-align:baseline which is why your #portal is being pushed to the bottom of #portal-wrapper.
Change to vertical-align:top or another value to fix this. Read more about vertical-align here.