Force display: table element to not overstep parent element width - css

How can I prevent the display: table element overstepping its parent element width?
Here is a jsFiddle of the below:
.container {
max-width: 150px;
padding: 5px;
border: 2px solid #0f0;
}
.table {
display: table;
border: 1px solid #00f;
max-width: 100%;
}
.cell {
display: table-cell;
}
.cell:nth-child(2) {
background: #f00;
}
<div class="container">
<div class="table">
<span class="cell">
<select>
<option>long long long long long desc</option>
</select>
</span>
<span class="cell">A</span>
</div>
</div>
In effect, the .table element is wider than .container.
How can I prevent that and keep max-width of .table 100% of parent element? (max-width is not working).
I'm looking for pure CSS solution.

Very simple:
Demo http://jsfiddle.net/zpfLxkrh/3/
you need two things:
.table{
table-layout: fixed;
width: 100%;
}
select {
max-width: 100%;
}

The problem is not your display: table div... it is your select.
If you want to keep that width, make it behave!
select {
width: 100%;
}
Example
The select size will now be controlled by its cell size. I have changed the cell sizes to 50% to illustrate this.
.container {
max-width: 150px;
padding: 5px;
border: 2px solid #0f0;
}
.table {
display: table;
border: 1px solid #00f;
max-width: 100%;
}
.cell {
display: table-cell;
width: 50%;
}
.cell:nth-child(2) {
background: #f00;
}
select {
width: 100%;
}
<div class="container">
<div class="table">
<span class="cell">
<select>
<option>long long long long long desc</option>
</select>
</span>
<span class="cell">A</span>
</div>
</div>

Related

How to style nth-child alternating in flexbox

I like to build a grid-like construct where my first and every odd row have two flex elements by each other in f.e. 60% and 40% width and in my second and every even row these elements have opposite widths meaning 40% and 60% (reversed).
Sure I would define every element by hand, but when I just a frontend framework I like to generate these elements programmatically and that's where the struggle comes in.
I prepare the static version here: https://play.tailwindcss.com/dqiZBooPhQ
How can I determine which element gets the 60% and which gets the 40%?
I made a simple sample with css flexbox for you
CSS:
div {
min-width: 200px;
height: 25px;
}
.wrapper {
width: 500px;
display: flex;
flex-direction: column;
}
.wrapper > div {
display: flex;
}
.wrapper > div:nth-child(even) {
width: 100%;
background-color: #f00;
}
.wrapper > div:nth-child(even) > div:first-child {
width: 40%;
border: 1px solid black;
}
.wrapper > div:nth-child(even) > div:last-child {
width: 60%;
border: 1px solid black;
}
.wrapper > div:nth-child(odd) {
width: 100%;
background-color: #0f0;
}
.wrapper > div:nth-child(odd) > div:first-child {
width: 60%;
border: 1px solid black;
}
.wrapper > div:nth-child(odd) > div:last-child {
width: 40%;
border: 1px solid black;
}
and HTML
<div class="wrapper">
<div id="first">
<div class="a">test</div>
<div class="b">test</div>
</div>
<div id="second">
<div class="a">test</div>
<div class="b">test</div>
</div>
<div id="third">
<div class="a">test</div>
<div class="b">test</div>
</div>
</div>

CSS display:table-row How to width:100%? And border-bottom for rows with padding for table content?

