Flexbox - weird content overflows on specific widths - css

Take a look at this CodePen
The text in the 3rd panel (Spelling) overflows without any obvious reason - both on Chrome and Firefox:
I don't know if it is related - but the 2nd panel (Quiz: Leapfrog) takes more space horizontally than is needed for its contents - about 15-16 pixels:
If you play with the inline style of the card and change the max-width: from 478px to 470px and below, or to 511px and above - the overflow goes away.
May I get some help in understanding why this weird overflow happens and how to prevent it?

You're missing a flex-basis: 0 /* or 50% in your case could also work */ on your 3 items to help flex understand how things work together.
Have you tried to use css display: grid;?
Here is an example:
.wrapper {
display: grid;
width: 350px;
height: 160px;
background: #fafafa;
grid-gap: 10px;
grid-template-areas:
"first first"
"second third";
}
.child {
text-align: center;
font-family: sans-serif;
font-size: 24px;
font-weight: 800;
}
#child1 {
background: #0e6376;
grid-area: first;
}
#child2 {
background: #f9b4af;
grid-area: second;
}
#child3 {
background: #f15c3b;
grid-area: third;
}
<div class="wrapper">
<div class="child" id="child1">child1</div>
<div class="child" id="child2">child2</div>
<div class="child" id="child3">child3</div>
</div>

Okay, after more than 3 hours of scratching my head and no help from anyone I suddenly and out of nowhere decided to set a min-width on the white squares which contain the icons:
.activity_icon
{
border-radius: inherit;
flex: 0 0 60px;
min-width: 60px; /* <==== added */
height: 60px;
}
And voila - the Flexbox parent now properly wraps the Flexbox children.

Related

Place div between divs in mobile in plain css

I trying to place a div between divs for a mobile screen.
I don't want to use javascript, just plain css. Is there a way to achieve it?
I'm experimenting with flexboxes order but can't reach my goal.
.parent {
display: flex;
justify-content: flex-start;
}
.left {
background-color: yellow;
padding: 20px;
width: 50%;
}
.left-1 {
background-color: greenyellow;
padding: 20px;
}
.left-3 {
background-color: gray;
padding: 20px;
}
.right {
background-color: cyan;
padding: 20px;
width: 50%;
}
<section class="parent">
<div class="left">
<div class="left-1">1</div>
<div class="left-3">3</div>
</div>
<div class="right">2</div>
</section>
The easiest way to achieve your desired outcome is to use CSS grid layout, which allows for all elements to be siblings, along with a media-query:
/* simple reset to ensure all element sizes are calculated the same way,
and with the same base-styles: */
*,
::before,
::after {
box-sizing: border-box;
font-size: 16px;
font-family: system-ui, sans-serif;
font-weight: 400;
margin: 0;
padding: 0;
}
.parent {
/* using CSS Grid for layout: */
display: grid;
/* setting a gap between adjacent-elements,
(shorthand for 'row-gap' and 'column-gap') */
gap: 0.5em;
/* defining named areas for the contents to be positioned,
based on rows; the first row comprises of one area named:
'leftTop' and the second named 'main'; the second row
has 'leftLower' and 'main'; the reason that 'main' appears
twice is that we want the element in that position to span
across both rows: */
grid-template-areas:
"leftTop main"
"leftLower main";
/* setting height and width to be full-screen: */
width: 100vw;
height: 100vh;
/* setting padding, so that there is a visible gap between the
elements and the page's borders (obviously, adjust to taste): */
padding: 0.5em;
}
/* writing the common styles shared by all child-elements into the same
place for ease of maintenance/updates: */
.parent div {
padding: 20px;
}
/* the left-1 and left-2 elements will be laid out automatically according
to their order in the DOM, once any grid-items (the 'left-1', 'left-2',
and 'right' elements) have been allocated their specific places according
to the author's design: */
.left-1 {
background-color: greenyellow;
}
.left-3 {
background-color: gray;
}
.right {
background-color: cyan;
/* here we explicitly place this element into the named (but not quoted)
main grid-area: */
grid-area: main;
}
/* when the screen falls below 450px in width (obviously adapt to your own
requirements): */
#media screen and (max-width: 450px) {
/* the grid-template-areas are redefined into three single-column rows: */
.parent {
grid-template-areas: "topLeft" "main" "lowerLeft";
}
}
<section class="parent">
<!-- removed the wrapper 'left' column element, in order to allow the
'right' element to be positioned between the 'left-1' and 'left-3'
elements when the screen-size changes: -->
<div class="left-1">1</div>
<div class="left-3">3</div>
<div class="right">2</div>
</section>
JS Fiddle demo.
References:
box-sizing.
display.
font-family.
font-size.
font-weight.
gap.
grid-template-areas.
margin.
#media queries.
padding.
Bibliography:
"A Complete Guide to Grid."
"Basic Concepts of grid layout."
"CSS Grid Layout."

