I have the following snippet of html that forms an X-Y scrollable listbox
* {
font-family: "consolas";
}
.listbox {
border: 1px solid black;
padding: 4px;
width: 150px;
height: 200px;
display: flex;
flex-direction: column;
}
.caption {
font-weight: bold;
background-color: #aaf;
padding: 10px;
}
.content {
flex-grow: 1;
overflow: scroll;
}
.item {
background-color: #ddd;
padding: 2px;
padding-left: 6px;
margin-top: 4px;
white-space: nowrap;
}
<div class="listbox">
<div class="caption">Caption</div>
<div class="content">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three (this has a longer bit)</div>
<div class="item">Four</div>
<div class="item">Five</div>
<div class="item">Six</div>
<div class="item">Seven</div>
<div class="item">Eight (so does this)</div>
<div class="item">Nine</div>
<div class="item">Ten</div>
</div>
</div>
It's working fine, with one problem, as the user scrolls from left to right, the background of the div seems to get left behind. It's as though the actual div only stretches the width of its parent, and the scrolling/overflow thing is "faked" somehow.
Why is this the case?
How do I address the problem? The behaviour I want is for all the items to appear to be the same width as the largest one.
Try adding a container <div class="items"> around the items set it to display:inline-block.
.items {
display: inline-block;
}
* {
font-family: "consolas";
}
.listbox {
border: 1px solid black;
padding: 4px;
width: 150px;
height: 200px;
display: flex;
flex-direction: column;
}
.caption {
font-weight: bold;
background-color: #aaf;
padding: 10px;
}
.content {
flex-grow: 1;
overflow: scroll;
}
.items {
display: inline-block;
}
.item {
background-color: #ddd;
padding: 2px;
padding-left: 6px;
margin-top: 4px;
white-space: nowrap;
}
<div class="listbox">
<div class="caption">Caption</div>
<div class="content">
<div class="items">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three (this has a longer bit)</div>
<div class="item">Four</div>
<div class="item">Five</div>
<div class="item">Six</div>
<div class="item">Seven</div>
<div class="item">Eight (so does this)</div>
<div class="item">Nine</div>
<div class="item">Ten</div>
</div>
</div>
</div>
Explanation: by default a block level element takes 100% width of the container no more than that, however an inline block will expand to content length if available e.g. in a scrollable container.
Also apply .items {min-width: 100%;} in case you want the background to grow full width even with less text in every row.
Related
First of all, here is a codepen with the issue I am trying to solve.
This is a simplified version of the problem I have on an actual project. My goal is to keep the grid in the same format with 5 columns and to be able to increase the width of these cells so the content is always visible, but also so that it doesn't wrap before the first row of 5 columns is displayed. Whenever I try to increase the width of the cells the grid wraps and I lose the structure I want.
So, basically, increase width of items, but prevent wrapping, is it possible? It is fine if the content overflows the flex container itself, the goal is to add overflow-x to this grid.
.flex-container {
border: 1px solid silver;
display: flex;
width: 50%;
}
.wrap {
flex-wrap: wrap;
}
.wrap div {
background: gold;
}
.flex-item {
width: 160px;
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
}
<div class="flex-container wrap">
<div class="flex-item">11111111111111</div>
<div class="flex-item">22222222222222</div>
<div class="flex-item">33333333333333</div>
<div class="flex-item">44444444444444</div>
<div class="flex-item">55555555555555</div>
<div class="flex-item">66666666666666</div>
<div class="flex-item">77777777777777</div>
<div class="flex-item">88888888888888</div>
<div class="flex-item">99999999999999</div>
<div class="flex-item">00000000000000</div>
</div>
From the comments, it does look like grid is the option you need, it won't allow content to be wrapping and justify content will stick it on the side if shorter thant the width of the container.
here is the snippet with grid:
/* flex turned into grid */
.flex-container {
border: 1px solid silver;
display: grid;
grid-template-columns:repeat(5,auto);
justify-content:start;
overflow:auto;
width: 80%;
}
.wrap {
}
.wrap div {
background: gold;
}
.flex-item {
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
}
<div class="flex-container wrap">
<div class="flex-item">11111111111111</div>
<div class="flex-item">22222222222222</div>
<div class="flex-item">33333333333333</div>
<div class="flex-item">44444444444444</div>
<div class="flex-item">55555555555555</div>
<div class="flex-item">66666666666666</div>
<div class="flex-item">77777777777777</div>
<div class="flex-item">88888888888888</div>
<div class="flex-item">99999999999999</div>
<div class="flex-item">00000000000000</div>
</div>
I think, if it is allowable, that css grid may be a better candidate for the layout you are proposing...
.grid-container {
border: 1px solid silver;
display: grid;
width: 50%;
grid-template-columns: 20% 20% 20% 20% 20%; /* hard set five columns and no more */
}
.grid-container div {
background: gold;
}
.grid-item {
/* width: 160px; */
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
overflow-x: hidden; /* overflow-x to hide overflow as discussed in question */
}
<div class="grid-container">
<div class="grid-item">11111111111111</div>
<div class="grid-item">22222222222222</div>
<div class="grid-item">33333333333333</div>
<div class="grid-item">44444444444444</div>
<div class="grid-item">55555555555555</div>
<div class="grid-item">66666666666666</div>
<div class="grid-item">77777777777777</div>
<div class="grid-item">88888888888888</div>
<div class="grid-item">99999999999999</div>
<div class="grid-item">00000000000000</div>
</div>
.flex-container {
display: flex;
flex-wrap: wrap;
background-color:red;
}
.flex-container > div {
background-color: #f1f1f1;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
word-wrap: break-word;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="flex-container">
<div>11111111111111</div>
<div>22222222222222</div>
<div>33333333333333</div>
<div>44444444444444</div>
<div>55555555555555</div>
<div>66666666666666</div>
<div>77777777777777</div>
<div>88888888888888</div>
<div>99999999999999</div>
<div>00000000000000</div>
</div>
</body>
I have 3 divs which are horizontally aligned (aqua color). Inside each div, there are two divs (red and black one).
What I am trying to do is, align the black divs horizontally regardless of the red div. The css for the black div is
.black-div {
width: 100%;
height: 45px;
max-width: 235px;
display: inline-block;
color: #33244a;
font-size: 16px;
text-transform: uppercase;
font-weight: normal;
text-align: center;
line-height: 43px;
border: 2px dashed #d5d1d8;
border-radius: 6px;
box-sizing: border-box;
}
Output will something like this
I am not good at all in css. I have tried using position: fixed / absolute but no luck.
Try it.
Use div and min-height.
section{
display: inline-block;
border: 1px solid red;
width: 100px;
}
.textarea-wrap{
overflow: hidden;
min-height: 200px;
}
.textarea-wrap > textarea{
width: 100%;
resize: none;
}
.red{
background-color: red;
}
<div>
<section>
<div class="textarea-wrap">
<textarea rows="3">12312312</textarea>
</div>
<div class="red">
red
</div>
</section>
<section>
<div class="textarea-wrap">
<textarea rows="10">12312312</textarea>
</div>
<div class="red">
red
</div>
</section>
<section>
<div class="textarea-wrap">
<textarea rows="6">12312312</textarea>
</div>
<div class="red">
red
</div>
</section>
</div>
You should use table to make it more manageable, or use absolute positioning on the black div so you can position them measure from the bottom of the blue div.
There may be a solution without the spacer. Im looking for it :)
found solution without spacer justify-content: space-between;
.wrapper {
display: flex;
flex-direction: row; /* flex in a row inside (make columns .col) */
}
.col {
display: flex;
flex-direction: column; /* flex in a column inside */
justify-content: space-between; /* since the elements must not grow, fill the space between them */
flex: 1 1 100px; /* grow and shrink of col allowed to fill row evenly starting at 100px*/
margin: 5px;
border: 3px solid black;
background-color: aqua;
}
.red {
flex: 0 1 auto; /* no vertical (col) growing (so it does not expand vertically) */
border: 3px solid black;
border-radius: 10px;
background-color: red;
margin: 5px;
padding: 10px;
}
.black {
background-color: black;
color: white;
margin: 5px;
padding: 10px;
display: block;
flex: 0 1 auto; /* no growing allowed */
}
.resize {
overflow: hidden;
resize: vertical;
}
<div class='wrapper'>
<div class='col'>
<div class='red'>Some wide wide wide wide wide wide Text</div>
<div class='black'>Footer</div>
</div>
<div class='col'>
<div class='red'>Some<br/>much<br/>longer<br/>Text</div>
<div class='black'>Footer</div>
</div>
<div class='col'>
<div class='red resize'>Some Text<br><b><u>Resize me!</u></b></div>
<div class='black'>Footer</div>
</div>
</div>
Edit removed spacer div
Edit2 added css commenting for easier understanding
I'm trying to build a dropdown-style menu, but I'm running into some unexpected issues that appear to be caused by flexbox. The menu items that are hovered to open the dropdown are being styled using styles like the following to achieve a centered layout:
display: -ms-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-direction: column;
flex-direction: column;
The inline-flex display seems to be causing conflicts inside of the dropdowns that open under these menu items. The contents of the panels seem to want to collapse to as little space as possible (even less than what I would expect for an inline-block element with more space to grow). For example, I have 2 sections inside of a dropdown. I want both to expand as much as possible (up to 20ems for the link size), but each section tries to take as little room as possible, and the panel even overlaps. Here's a JSFiddle of my example (I apologize for the slightly messy example, but I wanted to keep it as close to my case as possible for now). If you remove the "inline-flex" block in the example, then you can see the intended behavior, but I would prefer to not have to do that to solve the issue.
I think this issue is related to a known flexbox issue with inline-flex containers struggling to size column wrapped elements, since the parent is flex column. That said, the children are flex row, so I would assume those to calculate their size appropriately.
Upon further inspection, simply replacing the inline-flex rules with a simple display:inline-block; will replicate the issue. Here is a fiddle of the example.
.navigation-bar__wrapper {
box-sizing: border-box;
position: relative;
z-index: 10;
}
.navigation-bar__wrapper .navigation-bar__dropdown-wrapper {
position: relative;
/* NOTE: Killing this line seems to fix the issue */
display:inline-block;
}
.navigation-bar__wrapper .navigation-bar__dropdown-wrapper:hover > .navigation-bar__menu-wrapper {
visibility: visible;
}
.navigation-bar__wrapper .navigation-bar__dropdown-wrapper > .navigation-bar__menu-wrapper {
left: 0;
top: 100%;
}
.navigation-bar__wrapper .navigation-bar__menu-wrapper {
background-color: #FFF;
/* NOTE: You can uncomment this line if you want the hovering effect */
/*visibility: hidden;*/
position: absolute;
border: 1px solid #000;
box-shadow: 3px 3px 2px #AAA;
z-index: 50;
top: 1px;
margin-left: -1.5em;
}
.navigation-bar__menu {
display: flex;
height: 325px;
padding: 2em;
font-size: 0.85em;
letter-spacing: 0.6px;
}
.navigation-bar__menu-item-wrapper {
display: inline-block;
padding: 1em 0.5em;
margin-right: 2em;
}
.navigation-bar__menu-item-wrapper .navigation-bar__menu-item-title {
max-width: 20em;
}
.navigation-bar__menu-item-wrapper .navigation-bar__menu-item-description {
color: #000;
line-height: 1.5em;
max-width: 20em;
}
.navigation-bar__menu-item-wrapper .navigation-bar__featured-image {
width: 193px;
height: 93px;
display: inline-block;
}
.navigation-bar__menu-section {
padding: 0 5px;
min-width: 150px;
}
.navigation-bar__menu-section + .navigation-bar__menu-section {
margin-top: 0;
padding-top: 0;
margin-left: 1em;
}
.navigation-bar__menu-section .navigation-bar__menu-section-title-wrapper {
padding-right: 2em;
}
.navigation-bar__menu-section .navigation-bar__menu-section-content-wrapper {
display: inline-flex;
flex-flow: wrap;
margin-top: 5px;
writing-mode: vertical-lr;
}
.navigation-bar__menu-section .navigation-bar__menu-section-content-wrapper > * {
writing-mode: horizontal-tb;
}
.navigation-panel-drilldown__wrapper .navigation-panel-drilldown__static-trigger {
padding: 1em 2em;
white-space: nowrap;
}
.navigation-panel-drilldown__wrapper .navigation-panel-drilldown__interactions-wrapper {
display: inline-flex;
flex-wrap: nowrap;
align-items: flex-start;
padding-top: 5px;
}
.navigation-panel-drilldown__wrapper .navigation-panel-drilldown__drilldown-content .navigation-bar__menu-item-wrapper {
display: block;
}
.navigation-bar__menu.has-panel-drilldown {
padding-left: 0;
}
.navigation-bar__menu.has-panel-drilldown .navigation-bar__menu-section {
padding-left: 0;
}
.navigation-bar__menu.has-panel-drilldown .navigation-bar__menu-section-title-wrapper.navigation-panel-drilldown__drilldown-title-wrapper {
padding-left: 2em;
}
<div class="navigation-bar__wrapper">
<ul class="navigation-bar__dropdown-containers-wrapper">
<li class="navigation-bar__dropdown-wrapper navigation-bar__data-menu">
<span class="navigation-bar__dropdown-title-wrapper">
I'm what is hovered to open the menu
</span>
<div class="navigation-bar__menu-wrapper">
<div class="navigation-bar__menu has-panel-drilldown">
<div class="navigation-bar__menu-section navigation-panel-drilldown__wrapper">
<div class="navigation-bar__menu-section-title-wrapper navigation-panel-drilldown__drilldown-title-wrapper">
<div class="navigation-bar__menu-section-title">Drilldown section</div>
</div>
<div class="navigation-panel-drilldown__interactions-wrapper">
<div class="navigation-panel-drilldown__static-triggers-wrapper">
<div class="navigation-panel-drilldown__static-trigger selected">Section 1</div>
<div class="navigation-panel-drilldown__static-trigger">Section 2</div>
<div class="navigation-panel-drilldown__static-trigger">Section 3</div>
<div class="navigation-panel-drilldown__static-trigger">Section 4</div>
</div>
<div class="navigation-panel-drilldown__drilldown-content-wrapper">
<div class="navigation-panel-drilldown__drilldown-content">
<a href="/noop" target="_blank" class="navigation-bar__menu-item-wrapper">
<div class="navigation-bar__menu-item-title">Some long option name that is too compressed</div>
</a>
<a href="/noop" target="_blank" class="navigation-bar__menu-item-wrapper">
<div class="navigation-bar__menu-item-title">Some other option name</div>
</a>
<a href="/noop" target="_blank" class="navigation-bar__menu-item-wrapper">
<div class="navigation-bar__menu-item-title">last option name that's long</div>
</a>
</div>
</div>
</div>
</div>
<div class="navigation-bar__menu-section">
<div class="navigation-bar__menu-section-title-wrapper">
<div class="navigation-bar__menu-section-title">Extra</div>
</div>
<div class="navigation-bar__menu-section-content-wrapper">
<a href="/noop" target="_blank" class="navigation-bar__menu-item-wrapper">
<div class="navigation-bar__menu-item-title">Extra option</div>
<div class="navigation-bar__menu-item-description">Some long description name about the extra option here</div>
</a>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
I have a flex container with individual child containers within it. Within those child containers, I have a simple content div and a title div. What I am trying to do is centre the title text vertically, but keep it at the top of the box. Then, I am trying to centre the content div in the box, both horizontally and vertically.
I have sort of figured it out (but knowing me this code is a load of drivel), but now when the viewport size decreases, the content text (with overflow: hidden) does not hide when the size decreases. I have figured out that this is down to the margin being set to 0, but I need it to be set to 0 in order for the bloody content div to center!
Any and all help offered is much appreciated. Here is a link to the jsfiddle that I created in order to help you visualise the problem. Change the size of the viewport and you'll see my issue, namely on the "Total cash amongst players" box.
http://jsfiddle.net/mpqbassm/
body {
background: #000;
}
.flex-container {
display: flex;
justify-content: space-around;
margin-right: 10px;
margin-bottom: 10px;
}
.flex-info {
color: white;
font-family: 'Arial', sans-serif;
box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.2);
padding: 10px;
border-radius: 2px;
width: 20%;
height: 100px;
display: flex;
flex-direction: column;
}
.flex-info.green {
background: #79B0B4;
}
.flex-info.blue {
background: #7993B4;
}
.flex-info.foam {
background: #79B47D;
}
.flex-info.pink {
background: #9B79B4;
}
.flex-info.red {
background: #B4797F;
}
.flex-info .flex-title {
font-size: 16px;
text-align: center;
white-space: nowrap;
overflow: hidden;
}
.flex-info .flex-content {
font-size: 40px;
margin: auto;
overflow: hidden;
}
<div class="flex-container">
<div class="flex-info green">
<div class="flex-title">Number of characters created</div>
<div class="flex-content">46,401</div>
</div>
<div class="flex-info blue">
<div class="flex-title">Number of vehicles purchased</div>
<div class="flex-content">499,012</div>
</div>
<div class="flex-info foam">
<div class="flex-title">Total cash amongst players</div>
<div class="flex-content">$192,012,299</div>
</div>
<div class="flex-info red">
<div class="flex-title">Total bans issued</div>
<div class="flex-content">12</div>
</div>
To stop the content from overflowing, overflow: hidden must be on the parent container of the element.
In this case, that would be any div with the class .flex-info.
Take a look at this in practice below.
body {
background: #000;
}
.flex-container {
display: flex;
justify-content: space-around;
margin-right: 10px;
margin-bottom: 10px;
}
.flex-info {
color: white;
font-family: 'Arial', sans-serif;
box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.2);
padding: 10px;
border-radius: 2px;
width: 20%;
height: 100px;
display: flex;
flex-direction: column;
overflow:hidden;
}
.flex-info.green {
background: #79B0B4;
}
.flex-info.blue {
background: #7993B4;
}
.flex-info.foam {
background: #79B47D;
}
.flex-info.pink {
background: #9B79B4;
}
.flex-info.red {
background: #B4797F;
}
.flex-info .flex-title {
font-size: 16px;
text-align: center;
white-space: nowrap;
overflow: hidden;
}
.flex-info .flex-content {
font-size: 40px;
margin: auto;
overflow: hidden;
}
<div class="flex-container">
<div class="flex-info green">
<div class="flex-title">Number of characters created</div>
<div class="flex-content">46,401</div>
</div>
<div class="flex-info blue">
<div class="flex-title">Number of vehicles purchased</div>
<div class="flex-content">499,012</div>
</div>
<div class="flex-info foam">
<div class="flex-title">Total cash amongst players</div>
<div class="flex-content">$192,012,299</div>
</div>
<div class="flex-info red">
<div class="flex-title">Total bans issued</div>
<div class="flex-content">12</div>
</div>
</div>
I am trying to make a full height page using flexboxes, where the content also uses a flexbox. The page should look as follows example of what it should look like. The blue div is dynamic and could change in height and the red content should take up the remaining space of the content div. This works on both Firefox and IE, however on Chrome it overflows. Can somebody explain why it overflows on Chrome?
The HTML is as follows:
<body>
<div class="container">
<div class="navbar">Navbar</div>
<div class="content">
<div class="container">
<div class="fill"></div>
<div class="dynamic">Here is some dynamic content<br>Test</div>
</div>
</div>
</div>
</body>
And the CSS is:
body{
margin:0;
}
.container{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.navbar{
background-color: #ccc;
flex: none;
}
.content{
background-color: #333;
flex: auto;
padding: 10px;
}
.dynamic{
background-color: #0066ff;
flex: none;
}
.fill{
flex: auto;
background-color: #ff0000;
}
Here is an updated snippet.
Use flex:1 for the container that needs to adjust the height automatically.
body {
margin: 0;
}
.container1 {
display: flex;
flex-direction: column;
width: 100%;
height: 100vh;
}
.navbar {
background-color: #ccc;
}
.content {
flex: 1;
background-color: #ff0000;
border: 10px solid #333;
border-bottom: none;
}
.dynamic {
background-color: #0066ff;
border: 10px solid #333;
border-top: none;
}
<body>
<div class="container1">
<div class="navbar">Navbar</div>
<div class="content">
</div>
<div class="dynamic">Here is some dynamic content
<br>Test</div>
</div>
</body>