Can I avoid this flexbox wrapper? - css

I'm not really sure if I need a wrapper to delimit the max-width of the container.
The header has a 100% width, and the .wrapper delimits to a 1000px max width.
Is there any way to avoid using the .wrapper div?
body { margin: 0; }
header {
margin: 0;
padding: 0;
background-color: DarkRed;
}
.header-wrapper {
margin: auto;
max-width: 500px;
padding: 10px 0;
}
#logo, #tagline, #menu {
margin: auto;
padding: 5px;
}
#logo {
flex: 2;
background-color: Crimson;
}
#tagline {
flex: 5;
background-color: Salmon;
}
#menu {
flex: 3;
background-color: IndianRed;
}
#media (min-width: 768px){
.header-wrapper {
display: flex;
}
}
<header>
<div class="header-wrapper">
<div id="logo">Logo</div>
<div id="tagline">Tagline</div>
<div id="menu">Menu</div>
</div>
</header>
CodePen

This will depend on your exact needs, there's no fast rule about your exact html structure when it comes to designing a page.
If you want a background color that extends the entire 100% width but you want the content to have a hidden left/right barrier, you probably want a wrapper to force that barrier rule. otherwise, the red background will only be as wide as the 1000px rule (or whatever you set your centered bounds to)
if you don't need a barrier and want the content/nav items to span the entire width, then you don't need a wrapper.
again, it's really up to you depending on the overall design of the component

Set all div max-width, which is equal to 1000px

what you did looks like your wrapper will always be 500px according to mediaqueries, so width of each elements are static.
You can modify your mediaqueries and remove the extra wrapper and the flex values.
Snippet below behave just like your codepen ... with a wrapper less :
body {
margin: 0;
}
header {
margin: 0;
padding: 0;
background-color: DarkRed;
padding: 10px 0;
}
#logo,
#tagline,
#menu {
padding: 5px;
}
#logo {
background-color: Crimson;
}
#tagline {
background-color: Salmon;
}
#menu {
background-color: IndianRed;
}
#media (min-width: 768px) {
header {
display: flex;
justify-content: center;
}
#logo {
width: 100px;
}
#tagline {
width: 250px;
}
#menu {
width: 150px;
}
}
<header>
<div id="logo">Logo</div>
<div id="tagline">Tagline</div>
<div id="menu">Menu</div>
</header>
http://codepen.io/gc-nomade/pen/ENqPVp

Related

Responsive design - mantain the aligment of a div to the left when the width becomes smaller