Float on Google Chrome and Microsoft Edge

I'm using float to align 3 div ( left, center, right ). the first picture show how it looks on
on Google Chrome. the second picture show how
it looks on Microsoft Edge . a float works fine on Google Chrome, when using Microsoft Edge the last div(right) moved to a left-bottom container. why this is happens
* body,
p,
img {
margin: 0;
}
.container {
width: 900px;
border: 5px solid green;
padding: 3px;
margin: auto;
}
.left {
background-color: blueviolet;
width: 150px;
height: 300px;
line-height: 100px;
text-align: center;
float: left;
}
.center {
width: 600px;
height: 300px;
background-color: burlywood;
float: left;
}
.right {
width: 150px;
height: 300px;
background-color: coral;
float: left;
}
.clear {
clear: left;
}
<div class="container">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
<div class="clear"></div>
</div>
The CSS you wrote make the output appear as in the picture. In your container you used border and padding. The two will cause the actual width of the container to be less than 900px on some browser. So the width is 900 - (5 + 5) - (3 + 3) = 884px.
Possibly, chrome tried to understand what you want, but Edge give you actual output. This is expected as border and padding affect the final width of div containers. Though, setting margin does not affect it.
To resolve the issue and cause the three dogs to appear on same line on all browser, i.e the coral div to appear on the right, you will add the following CSS to your container (or preferably body tag):
box-sizing: border-box;
You can read more at https://css-tricks.com/box-sizing/
Don't forget to add all the Vendor Prefixes

Force Square Div

I am trying to create two sections, one left and one right, where one of them is a image and the other one is text. They should always be the same width and height and always square. I use the Avada theme on Wordpress and trying to fix this with their Element Builder and custom css. No luck.
Here is a page where the resault is not square but responsive:
https://sundlof.se/devskargard/
I have found some codes that does force div to be square but they donĀ“t take the other square in to the equation. If this requires jQuery, please tell me, I have not yet tried that, I really what to get this done with css if possible.
Any ideas will be much appreciated!
Regards,
Fredrik
You can use display:flex to on the square wrapper and give it a height. This will always result in flex-child taking height of its immediate flex parent.
You can then plugin some media-queries to make this flex grid responsive using flex-wrap property
body {
padding: 20px;
box-sizing: border-box;
}
.flex {
display: flex;
justify-content: center;
border: 1px solid black;
height: 250px;
}
.section {
align-items: center;
width: 50%;
border: 1px solid black;
margin: 5px;
}
<div class="flex">
<div class="section">Section 1</div>
<div class="section">Section 2</div>
</div>
You Just go through following links then you will get an idea about the aspect ratios and responsive blocks.
Learn how to maintain the aspect ratio of an element with CSS.
Aspect Ratio Boxes Advanced
<div class="container">
<div class="text">1:1 Aspect ratio</div>
</div>
.container {
background-color: red;
position: relative;
width: 100%;
padding-top: 100%; /* 1:1 Aspect Ratio */
}
.text {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
font-size: 20px;
color: white;
}
Example
Thanks for the help!
I ended up to justify the square with media querys every 200 och 300px to keep it close to square. Not a beautiful solution, but a simple one.

Having trouble in vertically center aligning a div with block of texts

https://jsfiddle.net/n00q5wdn/
Please refer to fiddle for the output plus I'm linking an image so that the problem may be understood more clearly.
I just want to have the 'hgroup' to be vertically centered.
HTML:
<article id="full-height">
<div class="hgroup">
<h1>Exotic Designs</h1>
<h2>Best Quality</h2>
</div>
</article>
SCSS:
#full-height {
background-color: red;
min-height: 600px;
}
.hgroup {
h1 {
color: white;
font-size: 5em;
font-weight: 800;
line-height: 0.8em;
text-shadow: black 0 0 20px;
text-align: center;
}
h2 {
display: block;
color: white;
width: 60%;
max-width: 200px;
margin: 0 auto;
text-align: center;
border: 1px solid white;
margin-top: 15px;
padding: 10px;
background: rgba(0, 0, 0, 0.5);
font-size: 1.3em;
}
}
The best fit for this kind of problem is flexbox, which uses the Box Alignment spec, specifically created for these situations.
If you set the #full-height-element to display as a flex row container, you can align the contents with align-items (vertically) and justify-content (horizontally).
#full-height {
display: flex;
align-items: center;
justify-content: center;
}
See forked fiddle here.
This will work in most modern browsers, and if you run it through something like Autoprefixer you can get it working in some slightly older browsers as well (IE10, older Safari etc). IE9 and other ancient browsers do not support flexbox, so I recommend a fallback with either the .hgroup element having a fixed margin, or just top aligned etc. If you can get away with a fixed, explicit height of the container, there's another, more hacky and involved solution:
I see you have dabbled with inline-block and vertical-align to try and use the middle keyword for vertical centering. That will only work if you can set a definite height on the #full-height container, and use a "ghost"-element to force the line-height calculation to cover the box, for example:
#full-height {
height: 600px;
text-align: center; /* horizontal centering */
}
/**
* "ghost element", to force the calculation of the
* middle keyword to equal the vertical middle of
* the box.
*/
#full-height:before {
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
/* offset the whitespace generated by inline-block.
May vary with font-size. */
margin: -.25em;
}
.hgroup {
display: inline-block;
vertical-align: middle;
}
See jsbin example for this solution here.

