I'm building my first website, and I am having some issues figuring out how to combine a wrapper that limits the max-width of the content and using flexbox on a section.
A typical section of my website would look like:
<section class="hero flex">
<div class="wrapper">
<h1>Content 1</h1>
<p>Content 2</p>
<button>Content 3</button>
</div>
</section>
I am running into the following problems:
When adding the wrapper div between section & the content, the content is no longer direct children of section, and thus are not affected by the flexbox. Therefore I cannot center the content.
If I put the classes .hero and .wrapper on the section tag, the background color is affected by the width/max-width of wrapper
I'm sure that I'm running into more problems that I still haven't found yet. I am therefore interested in how to use a wrapper for limited max-width together with flexbox sections.
.hero{
max-width: 700px;
}
.wrapper{
width: 100%;
display: flex;
justify-content: space-between;
}
<section ="hero flex">
<div class="wrapper">
<h1>Content 1</h1>
<p>Content 2</p>
<button>Content 3</button>
</div>
</section>
Related
If you’re trapped in a page wrap - say all the contents of the page are in a div whose width is 900px, then you want one div WITHIN that that’s the full page width. What’s the easiest way to do this?
I know you can end the 900px div, do the full width div, and then start another 900px div, but is there a way to style the inner div so you don't have to escape it? 100vw works for making it the right size but doesn't position it in the right spot.
So simplistic example:
<div style="width:900px;margin-right:auto;margin-left:auto;display:block;">
<p>text text</p>
<div style="width:100vw;">
<p>I want this section to be the full page width and centered</p>
</div>
<p>text text</p>
</div>
Thanks!
You can use negative left margin (-50vw + half parent width).
body {margin: 0;}
#a {background: red;}
#b {background: green; margin-left: calc(-50vw + 200px)
<div id="a" style="width:400px;margin-right:auto;margin-left:auto;display:block;">
<p>text text</p>
<div style="width:100vw;" id="b">
<p>I want this section to be the full page width and centered</p>
</div>
<p>text text</p>
</div>
For this code example I've added IDs (for cleaner CSS styles) and change parent div to 400px (because there is smaller window).
I don't recommend trying to make a child div "escape" its parent because going with that approach will require pointlessly complicated CSS. You can accomplish what you want with a container div and a couple nested children which is a much simpler solution:
.narrow {
width: 300px;
margin: 0 auto;
background-color: tomato;
padding: 16px;
}
.full {
background-color: gold;
padding: 16px;
}
<div>
<div class="narrow">
<p>text text text</p>
</div>
<div class="full">
<p>more text or image or whatever</p>
</div>
<div class="narrow">
<p>text text text</p>
</div>
</div>
I would argue that the way you are trying to solve the issue is not very helpful for an actual website. Normally, you would have a container, your top div, which contains its lower elements. Making a child element go outside its parent div like you seem to want goes against that mentality.
Of course, sometimes you may want to put an element outside its parent, and you can use pavel's answer. For example, maybe you want to animate a line moving. You would then offset that element by -100% and then change that offset to give it the impression of movement. But that would be a special case.
To solve your problem, I would use the following structure:
Here is a link to the example too.
<div class='container'>
<div class='thin'>
<p>text text</p>
</div>
<div class='full-width'>
<p>I want this section to be the full page width and centered</p>
</div>
<div class='thin'>
<p>text text</p>
</div>
</div>
.container{
text-align:center;
padding: 0 5vw; //padding of 5vw to the left and right
}
.thin{
width:80vw;
margin: 0 auto;
background-color:yellow;
}
.full-width{
background-color:green;
}
I am building a personal website, and have been using a lot of flexbox to attain the layout I want. I recently ran into an issue that I cannot seem to solve. Where the items in my flexbox container seem to be spilling out and into other containers, such as my header container or past the bottom of where the page should end.
<div class="main-container">
<div class="header">
<h1>John Doe</h1>
<h2>Test</h2>
</div>
<div class="content-container">
<div class="projects">
<div class="content-container">
<div>
<h1>project</h1>
<p>project text</p>
</div>
<div>
<h1>project</h1>
<p>project text</p>
</div>
<div>
<h1>project</h1>
<p>project text</p>
</div>
<div>
<h1>project</h1>
<p>project text</p>
</div>
</div>
</div>
</div>
</div>
https://codepen.io/anon/pen/XYBbgE
I wanted to use a flexbox layout for my projects section so that the content will be centered, and I like how easy it is to do that with flexbox. If you adjust the height of the codepen container by either increasing the height OR reduce it, you can see that the header is hiding some of the elements.
I have included some HTML to kind of show the layout. I have excluded a lot to conserve space, however the codepen link is much closer to what the actual design looks like.
EDIT: I made a gif demonstrating the behavior that I am having an issue with
gif of flexbox problem
As you can see, as I adjust the height, the header of my page appears to cover up some of the items beneath it. I also cannot scroll higher than what the height is, if that makes sense.
To point out your error, it's the alignment of item's, for all elements you have aligned it center vertically. so it seemed out of a container as it's height was more than viewport. You can fix it by align-items: center; to align-items: flex-start;
.projects {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: flex-start;
}
and to let you know, i think you are using too flex for everything which can be achieved without it easily
Isn't the first time I want all content inside all sections are in a container with a max-width, but the only solution is duplicate html tags. Something like this:
<body>
<section class="one">
<div class="wrapper">
// content for one
</div>
</section>
<section class="two">
// There is a background here
<div class="wrapper">
// content for two
</div>
</section>
<section class="three">
<div class="wrapper">
// content for three
</div>
</section>
<section class="four">
// There is a background here
<div class="wrapper">
// content for four
</div>
</section>
</body>
Putting a div "wrapper" inside looks like the only solution to control every section with a max-width/centered and keeps the ability to put a full-width backgound in few section.
I don't like this solution, is a div duplicated for every section with same properties. If someday I change my mind and want remove it or I need to do it in every section or I need to remove css to that selector. Its look not semantical for me.
Any solution?
I would create a div like this
<div id="maindiv">
<div id="sitecontainer">
<!-- inner content -->
</div>
</div>
Then you can control max width from one place for all section. IF you don't want max width for a section, remove the site container div from within that section. You change your mind on the width? Change it in one place. You decide to go 100% width, change the width to 100% inside that div. Makes it easy to manage sitewide..
Your css
#sitecontainer { float: left; width: 1000px; margin: 0 auto; }
#maindiv { float: left; width: 100%; }
Then if you add another div,
<div id="secondarydiv">
<div id="sitecontainer">
// content still 1000px centered
</div>
</div>
The container's background-image should fit the navigator width, but the content should have a maximum width of 800px. So when I zoom out, the content does not spread along the navigator's width in an ugly form.
I want to know if this is possible just with my current html code, I do not want to add another tag in my html.
This is my code:
.container{
display:flex;
flex-wrap:no-wrap;
background-image: /* some huge image */
}
.container div{
flex:1;
}
<div class="container">
<div>
<h1>Section 1</h1>
<p>Some text</p>
</div>
<div>
<h1>Section 2</h1>
<p>Some text</p>
</div>
<div>
<h1>Section 3</h1>
<p>Some text</p>
</div>
</div>
Here is a CODEPEN with some cosmetics
Parent div: Navigation
Make a child div inside the parent, set the width on the child to be 800px.
Center (or wherever) the child div with margin: 0 auto;
Put content within child.
Edit: oops I guess that's what you didn't want to do, sorry.
You can set container max-width:800px; and margin:0 auto;
You would need 2 containers for your items.
Like
<div id="main-container">
<div class="container">
</div>
</div>
So you can set a max-width that contains the items but not affecting the width of the container with the background.
Here's your updated code
If I try to apply min-width, max-width to a floating div so that it expands to max-width when the right content is hidden does not work.
But, if I use table and 2 tds in it, the left td will expand to 100% if the right td is hidden.
Can I achieve this table effect with floated divs?
I don't think you can do what you are asking, but you can make it look like what you are asking.
Make it into two tds and put a max-width on a div inside the td. Would that work?
This isn't going to work with floats. Luckily we now have more tools at our disposal.
Here are two very simple methods to expand a div to 100% of the available width if a sibling horizontally to it is hidden or removed.
#1 – Using display: flex
Compatibility: Edge and all modern browsers. IE 10 and 11 support the non-standard -ms-flexbox.
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container div is given display: flex.
The containers children are give flex: 1 and they will be assigned equal width, can grow and can shrink.
.container {
width: 500px;
display: flex;
}
.container>div {
flex: 1;
background: #FF6961;
height: 200px;
margin-bottom: 20px;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
Read this guide to flexbox
Read more about flexbox on the MDN
#2 – Using display: table
Compatibility: IE8+ and all modern browsers
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container is given display: table
The containers children are given display: table-cell and will act the same as cells in an HTML table. If a cell is hidden or is removed the other cell will take its space.
.container{
display: table;
width: 600px;
margin: 20px;
}
.container>div {
display: table-cell;
height: 200px;
background: #FF6961;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
<div class="container">
<div>
Content takes up the remaining width if a cell has a fixed width.
</div>
<div style="width: 200px">
Content
</div>
</div>
Read more about CSS tables on the MDN