background color disappears when overflow is visible - javascript

I have the following CSS code written;
#container {
width: 1300px;
background-color:green;
margin:0 auto;
overflow:hidden;
}
#menu {
float:left;
width:20%;
background-color: yellow;
}
After searching google for a long time I couldn't find an explaination why the container background color is disappearing when the container overflow attribute is visible.
Can someone help me understand why ?
Update:
Thanks alot for your answers.... :)
I don't mind using overflow:hidden, ijust want to understand its purpose and how to use it.
As i unserstand, the overflow property specifies what happens if content overflows an element's box, so i dont understand why would its visibilty make the container background color disappear or why would it change the container height.

Since the elements within the container are have float:left - the container had a height of 0 - which is also what is causing you not to see any background.
In order to fix this there are a few solutions out there:
One of them is called clearfix
<div id="container" class="clearfix">
<!-- floated elements here -->
</div>
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
Another is by setting overflow:hidden on the container element - this establishes a new block formatting context - which in effect clears the floats. (See this post)
From the spec:
Floats, absolutely positioned elements, block containers (such as
inline-blocks, table-cells, and table-captions) that are not block
boxes, and block boxes with 'overflow' other than 'visible' (except
when that value has been propagated to the viewport) establish new
block formatting contexts for their contents.
In a block formatting context, boxes are laid out one after the other,
vertically, beginning at the top of a containing block. The vertical
distance between two sibling boxes is determined by the 'margin'
properties. Vertical margins between adjacent block-level boxes in a
block formatting context collapse.
In a block formatting context, each box's left outer edge touches the
left edge of the containing block (for right-to-left formatting, right
edges touch). This is true even in the presence of floats (although a
box's line boxes may shrink due to the floats), unless the box
establishes a new block formatting context (in which case the box
itself may become narrower due to the floats).

This is because of the floating child element. If your container only contains floated elements, its height will be equal to zero.
You need to include a clear element, different possibilities exists:
The Empty Div Method: By adding a <div style="clear: both;"></div> as latest child element.
The Overflow Method: By setting an overflow: hidden on the container element
The Easy Clearing Method: By adding extra CSS and a class on the parent element (clearfix')
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}

It is happening because you have not given any height to #menu.
As, #container has height of #menu, background is not visible.
Give some height to it.
#menu {
float:left;
width:20%;
background-color: yellow;
height:50px;
}
DEMO here.

You can set the height of the container div to be equal with the height of the menu. This way you don't need the overflow: hidden setting.
$("#container").height($("#menu").height());
Demo here: http://jsfiddle.net/er144/ZV6pb/

Related

Strange effect of CSS overflow hidden vs. visible on position of parent element [duplicate]

