Why does display:flex make the div becomes less than 100% width of parent in inspector? - css

I'm a bit confused with how Chrome's browser/dev tools inspector is highlighting the width of a div:
In the following code, .siteFooter_upperFooterFlex__Ut3VI (yellow) visually displays as 100% width of .siteFooter_upperFooterContent__Jt8SZ (light-blue) with the inspector closed, however, when I inspect .siteFooter_upperFooterFlex__Ut3VI (yellow), I see:
Why doesn't the inspector show the yellow background color reaching the full width, which is 100%?
.siteFooter_upperFooterContent__Jt8SZ {
position: relative;
z-index: 20;
padding-top: 3rem;
padding-bottom: 3rem;
background-color: lightblue;
}
.siteFooter_upperFooterFlex__Ut3VI {
display: flex;
align-items: stretch;
justify-content: center;
background-color: yellow;
}
.siteFooter_separatorWrap___XQCE {
display: flex;
align-items: center;
justify-content: center;
}
#media (min-width: 768px) {
.siteFooter_upperFooterLeft__0MGuC {
width: 35%;
padding-left: 4rem;
padding-right: 4rem;
}
.siteFooter_upperFooterRight__FGTWq {
display: flex;
width: 35%;
flex-direction: column;
padding-left: 4rem;
padding-right: 4rem;
}
}
<div class="siteFooter_upperFooterContent__Jt8SZ">
<div class="siteFooter_upperFooterFlex__Ut3VI">
<div class="siteFooter_upperFooterLeft__0MGuC">
<div class="siteFooter_upperFooterTextWrap__Pn_No">
<p class="siteFooter_upperFooterText__ofee9">Quisque varius libero sit amet nisl blandit dictum.</p>
</div>
<div class="siteFooter_upperFooterButton__1p9RV"><a class="buttonLink_black__TlKdt"
href="/contact/sales/">Talk to Us</a></div>
</div>
<div class="siteFooter_separatorWrap___XQCE">
<div class="siteFooter_separator__NRxtG"></div>
</div>
<div class="siteFooter_upperFooterRight__FGTWq">
<div class="siteFooter_upperFooterTextWrap__Pn_No">
<p class="siteFooter_upperFooterText__ofee9">Quisque varius libero sit amet nisl blandit dictum.</p>
</div>
<div class="siteFooter_upperFooterButton__1p9RV"><a class="buttonLink_white__zKdgU"
href="https://sandbox.mandoemedia.com/sandbox-wizard">Quisque varius libero sit amet nisl blandit dictum.</a></div>
</div>
</div>
</div>