Page-filling flexbox layout with top and side bars not quite working

The layout I am trying to achieve is like this, exactly filling the entire viewport of the browser:
[----fixed height top "menu bar"----]
/-----\/----------------------------\
|fixed|| |
|width|| both ways stretchy content |
|side || |
|bar || |
\-----/\----------------------------/
I have it nearly working, but I haven't figured out how to specify that the horizontally-arranged boxes vertically fill the space available to them rather than the height of the page. As it currently stands, whenever the content in the sidebar is long enough to cause it to gain a scroll bar, I end up with an additional vertical scrollbar on the entire page which scrolls by exactly the height of the top bar, which is not what I want.
The following 1998-styled demo page illustrates the problem. It actually produces the layout I want in Safari 9, but not Chrome or Firefox.
Note these additional constraints, which are already satisfied by the demo and must be preserved:
There may be an arbitrary number of fixed-width or stretchy boxes arranged in the horizontal direction.
Each side bar or main content has an overflow-y: auto vertical scrollbar. This must also work (that is, long content must not make the overall flexbox layout exceed the viewport size). Some of the sidebars themselves use flexbox layout in the vertical direction.
A 90%-10% layout is not suitable for the purpose. Nor is allowing some of the content to be clipped. The entire reason I have this layout problem is that the application should be using every pixel of the screen to show useful information or controls, so any extra whitespace or clipped content is undesirable.
<!doctype html>
<html style="height: 100%;">
<title>Flexbox test</title>
<style type="text/css">
#parent-of-topbar {
height: 100%; box-sizing: border-box; margin: 0;
background: #FCC;
display: flex; flex-direction: column;
}
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 .3em 0;
color: black;
flex: 0 0 auto;
}
#main {
display: flex; flex-direction: row;
flex: 1 1 auto;
max-height: 100%;
}
.subwindow {
overflow-x: clip;
overflow-y: auto;
max-height: 100%;
border: 3px outset #CCC;
background: linear-gradient(to right, #CCC 0%,#AAA 100%);
}
.fixed {
flex: 0 0 auto;
width: 10em;
}
.stretchy {
flex: 1 1 auto;
width: 100%;
}
</style>
<body id="parent-of-topbar">
<div id="topbar">top bar content</div>
<div id="main">
<div class="subwindow stretchy">stretchy part</div>
<div class="subwindow fixed">
fixed sidebar 1; this should be scrollable, not stretch the content
<details open><div style="font-size: 3em;">spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam</div></details>
</div>
<div class="subwindow fixed">
2nd fixed sidebar
</div>
</div>
</body>
Here is a screenshot of the layout I want to achieve, faked by hardcoding a dimension:
Here is a screenshot of the layout the current demo gets on Chrome:
UPDATE
After a bit of back and forth in the comments we came up with the solution. It's a simple fix, but wasn't simple to discover.
The answer boils down to this:
In the original code, the horizontal boxes are wrapped in a container having flex: 1 1 auto.
For the layout to work the container needs to have flex: 1 1 0 (or flex: 1, for short).
The original code caused a vertical scrollbar on the viewport window because flex: 1 1 auto sizes the item based on content size or height properties.
The adjusted code results in a layout that fits neatly in the viewport because flex: 1 1 0 sizes the item based on the free space in the flex container.
DEMO
The flexbox spec goes into more detail in section 7.1.1. Common Values of flex.
I have it nearly working, but I haven't figured out how to specify that the horizontally-arranged boxes vertically fill the space available to them rather than the height of the page. As it currently stands, whenever the content in the sidebar is long enough to cause it to gain a scroll bar, I end up with an additional vertical scrollbar on the entire page which scrolls by exactly the height of the top bar, which is not what I want.
Each side bar or main content has an overflow-y: auto vertical scrollbar [which must be preserved].
You have two flex items: #topbar and #main.
The height of #topbar is based on content, padding and border (it has no specified height).
The height of #main is max-height: 100% (which, on Chrome and FF, computes to height: 100%).
When you add these two heights together the sum exceeds the height: 100% applied to their container (#parent-of-topbar). That's the reason for the vertical scrollbar on the body.
Solution #1
The simplest way to resolve this issue, while preserving the vertical scrollbar on the content boxes, is to use overflow: hidden.
Add this to the CSS:
body { height: 100%; overflow: hidden; }
DEMO: http://jsfiddle.net/mwfkLu8b/
This is a blunt force object method. It gets the job done quickly, easily and effectively, but it costs you the lower portion of the screen. In other words, overflow: hidden clips the area where the vertical scrollbar was going.
Solution #2
Another method to resolve the issue, which also preserves the vertical scrollbar on content boxes, but doesn't clip any content, is to distribute the 100% height among flex items.
Try this:
* { box-sizing: border-box; } /* new */
body { height: 100%; } /* new */
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 .3em 0;
color: black;
flex: 0 0 auto;
height: 10%; /* new */
}
#main {
display: flex;
flex-direction: row;
flex: 1 1 auto;
/* max-height: 100%; */
height: 90%; /* new */
}
DEMO: http://jsfiddle.net/mwfkLu8b/1/
If #topbar needs to be a fixed height, then you can use pixels and calc to equal 100%.
#topbar { height: 40px; }
#main { height: calc(100% - 40px); }
DEMO: http://jsfiddle.net/mwfkLu8b/2/
Thanks to Michael_B's answer and comments, I've figured out the solution which works for the demo as well as my actual application.
The key rule is: do not use height: 100%; or width: 100%; anywhere inside of flexbox. Use flex-grow to make things expand to fit their containers, even if this means converting the content of the .subwindow elements to flexbox layout where it wasn't before.
Furthermore, do not set flex-basis: auto (directly or via the flex shortcut) on stretchy things. Instead use flex-basis: 0% (or any zero length), which is implicitly done by flex: <number>;, and let the growing take care of filling the container. I'm still not sure whether this is necessary if you follow the first rule absolutely, but it seems to help in imperfect cases.
Revised demo (now showing a 100%-like main panel as my real application had, which was another complication):
<!doctype html>
<html style="height: 100%;">
<title>Flexbox test</title>
<style type="text/css">
#parent-of-topbar {
height: 100%; box-sizing: border-box; margin: 0;
background: #FCC;
display: flex; flex-direction: column;
}
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 .3em 0;
color: black;
}
#main {
display: flex; flex-direction: row;
flex: 1;
}
.subwindow {
overflow-x: clip;
overflow-y: auto;
border: 3px outset #CCC;
background: linear-gradient(to right, #CCC 0%,#AAA 100%);
display: flex;
flex-direction: column;
}
.fixed {
flex: 0 auto;
width: 10em;
}
.stretchy {
flex: 1;
}
</style>
<body id="parent-of-topbar">
<div id="topbar">top bar content</div>
<div id="main">
<div class="subwindow stretchy">
<div style="background: #CFC; flex: 1; vertical-align: middle; text-align: center;">stretchy content</div>
</div>
<div class="subwindow fixed">
fixed sidebar 1; this should be scrollable, not stretch the content
<details open><div style="font-size: 3em;">spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam</div></details>
</div>
<div class="subwindow fixed">
2nd fixed sidebar
</div>
</div>
</body>
Not totally clear on what you want exactly, so let me know so I can accommodate. You mentioned content being in viewport. so I used vh and vw.
html {
box-sizing: border-box;
font: 400 16px/1.5 small-caps"Trebuchet MS";
}
*,
*:before,
*:after {
box-sizing: inherit;
margin: 0;
padding: 0;
border: 0 solid transparent;
outline: 0;
text-indent: 0;
}
body {
background: #FCC;
color: #000;
position: relative;
display: flex;
flex-direction: column;
height: 95vh;
width: 100vw;
}
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 2px 0;
color: black;
line-height: 1.4;
max-height: 32px;
flex: 2 0 32px;
}
#main {
display: flex;
flex-direction: row;
flex: 1 0 auto;
max-height: 100%;
}
.subwindow {
overflow-x: clip;
overflow-y: auto;
max-height: 110%;
outline: 3px outset #CCC;
background: linear-gradient(to right, #CCC 0%, #AAA 100%);
}
.fixed {
width: 10em;
}
.stretch {
flex: 1 0 10em;
width: 100%;
}
details > div {
font-size: 3em;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Flexbox test</title>
</head>
<body>
<header id="topbar">Header</header>
<main id="main">
<section class="subwindow stretch">
<h3>Section 1</h3>
<h4>Expanding Section</h4>
</section>
<section class="subwindow fixed">
<h3>Section 2</h3>
<h4>Scrolling Section</h4>
<details open>
<div>spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam</div>
</details>
</section>
<section class="subwindow fixed">
<h3>Section 3</h3>
<h4>Static Section</h4>
</section>
</main>
</body>

Resources