Is there a CSS/HTML-only way to take into account the size of overflown content? Consider the example below:
.outerZeroSize {
width: 0px;
height: 0px;
overflow: visible visible;
}
.innerContent {
width: 200px;
height: 300px;
}
.belowContent {
}
<div class="outerZeroSize">
<div class="innerContent">
Some content<br/>
Some more content <br/>
And some more
</div>
</div>
<div class="belowContent">Content below</div>
The text in the div belowContent ends up on top of the text of innerContent.
Question: Since the height of innerContent is 300px, I would like belowContent to appear 300px below outerZeroSize (instead of on top of it). Is this possible with CSS/HTML?
Constraints:
Assume that .outerZeroSize and .innerContent cannot change (neither HTML, nor CSS part), because they come from a third-party (React-Virtualized Table).
UPDATE: The height of .innerContent can change dynamically, 300px is just an example (so just offsetting .belowContent by this same amount is not an option, either).
What can be changed is .belowContent (HTML and CSS), and of course it is possible to add stuff around the .outerZeroSize div.
Related question (from React Virtualized Table perspective).
Simply add a 300px margin-top to belowContent.
.outerZeroSize {
width: 0px;
height: 0px;
overflow: visible visible;
}
.innerContent {
width: 200px;
height: 300px;
}
.belowContent {
margin-top: 300px;
}
<div class="outerZeroSize">
<div class="innerContent">
Some content<br/>
Some more content <br/>
And some more
</div>
</div>
<div class="belowContent">Content below</div>
Another solution would be to move belowContent inside outerZeroSize.
.outerZeroSize {
width: 0px;
height: 0px;
overflow: visible visible;
}
.innerContent {
width: 200px;
height: 300px;
}
.belowContent {
width: 200px;
}
<div class="outerZeroSize">
<div class="innerContent">
Some content<br/>
Some more content <br/>
And some more
</div>
<div class="belowContent">Content below</div>
</div>
Related
First of all, please look at this code.
I learned that this was a common way to realize liquid layout.
But I can not understand some of this code.
.container {
overflow: hidden;
}
main {
float: left;
width: 100%;
margin-right: -340px;
background: red;
}
.main-inner {
margin-right: 340px;
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Question 1
I understand that the negative margin has the effect of moving an element in the specified direction. However, when you run this code, the main element does not seem to be moving at all. Why is this?
Question 2
Since we set the width of the main element to 100%, I understand that the aside element hits the main element and that the main element and aside element can not be side by side.
So, I think that we prepare a horizontal width that can apply the aside element by applying negative margin, but the background color of the main element is applied in the same way as when the horizontal width is 100%. Why is the background color of the main element not (100% - aside width)? How is this series of rendering done?
Question 3
Which document on W3.org describes these actions? I tried looking, but I could not find any detailed information on them.
thank you.
Let's start by adding the properties one by one and see what is happening.
Intially we have this code with no margin applied and only float elements:
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
}
.main-inner {
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
It's clear that you made the red element to be width:100% floating on the left and the green one to float on the right with a fixed width. You may also notice that p element is having a default margin that's why the blue is not totally covering the red.
Now if you add negative margin-right you will not move the element or decrease the width but you will pull the content from the right in order to overlap the element. Here is a basic illustration:
.box {
width: 200px;
height: 200px;
background: red;
float: left;
}
<div class="box" style="margin-right:-100px;height:220px">
</div>
<div class="box" style="background:blue;">
</div>
As you can see the blue box is overlapping the red one by exactly 100px because we applied -100px to the margin-right of the red box. Same logic will happen in your case, you applied a negative margin equal to the size of the sidebar so you created the need space to move the sidebar at the same level of the main element.
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
margin-right:-340px;
}
.main-inner {
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
So the main element is still 100% width BUT the sidebar is overlapping it due to negative margin.
Now the last step is to add the margin inside the main and in this case it will reduce the width of the inner element to make the total (width + margin) always equal to the width of parent element (containing block)
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
margin-right:-340px;
}
.main-inner {
background: blue;
margin-right:340px;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Here is another illustration of margin with block element non floated:
.container {
border: 2px solid;
max-width: 50vw;
margin: auto;
}
.first {
height: 100px;
background: red;
margin: 0 -50px;
}
.second {
height: 100px;
background: blue;
margin: 0 50px;
}
<div class="container">
<div class="first">
</div>
<div class="second">
</div>
</div>
In this case the width is increasing/decrasing due to margin because the logic is always: width + margin = width of containing block.
With elements like float and inline block the logic is the same but we won't have width changes because the width is defined either by the content or explicitly.
.container {
border: 2px solid;
display:inline-block;
}
.first {
float:left;
height: 100px;
background: red;
margin-right:-50px;
}
.second {
display:inline-block;
width:200px;
height: 120px;
background: blue;
margin-top:20px;
margin-right:-100px;
}
<div class="container">
<div class="first">
some text here
</div>
<div class="second">
</div>
</div>
Here the float element has a width defined by the content, the inline-block has a width equal to 200px. The negative margin is creating the overlap and the size of the parent element (the containing block) is equal to width + margins.
For the references:
8 Box model
9 Visual formatting model
10 Visual formatting model details
The above explanation is very simplifed. Refer to the specification links for a full and details explanation.
The odd placement from <main> comes from a browser css-rule
p {
display: block;
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
}
You can reset it using a css reset like normalize.css.
However, I recommend using display: flex. Some wonderful resources.
.container {
display: flex;
}
main {
width: 75%;
}
aside {
width: 25%;
}
I have a slightly unusual CSS challenge to overcome.
I have a two column layout, whereby the width of the left column is set by the width of a main image, and the right allowed to fill the remaining space. There is a container under the main image, which could have a natural width greater than the main image. However, I want this div to be the same width as the main image, and the overflow to be hidden. Here is my effort at attempting this:
.outer {
margin-right: 5px;
position: relative;
}
.left {
float: left;
}
.right {
width: auto;
overflow: hidden;
}
.contentOuter {
overflow: hidden;
}
.content {
width: 500px;
}
.inner {
background-color: grey;
color: white;
width: 100%;
height: 150px;
}
<div class="outer left">
<div class="image">
<img src="http://placehold.it/350x150" />
</div>
<div class="contentOuter">
<div class="content">
<img src="http://placehold.it/500x50" />
</div>
</div>
</div>
<div class="outer right">
<div class="inner">
Hello world!
</div>
</div>
But as you can see, .contentOuter stretches to the width of its contents, regardless of what I attempt.
One major caveat I have is that apart from .content having a fixed width, I don't want any other hard-coded widths in my CSS; everything should be completely fluid, and the dimensions of the columns determined by the dimensions of the .image img.
So, I am after something that visually looks like this, but without the hard-coded max-width on .content:
.outer {
margin-right: 5px;
position: relative;
}
.left {
float: left;
}
.right {
width: auto;
overflow: hidden;
}
.contentOuter {
overflow: hidden;
}
.content {
max-width: 350px; /* Hard-coded for demo purposes */
}
.inner {
background-color: grey;
color: white;
width: 100%;
height: 150px;
}
<div class="outer left">
<div class="image">
<img src="http://placehold.it/350x150" />
</div>
<div class="contentOuter">
<div class="content">
<img src="http://placehold.it/500x50" />
</div>
</div>
</div>
<div class="outer right">
<div class="inner">
Hello world!
</div>
</div>
One option, though that depends on further requirements you may have, it so simply add to the lower block:
position: absolute;
width: 100%;
This takes it out of the flow, and the enclosing element will not take its width into account for sizing, only that of the image on top. The overflow: hidden will then hide whatever overflows.
The drawback is that the height of the enclosing element (or the position or subsequent elements) will not take into account the size of this element.
jsFiddle: https://jsfiddle.net/jacquesc/rsz0hb1g/
A quick way to solve this would be to simply use some jQuery. It would only take two lines of code to achieve this.
var imgWidth = $('.image').width();
$('.content').width(imgWidth);
I have this markup:
<div id="wrapper">
<div id="container">
<div class="block"></div>
<div class="block"></div>
</div>
</div>
and this CSS:
#wrapper {
width: 100%;
overflow: hidden;
}
#container {
width: 200%;
}
.block {
width: 50%;
float: left;
}
Basically all I want to do is, have 2 fullwidth divs floating next to each other, but when I put some content in them I get container centered and pieces of both divs showing, like this: http://prntscr.com/8lr4l6
What am I doing wrong?
There is no need to set the width of the wrapper and of the container. It is always 100%, if nothing else is set. Just set a width of 50% to every block and float them left.
#wrapper {
overflow: hidden;
}
.block {
float: left;
width: 50%;
}
Example
would something like this work for you: http://jsfiddle.net/swm53ran/338/
you can see the div to by commenting out overflow: hidden
<div class="container">
<div class="block block1">
This is content for div 1 This is content for div 1 This is content for div 1
</div>
<div class="block block2">
This is content for div 2 This is content for div 2 This is content for div 2
</div>
</div>
body {
overflow: hidden;
}
.container {
width: 200%;
padding: 0px;
}
.block {
display: inline-block;
width: 50%;
float: left;
outline: 1px solid gray;
}
Boy, am I a fool!?
In my case answer was pretty simple. I had left autofocus attribute on my input which were on the off screen div, and of course it automatically scrolled to that div.
Thanks everyone for answers though. :)
I want to place divs next to each other. I dont't know number of divs, since this is dynamically created and changed. I would like to have one parent div which will have scrollbar in case there are many child divs (and their width is greater than parent).
Here's the jsFiddle example. So, basically I would like to have all this three columns, next to each other and with scrollbar on the bottom of parent div.
HTML:
<div class="content">
<div class="column">Column</div>
<div class="column">Column</div>
<div class="column">Column</div>
</div>
CSS:
content {
width: 100px;
background- color: #355E95;
overflow: visible;
}
.column {
width: 50px;
display: inline-block;
}
Add white-space:nowrap to your parent div.
FIDDLE
You would need to use a content div for the scroll and then a wrapper for the columns, adjusting the width of the wrapper to fit all 3 of your columns (150px in your example).
The column structure is made by floating div's left, but it will float to the width of your parent container, in this case your parent container is only 100px so we need to add a wrapper for them to fit inside.
If you also want a vertical scroll you will need to set a height to your container.
Jsfiddle: http://jsfiddle.net/tYnH3/
css:
.content {
width: 100px;
background-color: #355E95;
overflow: auto;
}
.content-wrapper {
width: 150px;
}
.column {
width: 50px;
float: left;
}
html:
<div class="content">
<div class="content-wrapper">
<div class="column">
Column
</div>
<div class="column">
Column
</div>
<div class="column">
Column
</div>
<div class="column">
Column
</div>
<div class="column">
Column
</div>
<div class="column">
Column
</div>
</div>
</div>
Fiddle: http://jsfiddle.net/bdssw/
use float:left;
.column {
width: 50px;
display: inline-block;
float:left;
}
Try the following JS fiddle
http://jsfiddle.net/jT6SW/1/
#wrapper
{
float: left;
height: 150px;
width: 250px;
margin: auto;
border: 1px black solid;
overflow-y: hidden;
overflow-x: scroll;
}
use width:auto;
.content {
width: auto;
background-color: #355E95;
overflow:scrolling;
position:fixed;
}
.column {
width: 50px;
float:left;
}
http://jsfiddle.net/XqSJG/6/
I have an element with a 70% width, and it is floating beside another element with 30% width. However, when I add 25px of padding, the element expands and breaks the format.
Is there any way to make padding increase the contents' distance from the element's edge, as opposed to making the element bigger?
.seventy {
float: left;
width: 70%;
background-color: lightsalmon;
}
.thirty {
float: left;
width: 30%;
background-color: lightgreen;
}
.padded {
padding: 25px; /* Forces box onto next line */
}
<div>Works:</div>
<div class="seventy">70% wide</div>
<div class="thirty">30% wide</div>
<br><br>
<div>Broken:</div>
<div class="seventy">70% wide</div>
<div class="thirty padded">30% wide, padded</div>
When you use the border-box model, the padding is included in the box size. See here for details.
.seventy {
float: left;
width: 70%;
background-color: lightsalmon;
}
.thirty {
box-sizing: border-box;
padding: 25px;
float: left;
width: 30%;
background-color: lightgreen;
}
<div class="seventy">70% wide</div>
<div class="thirty">30% wide</div>
I would create another element of the same type (may I guess it's a div?) inside the element and set that one to have a padding/margin of 25px.
For example:
<div id="wrapper">
<div id="width30">
</div>
<div id="width70">
<div id="padding25">
Acctual content here.
</div>
</div>
</div>
</div>