This appears to be a quirk of Chromium's dev tools implementation; I suppose it is Chromium trying to be helpful. The dev tools are showing you how much of the flex item's width is taken up by the child elements vs how much is 'padded' by the flex layout (the blueish purple boxes on the left and right edges). Note that I've specified Chromium here, not just Chrome; other Chromium browsers like Edge appear to have this "feature", too.
When you hover, note that the width amount shown (for your screenshot, that's 1157px) is more than the width of each child container added together.
The dev tools in Firefox do not make such a distinction and just show you how much space the flex item effectively takes up (which is the full width).

Related

Extending images from left and right sides of text to edges of screen while maintaining page layout?

I'm trying to design a page header style where two images start from either side of header text, and extend outward to the full width of the screen. Meanwhile, the position of the header text needs to stay left-aligned with the position of the other page content that flows below it, which has a width of 100% but a max-width of 1280px. I don't want the images to be cut off by the text.
Here's an image of what I'm trying to achieve:
Image showing tight width screen vs. large width screen
I want the text to not cut off the circles seen on its left and right sides.
What I've tried:
I've tried positioning the two images using ::before and ::after, however, I haven't found a way to set the start of those pseudo-elements to the start and end of the text span.
I could just set a background image on a full-width container containing the header text, but then I'd have to apply a white background to the header text span, which leads to cutting off of the image as it goes behind the text -- not ideal.
Display:flex gets me closest to the behaviour I want (with left and right divs hugging either side of the div containing the text span and filling the rest of the screen space), however, no straightforward way to make sure the left edge of the text is aligned to the left edge of the rest of the body content. The flex solution works if I wanted centered text, but I need left-aligned text.
CSS grid is something I've considered but it seems like I wouldn't get the hugging behaviour I want while still aligning well with page content.
Thanks!
--EDIT: I tried to include some code of the best solution I have gotten so far which was with display:flex. I had to simplify it from my source code and couldn't get this to run, unfortunately, apologies as I'm quite new to posting on S.O.. --
body {
margin: 0px auto;
width: 100%;
background-color: #333;
}
.page-header {
display:flex;
background-color:#fff;
}
.left {
flex:auto;
background-image: url("[image]");
background-repeat:repeat-x;
background-position: right bottom 20px;
}
.text {
flex:initial;
text-align: center;
max-width: 1280px;
}
.right {
flex:auto;
background-image: url("[image]");
background-repeat:repeat-x;
background-position: left bottom 20px;
}
.body-content-wrapper {
max-width: 1280px;
padding: 2.5%;
background-color: #333;
}
and
<body>
<div class=“page-header”>
<div class=“left”>The left image</div>
<div class=“text”><h1>The page header text</h1></div>
<div class=“right”>The right image</div>
</div>
<div class=“body-content-wrapper”>
[rest of page content]
</div>
</body>
EDIT
Here's an image of what I'm trying to avoid with the header image: it being "cut off" on either side of the text (the left-side dots in the header should start at the left side of the text and extend to the edge of the screen, while the right-side dots should start at the immediate right side of the text and extend rightward to the edge of the screen).
You don't need :before and :hover. As long as you know your max-width then you should be fine with a combination of max-width, setting your left and right margins to auto, and using flexbox for the image columns.
Note that I'm using max-width: 500px in the example below so it fits within the StackOverflow page a bit nicer.
.header {
background-image: url(https://i.imgur.com/Iypn3mA.jpg);
background-position: center center;
background-repeat: repeat-x;
background-size: 50%;
}
.header .container {
display: flex;
}
.header h1 {
background-color: #fff;
padding: 0 10px;
}
.container {
margin: 10px auto;
max-width: 500px;
}
.columns {
display: flex;
flex-direction: row;
}
.columns > * {
flex-grow: 1;
}
.columns > :not(:first-child) {
margin-left: 10px;
}
img {
display: block;
width: 100%;
}
<div class="body">
<div class="header">
<div class="container">
<h1>I am some variable text</h1>
</div>
</div>
<div class="container hero">
<img src="https://via.placeholder.com/2400x800?text=hero" />
</div>
<div class="container columns">
<div>
<img src="https://via.placeholder.com/1000x1000?text=1" />
</div>
<div>
<img src="https://via.placeholder.com/1000x1000?text=2" />
</div>
<div>
<img src="https://via.placeholder.com/1000x1000?text=3" />
</div>
</div>
</div>
I figured out a solution using calc()
You won't see the dots image in this example but can see how the left and right header divs allow me to position the background image relative to the start and end of the page title text, without being cut off by the page title div.
.header-parent {
background-color:#fff;
display:flex;
padding-top: 200px;
}
.body-parent {
position: relative;
margin:0px auto;
background-color: #fff;
width:100%;
max-width:300px;
}
article {
padding: 10px;
}
.left-dots {
width: calc((100% - 300px) / 2);
background-color:#78AA56;
background-image: url("img.png");
background-repeat:repeat-x;
background-position: right bottom 20px;
}
.title {
flex:initial;
min-height: 50px;
margin:0 10px;
}
.right-dots {
background-color:#CC4483;
background-image: url("img.png");
background-repeat:repeat-x;
background-position: left bottom 20px;
flex:auto;
}
<div class="header-parent">
<div class="left-dots"></div>
<div class="title"><h1>Page title</h1></div>
<div class="right-dots"></div>
</div>
<div class="body-parent">
<article>text text text text
Body text
Where its left margin lines up with the page title margin
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac dictum nisi. In vulputate in purus non laoreet. Nullam non ligula congue, porta lorem fermentum, feugiat urna. Quisque mollis nisl et risus malesuada vulputate. Nullam id efficitur odio, quis interdum augue. Praesent volutpat bibendum tellus, non pellentesque arcu. .</article>
</div>

2x2 mobile flex grid with top menu bar

I've been trying - and failing - to get the following grid layout in CSS flexbox (no grid, I need to support older browsers):
As you can see, I need a
Menu bar (dark grey), always on top, always full width and fixed height
a 2x2 grid (blue and white) that's full width on portrait mode and same aspect ratio on landscape
the purple container using the rest of the available space. Stacked below on portrait and to the side on landscape.
I know about media queries, and I guess I need one to limit the .grid width, but I don't know how to get the landscape layout with that.
Looks simple enough but I guess I need your help! :(
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
min-height: 100%;
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex: 1 0 auto;
flex-direction: column;
}
.row {
display: flex;
flex: 1 0 auto;
flex-direction: row;
flex-wrap: wrap;
}
.col {
flex: 1 0 auto;
}
.grid {
width: 50vw;
}
.topbar {
background-color: #1f1f1f;
max-height: 50px;
}
.purple {
background-color: #663353;
}
.purple p {
padding: 2em;
}
.grid:nth-child(3n+1) {
background-color: #6798cc;
}
<div class="container">
<div class="row topbar"></div>
<div class="row wrap">
<div class="col grid"></div>
<div class="col grid"></div>
<div class="col grid"></div>
<div class="col grid"></div>
</div>
<div class="row">
<div class="col purple">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id ipsam rerum laborum velit obcaecati, eveniet reiciendis, veritatis ipsa ducimus recusandae quidem nesciunt dolor facilis sed neque quod.</p>
</div>
</div>
</div>

Balancing block elements like lines of text in print

I would like to achieve a result similar to balancing text lines in print but for block elements. Say a collection of 50/50px boxes in a 300/100px container. Floating the boxes within the container will make them fill up one "row", then wrap onto the next one like this:
[1][2][3][4][5][6]
[7]
I would like them to "wrap" in a more balanced way:
[1][2][3][4]
[5][6][7]
or even better, have them "wrap" at every column filling up space as they go:
[1][3][5][7]
[2][4][6]
I figured you can do this with CSS columns but it feels like a hack because the container element need to be float:left or display:inline-block to force columns to stick together, it needs a constrained height etc. I have added a snippet for reference.
Is there a more genuine CSS way to achieve this?
.wrap {
display: inline-block; /*Needs this so make colums stick together*/
columns: 100px;
column-gap: 0;
height: 200px;
}
.wrap>div {
width: 98px;
height: 98px;
background: red;
/* styling only */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border: 1px solid blue;
}
<div class="wrap">
<div>1Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
<div>2Mauris eu risus.</div>
<div>3Vestibulum auctor dapibus neque.</div>
<div>4Consectetuer adipiscing elit.</div>
<div>5Eu risus.</div>
<div>6Vestibulum auctor dapibus neque.</div>
<div>7Lorem ipsum dolor sit amet</div>
<div>8Aliquam tincidunt mauris eu risus. Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
<div>9Vestibulum auctor dapibus neque.</div>
</div>
Here's a flexbox solution: Using flex-direction: column and flex-wrap: wrap on the parent element you can make the items wrap from top to bottom and fill another column once the column is filled.
This is the code to get flexbox working:
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
And here's a demo:
.wrap {
background-color: silver;
height: 100px;
width: 400px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
}
.box {
height: 50px;
width: 50px;
background-color: red;
box-sizing: border-box;
border: 1px solid white;
}
<div class="wrap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>

How do I get a lone element in the last line of a flexbox layout to look the same?

I'm trying to create some CSS for a list of rectangles, with wrapping, that is responsive. The rectangles can contain a variable amount of text. The rectangles should have a minimum width of 300px, but can grow if there is more space available. It should work no matter the number of rectangles.
This is an image of what I want it to look like, in a wide desktop screen, a normal desktop screen and a phone, roughly:
(I realise that most phone and desktops are wider than that in pixels, but these numbers are easier to work with when it comes to SO's code snippets.)
I'm trying three techniques, and none of them do what I want:
1. Flexbox doesn't work:
Flexbox would seem ideal for this job. The trouble with the flexbox implementation is that I can't find a way to make sure the last rectangle stays the same size as the rest, while also allowing the rectangles to grow in very wide screens. Here's an image of the best flexbox result that I could come up with, which has the problem with the last line:
Here's the code of the flexbox implementation:
.container {
display: flex;
flex-wrap: wrap;
}
.rect {
flex: 1 0 300px;
height: 150px;
}
<div class="container">
<div class="rect" style="background-color: #2F80ED"></div>
<div class="rect" style="background-color: #2D9CDB"></div>
<div class="rect" style="background-color: #56CCF2"></div>
<div class="rect" style="background-color: #A6E2F5"></div>
<div class="rect" style="background-color: #D6EBF2"></div>
</div>
2. float: left technique doesn't work:
Another responsive technique is to use floats, but I can't find a way to keep the rectangles the same width (with varying text content), while also allowing them to grow in the widest screens. Here's an image of what I ended up with:
Here's the code of the float: left implementation:
.container:after {
content: "";
clear: both;
}
.rect {
float: left;
min-width: 300px;
height: 150px;
overflow-y: hidden;
}
<div class="container">
<div class="rect" style="background-color: #2F80ED">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod</div>
<div class="rect" style="background-color: #2D9CDB"></div>
<div class="rect" style="background-color: #56CCF2">Lorem ipsum dolor sit amet, consectetur</div>
<div class="rect" style="background-color: #A6E2F5">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed</div>
<div class="rect" style="background-color: #D6EBF2"></div>
</div>
3. Why not media queries?
I'm looking for a solution that doesn't involve media queries, as media queries only let you put conditions on the screen width, and not on the .container width.
You may keep using flex with an extra element via a pseudo with no height:
.container {
display: flex;
flex-wrap: wrap;
background:gray;/*see me */
}
.container:after {
content:'';
flex: 1 0 300px;
margin-bottom:auto;
}
.rect {
flex: 1 0 300px;
height: 150px;
}
<div class="container">
<div class="rect" style="background-color: #2F80ED"></div>
<div class="rect" style="background-color: #2D9CDB"></div>
<div class="rect" style="background-color: #56CCF2"></div>
<div class="rect" style="background-color: #A6E2F5"></div>
<div class="rect" style="background-color: #D6EBF2"></div>
</div>
:Note that is fine for five, for six boxes behavior is different.
I know you said that you were looking for an answer that didn't involve media-queries, but I believe it would be the best way to handle this situation.
If you set position: relative; on your .container all of it's children will base their width percentage off of .container's width. While technically you would still be basing your conditions off of the screen width you can still set the container width to any size you want and the .rect's will scale to that width, it would just depend on which of your media queries were active for what percentage your .rect's would be scaling to.
You could also set a max-width: for your .container in any of those media queries if you don't want it to grow past a certain size.
Here is a link to a pen which has the layout looking like your intended images above. http://codepen.io/bryanrunner/pen/BppzbE
.container {
position: relative;
display: flex;
flex-flow: row wrap;
max-width: 1200px;
}
.rect {
height: 150px;
}
#media (max-width: 1920px) {
.rect {
width: 20%;
}
}
#media (max-width: 1000px) {
.rect {
width: 50%;
}
}
#media (max-width: 600px) {
.rect {
width: 100%;
}
}