trying to create table with 100% width content, but "width" did not work. can anyone help plz. how can I fix it? And there is "div" inside table cos I can't padding content another way. I need paddin from table borders, and i need bottom lines between table rows. without "border-collapse" "border-bottom" did not work for table rows. So i need add one more div just to do padding :(. Can anyone show me how to do it right without adding one more "div" inside table.
.tabble {
display: table;
border-collapse: collapse;
border-spacing: 10px;
border-radius: 6px;
width: 100%;
}
.table__row {
display: table-row;
width: 100%;
border-bottom: 1px solid red;
}
.table__row:last-child {
border: none;
}
.table__cell {
display: table-cell;
width: 20%;
padding: 10px;
text-align: left;
}
.padding-div {
padding: 5px 20px;
width: 100%"
}
</style>
<div class="tabble">
<div class="padding-div">
<div class="table__row">
<div class="table__cell">1</div>
<div class="table__cell">1</div>
</div>
<div class="table__row">
<div class="table__cell">2</div>
<div class="table__cell">2</div>
</div>
</div>
</div>```
There are a number of things wrong with your table.
There is a typo, " instead of ; in the CSS for .padding-div.
The table cells have width:20%, which interferes with the width calculations. The browser won't know whether to make the two cells together 40% or 100% wide. Remove this.
And the biggest problem, the padding div. You can't have an ordinary div inside a table and with a table row inside. Remove this div. If you want space around the whole table, apply a margin to the table itself.
Then it will have the desired result. That is, if what you want is to make the whole table as wide as the viewport.
.tabble {
display: table;
border-collapse: collapse;
border-spacing: 10px;
border-radius: 6px;
width: calc(100% - 40px); /* changed */
margin: 5px 20px; /* new */
}
.table__row {
display: table-row;
width: 100%;
border-bottom: 1px solid red;
}
.table__row:last-child {
border: none;
}
.table__cell {
display: table-cell;
/*width: 20%;*/ /* removed */
padding: 10px;
text-align: left;
}
.padding-div {
padding: 5px 20px;
width: 100%
}
<div class="tabble">
<div class="table__row">
<div class="table__cell">1</div>
<div class="table__cell">1</div>
</div>
<div class="table__row">
<div class="table__cell">2</div>
<div class="table__cell">2</div>
</div>
</div>
Note: if you do want the table to have a border, as you said in the comments, the solution changes a bit. Then the table itself needs to have a padding, and that means you can't use border-collapse, you'll have to use border-spacing:0 instead, which also means you'll need to apply the inside borders to the cells rather than the rows.
.tabble {
display: table;
border-spacing: 0; /* changed */
border-radius: 6px;
width: calc(100% - 40px); /* changed */
padding: 5px 20px; /* new */
border: 1px solid tan; /* purely for demo purposes */
}
.table__row {
display: table-row;
width: 100%;
}
.table__cell {
display: table-cell;
padding: 10px;
text-align: left;
}
.table__row:not(:last-child) .table__cell {
border-bottom: 1px solid red;
}
<div class="tabble">
<div class="table__row">
<div class="table__cell">1</div>
<div class="table__cell">1</div>
</div>
<div class="table__row">
<div class="table__cell">2</div>
<div class="table__cell">2</div>
</div>
</div>

"inline-flex" item does not grow with its content in Internet Explorer

I have a simple table structure made up of divs:
$(document).ready(function() {
$("button").on("click", function() {
$(".cell").outerWidth(500);
})
})
div {
border: 1px solid black;
box-sizing: border-box;
}
.container {
width: 400px;
height: 100%;
padding: 5px;
overflow: auto;
}
.row {
min-width: 100%;
width: auto;
display: inline-flex;
padding: 5px;
margin-bottom: 5px;
border-color: red;
}
.cell {
flex: 0 0 auto;
border-right: 1px solid black;
overflow: hidden;
min-width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="cell">x</div>
</div>
<div class="row">
<div class="cell">x</div>
</div>
<div class="row">
<div class="cell">x</div>
</div>
</div>
<button type="button">Change width</button>
The rows need to be vertically stacked, each having the (unknown) height of their content and be at least as wide as the container. The container has to scroll if the content does not fit. The width of the cells will be interactively changed using JS and the rows should expand to fit the whole content. For this reason, the rows have the following style:
.row {
min-width: 100%;
width: auto;
display: inline-flex;
}
The flex part is needed for the cells and is outside of the scope of this question. Being an inline element, the row will grow with the content in all major browsers but not in Internet Explorer 11. Check out the fiddle and click the button to change the width of the cells. The border helps to visualize the behaviour. The image below shows the expected behaviour (top) and how Internet Explorer interprets it (bottom):
What kind of bug is this (couldn't figure it out from the list of flexbugs) and how can I make it work in Internet Explorer?
In IE11 the behavior is as wanted:
The default flex behavior of flex items has changed. In Internet
Explorer 10, flex items that didn't fit their containers overflowed
the margins of the container or clipped to the margins of the
container. Starting with IE11, these items now shrink to fit their
containers (up to the min-width value, if specified). Use the
flex-shrink property to change this behavior.
https://msdn.microsoft.com/en-us/library/dn265027(v=vs.85).aspx
So, the following .cell rules should solve the issue
.cell {
flex: 0 0 auto;
-ms-flex: 0 1 auto; /* overwrites the previous rule only in IE11 */
border-right: 1px solid black;
overflow: hidden;
min-width: 200px;
}
Here's a solution I've come up with... that doesn't use Flex at all.
Updated:
Simplified the CSS to handle the margins and padding better. When you click the button to make the cell grow larger, because of the fixed width of the container, there is no margin between the row and the container.
$(document).ready(function() {
$("button").on("click", function() {
$(".cell").width(500);
})
})
html, body { width: 100%; height: 100%; margin:0; padding:0; }
div {
border: 1px solid black;
/* box-sizing: border-box; */
}
.container {
width: 400px;
padding: 5px;
margin:10px;
background: green;
overflow: auto;
}
.container::after, .row::after {
content: " ";
visibility: hidden;
display: block;
height: 0;
width: 0;
clear:both;
}
.row {
min-width: calc(100% - 22px);
padding: 5px;
margin: 5px;
border-color: red;
background: pink;
float:left;
}
.container > *:last-child {
/* margin: 0; */
}
.cell {
padding: 5px;
margin:5px;
border-right: 1px solid black;
overflow: hidden;
width: calc(200px - 22px);
background: orange;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="cell">x</div>
</div>
<div class="row">
<div class="cell">x</div>
</div>
<div class="row">
<div class="cell">x</div>
</div>
</div>
<button type="button">Change width</button>
The problem:
div {
box-sizing: border-box;
}
.cell {
flex: 0 0 auto;
}
The solution:
If you don't want to change this part of css, i suggest you to avoid setting width, instead of setting min-width
$(document).ready(function() {
$("button").on("click", function() {
$(".cell").css("min-width","500px");
})
})

three divs side by side with middle div expanding

I want three divisions side bu side with the middle explanding and the other two positioned at the ends. So here is what I tried. The padding rule disturbs the positioning but its necessary. I want approach which works in all major browsers(So ruling out flexbox)
.Button {
width: 80%; /*Useless Rule*/
}
.Button > .left {
float: left;
background-color: blue;
padding: 5px;
}
.Button > .right {
float: right;
background-color: red;
padding: 5px;
}
.Button> .middle {
width: 100%;
background-color: green;
padding: 5px;
}
<html>
<body>
<div class="Button">
<div class="left"><</div>
<div class="right">></div>
<div class="middle">Middle</div>
</div>
</body>
</html>
I like to use the display: table on the parent, and the display: table-cell on the children. Then give the first and third child a width of 1px. It will then be only as width as its content.
.button {
display: table;
width: 100%;
}
.button>div {
display: table-cell;
text-align: center;
background: lightblue;
}
.button>div:nth-child(1),
.button>div:nth-child(3) {
width: 1px;
background: lightgreen;
}
<div class="button">
<div><</div>
<div>Middle</div>
<div>></div>
</div>

CSS - Dynamic padding to expand divs to fill a dynamic width

So I have a variable number of elements in a div that has a variable width. The elements inside have a fixed space between them, 5px, but each one needs to expand to fill the full width of the space of the outer div with padding, so the text can be centerized.
Example:
.button-container{
width: 100%;
height: 50px;
}
.button-container .button{
min-width: 75px;
display: inline-block;
text-align: center;
border: 1px solid #FF0000;
}
.button-container .button + .button-container .button{
margin-left: 5px;
}
<div class='button-container'>
<div class='button'>B1</div>
<div class='button'>B2</div>
<div class='button'>B3</div>
<div class='button'>B4</div>
</div>
So how can I make the padding inside of the button class elements have a dynamic left and right padding to fill the space of the button-container class div?
Ideally, the solution will be a CSS only solution, as I don't want to have jQuery to do the spacing.
CSS tables would work here.
.button-container {
width: 100%;
height: 50px;
display: table;
border-collapse: separate;
border-spacing: 5px;
}
.button-container .button {
display: table-cell;
text-align: center;
border: 1px solid #FF0000;
vertical-align: middle;
}
<div class='button-container'>
<div class='button'>B1</div>
<div class='button'>B2</div>
<div class='button'>B3</div>
<div class='button'>B4</div>
</div>
You can use flexbox:
.button-container {
display: flex; /* Magic begins */
}
.button-container > .button {
flex: 1; /* Distribute the width equally */
text-align: center;
margin-left: 5px;
border: 1px solid #FF0000;
}
.button-container > .button:first-child {
margin-left: 0;
}
<div class='button-container'>
<div class='button'>B1</div>
<div class='button'>B2</div>
<div class='button'>B3</div>
<div class='button'>B4</div>
</div>

Resources