I have the following layout:
a wrapper that get all the width of the browser
a wrapper-right(menu) that is always close to the browser right
header that has a max width and is centered
content align with header
When the resolution is below a specific step(32rem) and wrapper_right get close to the header I want the header to get a smaller width, so the wrapper_right doesn't go over it.
The problem is that the header doesn't remain align to the left to the content, being set to left,right auto.
I try to use margin-left:80px, but doesn't work properlly.
If the resolution goes below 27rem I want the wrapper_right to be hidden, and header back to normal.
OBS. 27rem, 32rem are just for example, to be visible in the code box. I can modify the html code if is necessary.
.wrapper {
height: 6rem;
position: relative;
width: 100%;
background-color: red;
display: inline-block;
}
.header {
margin: 1.5rem auto 0;
max-width: 30rem;
background-color: blue;
}
#media (max-width: 32em) {
.header {
max-width: calc(30rem - 80px);
}
}
.wrapper-right {
background: green;
height: 100%;
position: absolute;
right: 0;
top: 0;
width: 80px;
}
.content {
max-width: 30rem;
margin: 0 auto;
background-color: orange;
}
<div class="wrapper">
<div class="header">
<div> lorem ipsum></div>
<div> lorem ipsum></div>
<div> lorem ipsum></div>
</div>
<div class="wrapper-right">menu</div>
</div>
<div class="content">content</div>
Is this what you're after?
https://codepen.io/panchroma/pen/PxKBBV
The important bits in the CSS are:
lines 36-40 where we're scaling the width of .header at viewports below 40rem
lines 42 - 50 where we're hiding .wrapper-right, and restoring .header to full-width
As an FYI, your CSS has a class titled .l-header but I couldn't see where you were going with this.
Hope this helps!
HTML
As originally posted
CSS
.wrapper {
height: 6rem;
position: relative;
width: 100%;
background-color: red;
display: inline-block;
}
.header {
margin: 1.5rem auto 0;
max-width: 30rem;
background-color: blue;
}
#media (max-width: 32em) {
.l-header {
max-width: calc(30rem - 80px);
}
}
.wrapper-right {
background: green;
height: 100%;
position: absolute;
right: 0;
top: 0;
width: 80px;
}
.content {
max-width: 30rem;
margin: 0 auto;
background-color: orange;
}
#media (max-width: 40rem) {
.header{
width:calc(75vw - 80px);
}
}
#media (max-width: 27rem) {
.wrapper-right{
display:none;
}
.header{
width:100%;
}
}
Version 2
Based on your comments, here's version 2
https://codepen.io/panchroma/pen/VVMJxM
The important bits are that I added the .header-wrapper. Then we're changing the left and right padding on .header-wrapper at various viewports to keep the header and content divs aligned.
Good luck!
HTML
<div class="wrapper">
<div class="header-wrapper">
<div class="header">
<div> lorem ipsum></div>
<div> lorem ipsum></div>
<div> lorem ipsum></div>
</div>
</div>
<div class="wrapper-right">menu</div>
</div>
<div class="content">content</div>
CSS
/* note that I'm using normalize.css in the CSS setings */
/* https://necolas.github.io/normalize.css/ */
.wrapper {
height: 6rem;
position: relative;
width: 100%;
background-color: red;
display: inline-block;
margin-right:80px;
}
.header {
margin: 1.5rem auto 0;
max-width: 30rem;
background-color: blue;
position:relative;
z-index:5;
}
.wrapper-right {
background: green;
height: 100%;
position: absolute;
right: 0;
top: 0;
width: 80px;
}
.content {
max-width: 30rem;
margin: 0 auto;
background-color: orange;
}
#media (max-width: 40rem) {
.header-wrapper {
/* add padding-right to make room for .wrapper-right */
/* have used 81px instead of 80px so we can be certain */
/* that the div isn't extending under .wrapper-right */
padding-right:81px;
/* add padding-left to keep .header and .content aligned */
/* logic is that the space to the left of .content */
/* is the half of the window width - width of .content */
padding-left:calc(50vw - 15rem);
}
}
/* at viewports below 27rem, hide .wrapper-right and return .header to full width */
#media (max-width: 27rem) {
.wrapper-right{
display:none;
}
.header-wrapper{
padding:0;
}
}

CSS - 2 Columns, One Fixed width, One Responsive