This question already has answers here:
CSS margin terror; Margin adds space outside parent element [duplicate]
(7 answers)
What is the point of CSS collapsing margins?
(1 answer)
How to disable margin-collapsing?
(12 answers)
Closed 3 years ago.
I've never read anything to suggest that the overflow property of an element would have the strange effect on element positioning that I'm seeing here:
https://codepen.io/kshetline/pen/ZEzLVxN
Toggle the toggle button in the example, and watch how somehow the background of a <div> mysteriously slides upward, covering previous content, while its contents stays in the same screen-relative place (meaning the content is moving lower relative to its parent's background).
The example is a very simplified version of something I'm trying to do with an Angular component that's meant to scale its <ng-content> — but the example is only CSS and HTML with a tiny touch of JavaScript, no Angular, since I'm trying to isolate the relevant variables.
The content of an HTML element can be scaled down using transform: scale( less-than-1 scaling factor ), but even though the content of the element is rendered smaller, by default the element's pixel dimensions remain the same, with the content (unless otherwise specified) shrinking toward the center of the element, and blank space left around that content that leaves the element at its original unscaled dimensions..
You need to compute negative margins that match the degree of scaling in order for the element itself to be considered smaller. I've done that, but I've found that unless the container for the scaled element has CSS overflow set to hidden, some weird positioning can occur, as if the extra blank space required that's supposed to be removed by the negative margins is still having some partial, hard-to-explain effect on the overall layout of other elements.
I'm seeing this behavior in Chrome, Firefox, Safari and Edge -- so I'm guessing it's "proper" CSS behavior, but it makes no sense to me, and I'm hoping someone can explain what's going on. I'd like to be able to keep overflow set to visible so that scaled content can still do things like show floating dropdown menus that don't get clipped at the boundaries of the element.
let hidden = true;
const inner = document.getElementById('inner')
function toggleOverflow() {
hidden = !hidden;
inner.style.overflow = hidden ? 'hidden' :
'visible'
}
html, body {
height: calc(100vh - 10em);
}
.page {
font: 32px Arial, Helvetica, sans-serif;
height: calc(100% - 1em);
}
.container {
background-color: #ACF;
height: 100%;
}
.outer-wrapper {
background-color: rgba(187, 255, 204, 0.5);
font-size: 2em;
margin: 0 1em;
position: relative;
}
.inner-wrapper {
overflow: hidden;
position: relative;
width: fit-content;
}
.ng-content {
margin: -18.75px 0;
transform: scale(0.5);
}
.container-text {
display: inline-block;
position: absolute;
bottom: 1em;
}
<div class="page">
<button onclick="toggleOverflow()">Toggle Overflow</button><br>
Content outside of the<br>
panel being scaled and its<br>
containing <div>, 32pt font<br>
<div class="container">
<!--Angular component start tag goes here -->
<div class="outer-wrapper">
<div id="inner" class="inner-wrapper">
<div class="ng-content">
50% scaled content goes here, 64pt font
</div>
</div>
</div>
<!-- Angular component end tag goes here -->
<span class="container-text">This is an absolutely positioned <span> in the same <div></span>
</div>
</div>
From CSS 2.2 spec
Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
So adding overflow:hidden is stopping the margins from collapsing.
You have set a negative margin in your .ng-content. If overflow is set to hidden, it will hide the negative margin. Set the margin to a positive number and it will fix this jumping issue.
.ng-content { margin: 18.75px 0; }
If you are trying to change the height of the element up and down, try using max-height with overflow: hidden. When max height is set to 0, it will be hidden. When set to something like 500px, your content will show!
Follow-up...
I created a variant on my first code pen here:
https://codepen.io/kshetline/pen/WNeRmOo
In this case, I'm using transform-origin: top center when I scale, and putting all of the needed negative margin on at the bottom of the scaled element, rather than splitting it evenly between top and bottom. That eliminates the weird vertical position shifting.
overflow: hidden is still needed to hide the excess of background color from "leaking out" of its container, but in the (common) case where the background of the scaled element is transparent, there would be no visible effect from using overflow: visible instead, and no worries about clipped dropdown menus originating inside the scaled element.
Follow-up #2...
Here's the best solution, using padding: 0.05px to deal with the real issue that #Alochi helped me understand — stopping border collapse:
https://codepen.io/kshetline/pen/zYONgzV

How to force div to spill outside of ul container on hover?

How can I let an arbitrary div nested within a ul spill outside of the ul, which is set to width: 160px; and overflow-y: hidden;? I have set it to overflow-y: hidden because the list needs to be scrollable.
Here is my list:
<ul>
<li> color name</li>
<div class="tooltip">color name</div>
<li> color name</li>
<div class="tooltip">color name</div>
<li> color name</li>
<div class="tooltip">color name</div>
.....
</ul>
For the names whose text is wider than 160 pixels I want a hover event to reveal the tooltip element's text and I want this text to spill outside of its container, ul.
I have read the following resources but none of them have helped me:
Allow specific tag to override overflow:hidden
Hovered element to overflow out from an overflow:hidden element css
https://css-tricks.com/popping-hidden-overflow/
CSS spread <li> horizontally across <ul>
Why does inner DIV spills out of outer DIV?
http://front-back.com/how-to-make-absolute-positioned-elements-overlap-their-overflow-hidden-parent
What causes a parent container to cut off content in child element?
https://medium.freecodecamp.org/a-step-by-step-guide-to-making-pure-css-tooltips-3d5a3e237346
If I understand your situation correctly, the problem can be solved by applying the z-index property to an ::after pseudo-element that receives content on :hover.
This creates a "tooltip" that's triggered by a hover state and will "spill out" of any parent div regardless of the parent's overflow property. As a bonus, it won't invalidate your markup with rogue tags in your lists.
HTML
<ul class="list">
<li class="list-item">color</li>
</ul>
CSS
.list {
border: 1px solid black; //to see element boundary
overflow: hidden;
width: 160px;
}
.list-item::after {
content: '';
}
.list-item:hover::after {
background-color: gray; //aesthetic only
content: 'long tooltip text about the color';
margin-left: 5px; //aesthetic only
position: absolute;
z-index: 999;
}
Example on Codepen
First off, you should fix your HTML. Only LI element can be direct children of UL elements. The invalid HTML is not likely to give you any issues in this particular case, but you should always strive to write valid HTML as you never know what weird issues might come up.
Next, if you have overflow: hidden on your parent UL, then there is nothing you can really do without getting javascript involved. Most "tooltip" types of libraries will handle this for you:
On hover, make a copy of the DIV which is outside of the UL (preferable at the document root - a direct child of the BODY)
Position the copied DIV so that it appears on top of (or next to) the original DIV - this requires JavaScript and I will leave as an exercise for the OP
Delete the copy when the user is no longer hovering.
Again, most "tooltip" libraries already do this for you. You might have to write custom CSS to make a tooltip appear on top of and existing element as opposed to next to it.

Dynamically responsive grid-style container in CSS

In my application a user is able to input text and click a button to append a new 'span' to the DOM (within a container) containing their inputted text. I want these spans to have as much width as needed to fit the given user inputted text (you can assume the user wont input something longer than the container's width). I would also want the container to fit as many spans as possible within in a row; and if a span needs more room than is left in the current row -> go to the row below (see the last two lines of the picture).
What kind of CSS would I need to add to my container as well as the spans within it to achieve the organization below?
Please Note: the width of this container is fixed, but the height grows as needed to fit new text filled spans
As per you mockup, You can achieve your task by two way:
Use flex CSS3 property
Use CSS3 property width auto and float left in span class.
let span class="class-name"
.class-name {
display: inline-block;
width: auto;
float: left;
}
In this span class, you can add more property as per your need.
To do this with the CSS3 flex property:
.container {
display: flex;
border: 1px solid red;
width: 20rem;
flex-wrap: wrap; /* otherwise it will try to fit everything on one line */
justify-content: space-between; /* alternatives are space-evenly or space-around*/
}
see this pen, with flex you have the advantage that you have better control over how this width of the container is uses, with the float solution you cannot justify the content, it will all stick to the left and leave unused space on the right.

Requesting more information about overflow: hidden

I'm creating an HTML/CSS application, and I'm a bit stuck.
Let's say that I have 2 elements positioned next to eachother display: inline-block
Every element has again a couple of elements which are placed next to eachother.
See the following illustration that tries to explain it:
So, the image below describes 3 different levels of elements:
Level 1: Red - Outer element
Level 2: Yellow - Wrapper element
Level 3: Green - Content
In HTML, this could be constructed writting like the following:
<ul id="holder">
<li>
<div>
<div class="col">Col 1</div>
<div class="col">Col 2</div>
</div>
</li>
<li>
<div class="col">Col 1</div>
<div class="col">Col 2</div>
</li>
</ul>
The UL represents the red element, the LI represents the yellow elements and the DIV elements represents the green elements.
Now, let's say that our red element has a fixed width and I place the overflow on hidden. This means that when I resize the page, the elements on the right dissapear when they don't fit the page.
But here the problem arizes, when I do resize the window, and the window becomes too small to render everything, immediately, the latest LI element is not visible on the screen anymore.
Is there any CSS way to make sure that no the LI element are hidden but the DIV elements inside the LI? When both DIV elements are hidden, off course the LI element can be hidden aswell since it's empty?
If there's no CSS way to do this, anyone minds putting me in the right direction by using JavaScript or something else?
Here's a jsFiddle to explain it a bit more.
Kind regards
The li disappears from view because it's in display: inline-block.
As soon as the window isn't wide enough, it moves below the first li.
You can see this happen if you release the #holder's height (height:auto).
The solution is to add white-space : nowrap to force the li to stay in one line.
Updated fiddle :
https://jsfiddle.net/zLqfe4z8/4/
It's not a problem of your elements hiding because there's not enough width, it's because they're wrapping because there's not enough width (and then being hidden by the overflow: hidden).
You can see this happening if you remove the height constraint on your wrapper:
#holder { overflow: hidden; border: 1px solid red; }
The fix is simple, stop it from wrapping using white-space: nowrap:
#holder { white-space:nowrap; overflow: hidden; border: 1px solid red; height: 52px; }

Making a div scrollable inside a resizeable container div

I am trying to make a div that looks like the MS Windows Command Prompt.
The div is resizeable, and has two children: a title-bar div, and a content div.
I want the content div to get scrollbars when it is larger than the window div. I want the title-bar to always be visible and not scroll, and not to be on top of the scroll bars.
http://www.webdevout.net/test?0vL interactively demonstrates my problem. Click on the content text and new rows get added. When enough rows are added for scroll bars to appear, they do not.
The content div has overflow:auto set.
Setting max-height or height on the content to 100% does not work because 100% doesn't account for the title-bar height, so the scrollbars appear after some rows have gone off the bottom. Also, the scrollbars, when they appear, obscure the draggable thumb on the outer div, stopping it being resizeable :(
Just change your resizable window to the child 'content' <div>. that way you're resizing the child <div> and the parent <div> resizes automatically to hold its contents.
Also, not sure if it was intentional but you have <div id ="Content" class="Content"> in your html and .Frame>.Contents { in your CSS (note the word content has an 's' in the CSS).
I believe this is what you're looking for:
http://www.webdevout.net/test?0wE
Add the following CSS:
.Content {
overflow: auto;
height: inherit;
}
Here you go: http://www.webdevout.net/test?0v-
Cheers ;)
I assume your HTML tree looks like:
Dialog
Title bar
Content
To make the Content scrollable, use the overflow CSS property
.content {
overflow: auto;
height: inherit;
}
Add the CSS property
overflow:auto;
Just add this to your CSS
overflow: auto;

Categories

Resources