table-cell width gets larger as width property gets smaller - css

I have the following code:
<div style="display: table; border: 1px solid green;">
<div style="display: table-cell; width: 1%; max-width: 1000px; background: red; height: 30px;"></div>
</div>
Changing the width property has completely counter-intuitive consequences.
A bigger example of this behavior: http://jsfiddle.net/8DUfr/2/. How is the width of the red rectangle calculated?

You were using width: percentage%; in the wrong div. You put it in the parent div for each red bar. I fixed your JSFiddle.
http://jsfiddle.net/8DUfr/4/
<h3>1%</h3>
<div style="display: table; border: 1px solid green; width: 1%">
<div style="display: table-cell; max-width: 1000px; background: red; height: 30px;"></div>
</div>

The box model in CSS has traditionally worked this way:
Given width w, the actual visible width of the box is calculated by adding w to the left and right padding of the element plus the left and right border. The width specified via the CSS width property, in modern browsers only tells CSS how wide the content area should be. See W3C documentation for an example.
For illustration purposes, let's say you have the following:
HTML
<div class="box">Something here</div>
CSS
.box {
width: 100px;
border: solid 1px red;
padding: 2px;
}
The visible width of .box is actually: 100 + 2 * 1 + 2 * 2 = 106px. To make the box measure exactly 100px, you have to subtract 6px from the specified width to compensate.
HTML
<div class="box-adjusted">Something here</div>
CSS
.box-adjusted {
width: 94px;
border: solid 1px red;
padding: 2px;
}
With the advent of CSS3, we now have the box-sizing property. The value that makes the width work as we expect is border-box.
HTML
<div class="box2">Something here</div>
CSS
.box2 {
width: 100px;
border: solid 1px red;
padding: 2px;
box-sizing: border-box;
}
See fiddle: http://jsfiddle.net/nnN6t/3/

Related

Text occupying more space than needed using flexbox

I'm trying to draw a square next to a multiline piece of text in a fixed width container for a color legend. However, I'm running into the issue that even though the text and the square should fit in the container, the square is getting squashed into a rectangle as the text element takes up more horizontal space than it should. Is there a way I can (preferably without hard-coded magic numbers) ensure that the p element only takes the horizontal space it needs to display the text?
Relevant MWE:
html:
<div class="div">
<div class="square">
</div>
<p class="text">
Lorumipsum dolorsitamet
</p>
</div>
css:
.div {
width: 140px;
display: flex;
align-items: center;
outline: 1px solid blue;
}
.square {
width: 25px;
height: 25px;
background-color: red;
}
.text {
margin-left: 2px;
outline: 1px solid red;
}
Fiddle:
http://jsfiddle.net/6jxtp8k5/59/
Use min-width and min-height instead of using width and height. This will ensure that the square will always have the specific width and height.
.square {
min-width: 25px;
min-height: 25px;
background-color: red;
}

make divs stay inside parent div with margins

i've been looking around to fix this, i havent seen a good answer on why this happens and how i can fix it..
basically i have a div that i set to 100% width and height, inside i have like a tabs section like on a broswer, i added a margin and padding to the main area, and when i set the tabs div to full width it sticks out some pixels, whats the correct way to deal with child divs sticking out of parents divs when playing with %'s and margins/padding
<div class="appview_fullscreen app_ama">
<center><strong>AMAMAMAMAMAMA</strong> </br>
<i>AMAMAMA</i>
</center>
<div class="main_area">
<div class="tabs_area">
</div>
<div class="main_window">
</div>
<div class="troubleshoot_area">
</div>
<div class="timeline">
</div>
</div>
</div>
.appview_fullscreen
{
width: 100% !important;
height: 100%;
background-color: black;
color: white;
font-size: 20px;
margin: 0px;
}
.app_ama
{
}
.main_area
{
border: 1px solid green;
width: 100%;
padding: 2px;
margin: 0px;
}
.tabs_area
{
border: 1px solid green;
height: 20px;
width: 100%;
}
demo : http://jsfiddle.net/S8RC3/
By simply removing 100% from the DIV elements.
DEMO
.main_area{
/* width:100%; Why? I'm a DIV! */
border: 1px solid green;
padding: 2px;
margin: 0px;
}
.tabs_area{
/* width:100%; Why? I'm a DIV! */
border: 1px solid green;
height: 20px;
}
DIV as being a Block level element is already wide as it's parent container.
Additionally you have a typo: </br> should be <br />, <br/> or <br>
For your padding and border, use box-sizing: border-box;.