There are many examples on this topic here, but what I am after is something that I cannot seem to find the answer to.
I want to create a two column page:
Left column for Navigation (Fixed Width), Right column for content (Responsive). The variation I am after is that I want the Nav to appear on the left for desktop and beneath the content on mobile.
I have the code 'working' kind of, but it's the responsive width of the right column that is the issue.
My code is below, Any guidance would be really valued.
.CF:after { content:"."; display:block; height:0; clear:both; visibility:hidden; }
.CF { display:inline-block; }
.CF { display:block; }
.content {max-width: 1300px; margin: 0 auto; padding: 0 25px; display:block; }
.information {display:block; background: lime;}
.menu {display:block; background: lightblue;}
#media all and (min-width: 992px) {
.content {padding: 0 50px; }
.information {display:block; float: right; width: auto; }
.menu {width: 250px; float:right; }
}
<div class="content CF">
<article class="information">
Article Information
</article>
<nav class="menu">
Menu
</nav>
</div>
I would use flexbox to solve this.
Below the menu is at the left side when the width of the screen is more than 991 pixels. Otherwise it is below the article.
I have assigned colors for visibility only.
.content {
display: flex;
background: blue;
}
.menu {
width: 100px;
background: red;
}
.information {
background: green;
flex-grow: 1;
}
#media all and (max-width: 991px) {
.content {
flex-wrap: wrap;
}
.menu {
order: 2;
}
.information {
order: 1;
min-width: 100%;
}
}
<div class="content">
<nav class="menu">
Menu
</nav>
<article class="information">
Article Information
</article>
</div>
I would suggest looking at CSS Grid or Flexbox for layout. Support for Grid is good.
Example using Grid...
codepen
.content {
max-width: 1300px;
margin: 0 auto;
padding: 0 25px;
display: block;
grid-template-columns: 250px 1fr;
}
.information {
background: lime;
order: 2;
}
.menu {
background: lightblue;
}
#media all and (min-width: 992px) {
.content {
display: grid;
padding: 0 50px;
}
}
<div class="content CF">
<article class="information">
Article Information
</article>
<nav class="menu">
Menu
</nav>
</div>
You've already had two great answers but just to add a few extra options, here are 5 different ways of achieving the same thing:
Example 1: Floats, Widths and Margins
The most compatible method, works on pretty much all browsers. Its also got the smallest CSS footprint.
#example1 .fixedColumn {
width: 180px;
float: left;
}
#example1 .flexibleColumn {
margin-left: 200px;
}
/* gratuituous styling */
.fixedColumn { background-color: #e84c1b; padding: 10px;} .flexibleColumn { background-color: #039be4; padding: 10px;} body { margin: 0; }
<div id="example1">
<div class="fixedColumn">
Fixed Column
</div>
<div class="flexibleColumn">
Flexible Column
</div>
</div>
Example 2: CSS calc()
Compatible with IE9+. Its a solid alternative if you don't need backwards compatibility.
#example2.calc {
overflow: hidden;
}
#example2.calc .fixedColumn {
width: 180px;
float: left;
}
#example2.calc .flexibleColumn {
width: calc(100% - 220px); /*200px for the fixed column and 20 for the left and right padding */
float: left;
}
/* gratuituous styling */
.fixedColumn { background-color: #e84c1b; padding: 10px;} .flexibleColumn { background-color: #039be4; padding: 10px;} body { margin: 0; }
<div id="example2" class="calc">
<div class="fixedColumn">
Fixed Column
</div>
<div class="flexibleColumn">
Flexible Column
</div>
</div>
Example 3: Display as Table
Another solid contender for backwards compatibility works pretty much across the board, but still feels like a bodge making things behave like a table.
#example3.table {
display: table;
width: 100%;
}
#example3.table .fixedColumn {
width: 180px;
display: table-cell;
}
#example3.table .flexibleColumn {
display: table-cell;
}
/* gratuituous styling */
.fixedColumn { background-color: #e84c1b; padding: 10px;} .flexibleColumn { background-color: #039be4; padding: 10px;} body { margin: 0; }
<div id="example3" class="table">
<div class="fixedColumn">
Fixed Column
</div>
<div class="flexibleColumn">
Flexible Column
</div>
</div>
Example 4: Flexbox
Great for modern browsers that support it; simple and intuitive.
#example4.flex {
display: flex;
}
#example4.flex .fixedColumn {
width: 180px;
}
#example4.flex .flexibleColumn {
flex: 1;
}
/* gratuituous styling */
.fixedColumn { background-color: #e84c1b; padding: 10px;} .flexibleColumn { background-color: #039be4; padding: 10px;} body { margin: 0; }
<div id="example4" class="flex">
<div class="fixedColumn">
Fixed Column
</div>
<div class="flexibleColumn">
Flexible Column
</div>
</div>
Example 5: Grid
Out of all the techniques here Grid was supported by browsers last. But its a great option if you have the option to use it.
#example5.grid {
display: grid;
grid-template-columns: 200px 1fr;
}
#example5.grid .fixedColumn {
grid-column: 1;
}
#example5.grid .flexibleColumn {
grid-column: 2;
}
/* gratuituous styling */
.fixedColumn { background-color: #e84c1b; padding: 10px;} .flexibleColumn { background-color: #039be4; padding: 10px;} body { margin: 0; }
<div id="example5" class="grid">
<div class="fixedColumn">
Fixed Column
</div>
<div class="flexibleColumn">
Flexible Column
</div>
</div>

Make DIV float to the bottom instead on top

I have two DIV's, first one is auto width (the content), second one is fixed width.
When the screen gets too narrow/window scaled, the fixed width DIV goes on the top and becomes 100% width as well. I would like to replicate this, but I want the fixed DIV to go on the bottom, not top, when browser gets too narrow. How can I accomplish this? Thanks.
(Please check in 'Full-Page' mode)
.container-wrapper
{
overflow: hidden;
}
.fixed-right
{
overflow: hidden;
min-height: 100px;
min-width: 400px;
float: right;
}
.auto-left
{
overflow: hidden;
min-height: 100px;
}
.fancy
{
border-radius: 2px;
background-color:lightgray;
margin-left: 5px;
padding: 5px;
}
#media
only screen and (max-width: 764px), (min-device-width: 764px) and (max-device-width: 1024px)
{
.fixed-right
{
float: none;
width: auto;
margin-left: 0px;
margin-bottom: 5px;
}
}
<div class="container-wrapper">
<div class='fixed-right fancy'>
Fixed
</div>
<div class="auto-left fancy">
Auto
</div>
</div>
Try adding this into your #media-query;
.container-wrapper {
display: flex;
flex-direction: column-reverse;
}
Pretty easy, change the order of the Divs in the HTML DOM:
<div class="container-wrapper">
<div class="auto-left fancy">
Auto
</div>
<div class='fixed-right fancy'>
Fixed
</div>
</div>
The float right, will make it as you wanted on desktop
You can use display: flex; on your wrapper. Switch the flex-direction in the two different viewports. Note this solution becomes more flexible if you add more elements to the wrapper, being able to set the order.
Then define the order of the divs.
in the large view you set the right div to order 1
in smaller you set it to 0, that means it will be first (on top)
.container-wrapper {
display: flex;
flex-direction: row;
}
.fixed-right {
overflow: hidden;
min-height: 100px;
min-width: 400px;
order: 1;
}
.auto-left {
overflow: hidden;
min-height: 100px;
}
.fancy {
border-radius: 2px;
background-color: lightgray;
margin-left: 5px;
padding: 5px;
}
#media only screen and (max-width: 764px),
(min-device-width: 764px) and (max-device-width: 1024px) {
.container-wrapper {
flex-direction: column;
}
.fixed-right {
width: auto;
margin-left: 0px;
margin-bottom: 5px;
order: 0;
}
.fancy {
margin-left: 0;
}
}
<div class="container-wrapper">
<div class='fixed-right fancy'>
Fixed
</div>
<div class="auto-left fancy">
Auto
</div>
</div>

Fixed width layout with one child spanning full screen width

Can I create a layout like on the picture below, while setting the fixed width only on the parent container? I also cannot use position: absolute; left: 0; right: 0; on Full screen width child, as I cannot remove it from the flow, because it's size is dynamic.
I can't change the markup.
The only solution I can think of is setting the fixed width on every Fixed-width child separately, but as I have a lot of them, that's not the most comfortable solution - means adding a class for every child that I add into the parent container.
Here is an example markup you can post a solution to.
HTML
<div class="fixed-width-container">
<div class="regular-child"></div>
<div class="full-screen-width-child"></div>
<div class="regular-child"></div>
<div class="regular-child"></div>
</div>
CSS
.fixed-width-container {
width: <some-fixed-width>;
}
you can give a try to the flex layout : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
text-align: center;
}
body {
margin: 0;
}
div {
border: 1px solid #333;
}
.fixed-width-container {
width: 400px;/* any width set */
margin: auto;
padding: 10px 10px 0;
background: yellow;
display: flex;
flex-flow: column;
align-items: center;
}
.fixed-width-container>div {
height: 3em;
margin-bottom: 10px;
background: lightblue;
min-width: 100%;
}
.full-screen-width-child {
width: 99vw;/* 100vw is fine too */
}
<div class="fixed-width-container">
<div class="regular-child">Fixed-width child</div>
<div class="full-screen-width-child">Full screen width child with dynamic contents</div>
<div class="regular-child">Fixed-width child</div>
<div class="regular-child">Fixed-width child</div>
</div>
codepen to test and play with
This is just an attempt, and probably not a very good one. But maybe it will spawn some more sophisticated solutions by others, or even yourself.
Idea: negative margins for the full-width child.
* {
box-sizing: border-box;
text-align: center;
}
body {
width: 100%;
background: #fff;
}
div {
border: 1px solid #333;
margin-bottom: 10px;
}
div:last-child {
margin-bottom: 0;
}
.fixed-width-container {
width: 70%;
margin: auto;
padding: 10px;
background: LightYellow;
}
.regular-child,
.full-screen-width-child {
height: 45px;
line-height: 45px;
background: LightBlue;
}
.full-screen-width-child {
margin-left: -24%;
margin-right: -24%;
background: LightGreen;
}
<div class="fixed-width-container">
<div class="regular-child">Fixed-width child</div>
<div class="full-screen-width-child">Full screen width child with dynamic contents</div>
<div class="regular-child">Fixed-width child</div>
<div class="regular-child">Fixed-width child</div>
</div>
The problematic part here is the dimension of the negative margins. If you use %, it will relate to the width of the fixed-width-container. Here, I chose width: 70% for it. Given a body width of 625px (as is the case for the Stack Snippet preview) and a margin of -24%, that would give a negative margin of 625px * 0.7 * 0.24 = 105px. I'm not sure what's the best approach of making this work for any configuration.