Vertically center, right align, multi-line text in absolutely positioned div with flexbox parent

I have a some absolutely positioned divs with two lines of text, an h2 and a p. I'm trying to get the text to be: centered vertically within the absolutely positioned div, right aligned, and there be a linebreak between the h2 and p tag.
The absolutely positioned divs are contained within a parent so I thought I could use flexbox to solve this problem, but turns out it's harder than expected. I've given the parent display:flex and align-items:center which vertically centers them. But then my h2 and p are on the same line, there's no linebreak.
So then I used flex-direction: column which created a linebreak, but then the text is no longer centered vertically. If I use align-items:flex-end and flex-direction:column the text will be right aligned and there will be a linebreak between the h2 and p, but then they are not centered vertically.
margin-right:auto can supposedly right align items, but combined with align-items:center and flex-direction:column, it doesn't work. float:right also doesn't work.
My markup looks like this:
<div class = "col-sm-12">
<div class = "row overlay-container">
<img src = "_img/top-right#4x.png" class = "img-responsive grid-image" alt = "top-right#4x image" />
<div class = "overlay overlay-2">
<h2>Recent Work</h2>
<p>Lorem ipsum dolor</p>
</div> <!-- /overlay -->
</div> <!-- /row -->
</div> <!-- /top right -->
where overlay is the absolutely positioned div inside the overlay-container. The overlay is a box positioned over a portion of the image. The display:flex and other properties mentioned above are on the overlay class.
It seems that no matter what I try, I can only get two out of the three conditions to work. Using flexbox is not a requirement, but I thought it would make it easy to vertically center the text. Can anyone help?
Here is a sample how to center using display: flex
Stack snippet
body {
margin: 0;
}
.overlay {
width: 300px;
margin-top: 5vh;
height: 90vh;
border: 1px solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div class = "overlay overlay-2">
<h2>Recent Work</h2>
<p>Lorem ipsum dolor</p>
</div> <!-- /overlay -->
Updated
In some situations one might need to use auto margin's instead, as the default behavior when centering with justify-content (when using flex-direction: column) is, when content doesn't fit, it will overflow at both top and bottom.
https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-center
Stack snippet
body {
margin: 0;
}
.overlay {
width: 300px;
margin-top: 5vh;
height: 90vh;
border: 1px solid;
display: flex;
flex-direction: column;
/*justify-content: center; removed */
align-items: center;
overflow: auto; /* scroll when overflowed */
}
.overlay h2 {
margin-top: auto; /* push to the bottom */
}
.overlay p {
margin-bottom: auto; /* push to the top */
}
<div class = "overlay overlay-2">
<h2>Recent Work</h2>
<p>Lorem ipsum dolor</p>
</div> <!-- /overlay -->
Updated 2
Here with a 3rd item in the middle, what will scroll when not fit.
Stack snippet
body {
margin: 0;
}
.overlay {
width: 300px;
margin-top: 5vh;
height: 90vh;
border: 1px solid;
display: flex;
flex-direction: column;
align-items: center;
}
.overlay p:first-of-type {
overflow: auto; /* scroll when overflowed */
}
.overlay h2 {
margin-top: auto; /* push to the bottom */
}
.overlay p:last-of-type {
margin-bottom: auto; /* push to the top */
}
<div class = "overlay overlay-2">
<h2>Recent Work</h2>
<p>
Lorem ipsum dolor<br>
Lorem ipsum dolor<br>
Lorem ipsum dolor<br>
Lorem ipsum dolor<br>
Lorem ipsum dolor<br>
Lorem ipsum dolor<br>
Lorem ipsum dolor<br>
</p>
<p>Maybe a link for more</p>
</div> <!-- /overlay -->
Another sample:
How to fix height the content inside a div with flex css

Resources