Including margin for width and height

I want box width and height to include all of the content, padding, border width, and margin by default. Is there a way to do this? Especially, I want to be able to specify something like width: 100% including everything up to the margin.
This is a vague question, but I'll answer the best I can.
Margin, by definition, is the area around the outside of your box; meaning there's no way to include margins inside of your div.
If you would like more padding on the inside of your box, but you don't want the box to resize, then use: box-sizing:content-box;
Or if you would like to include padding and the border, use: box-sizing:border-box;
A workable solution that preserves the size of your divs and removes overflow would look something like this:
#parent{
box-sizing:border-box;
width:100%;
height:200px;
padding:2em;
}
#child{
box-sizing:border-box;
width:100%;
height:100%;
padding:1em;
}
<div id="parent">
<div id="child"></div>
</div>
Just place the div you want to give margins to inside of another div that has padding. Thus creating faux margins.
if your margin is for example 10px you can use
width: calc(100% - 20px);
box-sizing: border-box;
browser support
w3schools.com reference
Set the CSS box-sizing property to border-box to make width and height include the content, border, and padding. This allows you to set width: 100% and still add padding or border. In other words box-sizing: border-box makes width include everything between the inner edges of the margin. There is no way to include the margin itself in such a way.
.example { box-sizing: border-box; width: 100%; padding: 10px }
Useful references
CSS Box Model visualization
CSS3 UI: box-sizing property
* { box-sizing: border-box } FTW
Maybe wrap another div around it and specified that div's width?
<div style="width: 100px; border: 1px solid blue;">
<div style="width: 100px; background:yellow; margin: 10px; border: 1px solid blue">
inner width 100px not including it's margin.
</div>
</div>
<div style="width: 100px; border: 1px solid blue">
<div style="background:yellow; margin: 10px; border: 1px solid blue">
inner width's 100px including it's margin.
</div>
</div>
Use display: flex; for the parent tag.
For example:
<!DOCTYPE html>
<html>
<head>
<style>
.center {
border: 1px solid black;
width: 100%;
overflow: auto;
box-sizing: border-box;
display: flex; /* it can put children in one line */
}
.left {
border: 1px solid black;
width: 20%;
float: left;
box-sizing: border-box
}
.right {
border: 1px solid black;
width: 80%;
margin: 0 10px;
float: left;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="center">
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>

How to set the maximum height of CSS tables?

I'm trying to vertically center text in a div using the method outlined in this article : http://css-tricks.com/vertically-center-multi-lined-text/
.container {
width: 160px;
margin: 80px auto;
padding: 5px;
height: 60px;
max-height: 60px;
border: 1px solid black;
display: table;
}
.container p {
height: 60px;
max-height: 60px;
display: table-cell;
vertical-align: middle;
text-align: center;
}
<div class="container">
<p>This is a lot of text. A really large amount of text, even. So much text here. And it just keeps going, oh my. Wow - so much text.</p>
</div>
<div class="container">
<p>Here's one line.</p>
</div>
JSFiddle here : http://jsfiddle.net/Vc88w/2/
The div must not go bigger than the specified height of 60px, and any overflowing text should be hidden. The CSS table trick works fine when there is not enough text to make the div overflow, but when there is too much it forces the div to go larger than 60px (the first example), which is not what I want.
Is there a CSS rule besides height and max-height that lets me override the height of a CSS table? Alternatively, how else could I achieve the vertical centering while enforcing a maximum height of 60px on the container div?
yes you must change in ".container" the "display:table" with a "display:block"
.container {
width: 160px;
margin: 80px auto;
padding: 5px;
height: 60px;
max-height: 60px;
border: 1px solid #000;
overflow: hidden;
display: block;
}

How can I send an inner <div> to the bottom of its parent <div>?

The div inside another div picture and code below. Because there will be text and images of the parent div. And red div will be the last element of the parent div.
<div style="width: 200px; height: 150px; border: 1px solid black;">
<div style="width: 100%; height: 50px; border: 1px solid red;">
</div>
</div>
This is one way
<div style="position: relative;
width: 200px;
height: 150px;
border: 1px solid black;">
<div style="position: absolute;
bottom: 0;
width: 100%;
height: 50px;
border: 1px solid red;">
</div>
</div>
But because the inner div is positioned absolutely, you'll always have to worry about other content in the outer div overlapping it (and you'll always have to set fixed heights).
If you can do it, it's better to make that inner div the last DOM object in your outer div and have it set to "clear: both".
A flexbox way.
.parent {
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* not necessary, just to visualize it */
.parent {
height: 500px;
border: 1px solid black;
}
.parent div {
border: 1px solid red;
}
<div class="parent">
<div>Images, text, buttons oh my!</div>
<div>Bottom</div>
</div>
Edit:
Source - Flexbox Guide
Browser support for flexbox - Caniuse
Make the outer div position="relative" and the inner div position="absolute" and set it's bottom="0".
Here is another pure CSS trick, which doesn't affect an elements flow.
#parent {
min-height: 100vh; /* set height as you need */
display: flex;
flex-direction: column;
background: grey;
}
.child {
margin-top: auto;
background: green;
}
<div id="parent">
<h1>Positioning with margin</h1>
<div class="child">
Content to the bottom
</div>
</div>
You may not want absolute positioning because it breaks the reflow: in some circumstances, a better solution is to make the grandparent element display:table; and the parent element display:table-cell;vertical-align:bottom;. After doing this, you should be able to give the the child elements display:inline-block; and they will automagically flow towards the bottom of the parent.
Note : This is by no means the best possible way to do it!
Situation :
I had to do the same thign only i was not able to add any extra divs, therefore i was stuck with what i had and rather than removing innerHTML and creating another via javascript almost like 2 renders i needed to have the content at the bottom (animated bar).
Solution:
Given how tired I was at the time its seems normal to even think of such a method however I knew i had a parent DOM element which the bar's height was starting from.
Rather than messing with the javascript any further i used a (NOT ALWAYS GOOD IDEA) CSS answer! :)
-moz-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
-ms-transform:rotate(180deg);
Yes thats correct, instead of positioning the DOM, i turned its parent upside down in css.
For my scenario it will work! Possibly for others too ! No Flame! :)
Here is way to avoid absolute divs and tables if you know parent's height:
<div class="parent">
<div class="child"> Home
</div>
</div>
CSS:
.parent {
line-height:80px;
border: 1px solid black;
}
.child {
line-height:normal;
display: inline-block;
vertical-align:bottom;
border: 1px solid red;
}
JsFiddle:
Example
You may not want absolute positioning because it breaks the reflow: in some circumstances, a better solution is to make the grandparent element display:table; and the parent element display:table-cell;vertical-align:bottom;. After doing this, you should be able to give the the child elements display:inline-block; and they will automagically flow towards the bottom of the parent.
<div style="position: relative;
width: 200px;
height: 150px;
border: 1px solid black;">
<div style="position: absolute;
bottom: 0;
width: 100%;
height: 50px;
border: 1px solid red;">
</div>
</div>
<div style="width: 200px; height: 150px; border: 1px solid black;position:relative">
<div style="width: 100%; height: 50px; border: 1px solid red;position:absolute;bottom:0">
</div>
</div>

Resources