DIVs and CSS layout not lining up, but why?

I'm trying to layout a screen using div's and CSS. It's a simple layout at this point but I can't seem to get the div's to line up. I want one wrapper div with two div's within it: one aligned to the left and one aligned to the right. However, they end up on top of each other.
I know this question is simple. What am I missing here?
If I reduce the width of the right div to 60% it lines up right but shouldn't I be able to use 100% of the width of the parent div?
#product_wrapper {
display: inline-block;
height: 75%;
width: 75%;
background-color: white;
text-align: top;
margin: 0 auto;
}
#images_wrapper {
background-color: red;
display: inline-block;
height: 100%;
width: 30%;
margin: 0;
padding: 0;
}
#content_wrapper {
background-color: blue;
display: inline-block;
height: 100%;
width: 70%;
margin: 0;
padding: 0;
}
<div id="product_wrapper">
<div id="images_wrapper">Foo</div>
<div id="content_wrapper">Bar</div>
</div>
Float left your children elements:
jsBin demo
#product_wrapper > *{float:left;}
Note that inline-block causes the inner elements to actually act like inline elements
where white spaces count!
SO another way would be to modify your HTML removing the NewLine separator:
jsBin demo
<div id="images_wrapper">
Foo content
</div><div id="content_wrapper">
^^-------------------------------------- no space here
Bar content
</div>
The third way (the worst one) is to set font-size to 0 for the parent (will remove logically the child's white-space gap since is now '0'); >> and than reset the font-size for children elements to px (cause em will not work since parent has 0).
But that's a good way to loose track of dynamic and responsive font sizes expecially if you use em and size inheritances.
The problem is the whitespace in the html, which occupies some space between the elements.
One way of fixing it is
#product_wrapper {
font-size: 0; /* Hide whitespace in the html */
}
#images_wrapper, #content_wrapper {
font-size: 16px; /* Reset to whatever vaue */
}
#product_wrapper {
display: inline-block;
height: 75%;
width: 75%;
background-color: white;
text-align: top;
margin: 0 auto;
font-size: 0;
}
#images_wrapper, #content_wrapper {
font-size: 16px;
}
#images_wrapper {
background-color: red;
display: inline-block;
height: 100%;
width: 30%;
margin: 0;
padding: 0;
}
#content_wrapper {
background-color: blue;
display: inline-block;
height: 100%;
width: 70%;
margin: 0;
padding: 0;
}
<div id="product_wrapper">
<div id="images_wrapper">Foo</div>
<div id="content_wrapper">Bar</div>
</div>
Use float:left instead of display:inline-block
#product_wrapper {
display: inline-block;
height: 75%;
width: 75%;
background-color: white;
text-align: top;
margin: 0 auto;
}
#images_wrapper {
background-color: red;
float:left;
height: 100%;
width: 30%;
margin: 0;
padding: 0;
}
#content_wrapper {
background-color: blue;
float:left;
height: 100%;
width: 70%;
margin: 0;
padding: 0;
}
<div id="product_wrapper">
<div id="images_wrapper">Foo</div>
<div id="content_wrapper">Bar</div>
</div>

Resources