I have two divs:
top div contains a long text that takes up several lines
lower div has min-height and flex-grow: 1
When I reducing the window to the scroll appeared, then in chrome everything is displayed correctly. But in IE11 top div is reduced to one line, and its text is on top of the bottom div.
I can fix it only with set some width for content of top div (it work with fixed width, or calc width, but not work with percentage width)
How can I fix it without setting width or with percentage width (width:100%)?
body,
html {
height: 99%;
padding: 0;
margin: 0;
}
.flexcontainer {
width: 25%;
display: flex;
flex-direction: column;
height: 100%;
border: 1px solid lime;
}
.allspace {
flex-grow: 1;
min-height: 300px;
background-color: yellow;
}
.longtext {
background-color: red;
}
.textcontainer {
border: 1px solid magenta;
/*IE work correctly only when specified width. by example: width:calc(25vw - 2px);*/
}
<div class="flexcontainer">
<div class="longtext">
section 1 with long name section 1 with long name section 1 with long name
</div>
<div class="allspace">
all space
</div>
</div>
jsfiddle: https://jsfiddle.net/tkuu28gs/14/
Chrome:
IE11:
IE11 is full of flex bugs and inconsistencies with other browsers.
In this case, the source of the problem is flex-shrink.
IE11 is rendering flex items oddly after applying flex-shrink: 1 (a default setting), which causes the lower item to overlap its sibling above. This problem doesn't occur in other major browsers.
The solution is to disable flex-shrink. It fixes the problem in IE11 without changing anything in other browsers.
Add this to your code:
.longtext {
flex-shrink: 0;
}
revised fiddle
You may also want to look into:
setting min-width: auto on flex items, as IE11 has a different minimum size default than newer browsers. See the "Browser Rendering Notes" section in my answer here: Why don't flex items shrink past content size?
setting the container to width: 100%, as IE11 may not do this automatically to block-level flex containers. Text in a flex container doesn't wrap in IE11
The use of flex-shrink: 0; mentioned in the accepted answer works to prevent overlapping. However, I'm using like flex: 0 1 15% as I intend to allow shrinking and this renders nicely in other browsers like MS Edge, Chrome, and Firefox, but not in IE 11.
To apply no shrinking (flex-shrink: 0) only for IE 11, I used the following instead as the -ms- is vendor-specific:
-ms-flex-negative: 0 !important;
problem solved:
body, html {
height: 100vh;
padding:0;
margin:0;
}
.flexcontainer{
width:25%;
display: flex;
height: 100%;
flex-flow: column;
border: 1px solid lime;
}
.allspace{
flex-grow:1;
background-color: yellow;
}
.longtext{
background-color: red;
//EDIT
flex-grow: 0;
min-height: 100px;
}
.textcontainer{
border:1px solid magenta;
/*IE work correctly only when specified width. by example: width:calc(25vw - 2px);*/
}
EDIT (screenshots on IE11)
Related
My front-end skills are poor, so does my English expression. Sorry ahead.
I have these several divs (some colors and margins are added as some kind of visual assistance):
<html>
<header>
<style>
.outer-container {
margin: 2px;
padding: 2px;
border: 1px deeppink dashed;
}
.inner-container {
margin: 2px;
padding: 2px;
border: 1px deeppink dotted;
display: flex;
flex-direction: row;
align-items: center;
}
.content0 {
background-color: black;
color: white;
border: 1px red solid;
white-space: nowrap;
}
.content1 {
max-width: 500px;
background-color: black;
color: white;
flex-grow: 1;
border: 1px red solid;
white-space: nowrap;
}
</style>
</header>
<body>
<div class="outer-container" style="width: 100%" align="center">
<div class="inner-container">
<div class="content0">Placeholder</div>
<div class="content1">Placeholder</div>
</div>
</div>
</body>
</html>
Here are my expected behaviors:
The outer-container has some kind of "externally appointed" width (width: 100% in this example, but not limited to this circumstance).
The content0 is expected to have a minimum width for displaying its content. The content1 is expected to expand horizontally and occupy its "container"'s space, at most 500px.
The inner-container is expected to expand and occupy its "container"'s space, while considering the maximum width of its children. In this example, I expected it to expand until content1 reaches its max-width. Then, inner-container is aligned to the center of outer-container.
Fig1: when outer-container is narrow, inner-container simply fills the outer-container.
Fig2: when outer-container gets wider, inner-container expands until its children stop expanding, and then inner-container gets to the center of outer-container. This picture was made by mspaint, not really I know how to implement it with HTML/CSS.
However, I bumped into troubles when trying to implement the third item. I've tried many combinations and searched over again. But for each attemption , either inner-container is not expanded at all, or inner-container expands and eats up outer-container. Is it possible to implement this with HTML and CSS (and JavaScript if really needed)? And if so, how?
The closest I could get is https://jsfiddle.net/ne9phs5y/.
The content0 and content1 behave as expected but unfortunately inner-container fills the entire outer-container which might or might not be a problem. The most important part was setting flex-basis of content1 to 500px.
I am facing a similar issue as this question scrollHeight gives incorrect value when height property is provided in css
where the scrollHeight of my element is incorrect when an explicit height is set on the element.
In my case there is no margin collapsing, but the bottom padding is collapsing.
I tried recreating that in a fiddle, and i realized that it might not have to do with the padding in my case, but the display: flex property.
Somehow the scrollHeight seems to be calculated differently when using display: flex vs when not using it.
$(function() {
console.log("test "+$(".container")[0].scrollHeight);
})
.header {
min-height: 48px;
background: red;
}
.body {
min-height: 28px;
background: green;
}
.footer {
min-height: 36px;
background: blue;
}
.container {
height: 56px;
/* remove this to see change in scroll height */
/* display: flex; */
}
.wrapper {
display: flex;
flex-direction: column;
padding-bottom: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="header">Some content </div>
<div class="body"> Body </div>
<div class="footer"> CTA </div>
</div>
</div>
http://jsfiddle.net/Lsz8an1r/4/
http://jsfiddle.net/3yrn6dz5/ - another example without an margins
I am not able to find any documentation to support the fact that the display:flex is somehow changing the calculation for scrollHeight. Any pointers/clarifications would be helpful.
I have tested this in Chrome 86
attaching images as some comments have suggested it might be a browser specific issue
With flex
Without flex
i have a sticky nav that when it sticks (position: fixed being applied) the width is changing to push the right of the navbar off the screen.
a screen recording example
a codesandbox eample
Using react/hooks and styled components. a hook is applying the prop of sticky: true (see code below).
I have tried a few different combinations of setting width: 100% or width: 100vw in both the non-sticky and sticky styles.
in the video you can see 2 things happening when the nav becomes "sticky". the border-radius-bottom-right is disappearing and the content of the nav is being pushed to the right. When not sticky, the nav has a width of 808px, when sticky it grows to 840px. To be clear I'm not saying the border radius style is being removed, but the border right is now off screen.
the code for the nav:
const Wrapper = styled.div`
padding: 1rem;
display: flex;
justify-content: center;
font-size: 1.5rem;
background-color: white;
color: black;
/* width: auto; */
/* width: 100%; */
z-index: 1;
margin: 0;
box-shadow: 0px 2px 10px #273136;
height: 30px;
border-radius: 0 0 10px 10px;
${props => props.sticky && css`
position: fixed;
top: 0;
width: 100vw;
`}
`;
This is being rendered inside of another wrapper component, wrapping the entire app, with the following styles:
text-align: center;
font-size: 10px;
color: black;
display: flex;
flex-direction: column;
max-width: 100vw;
You set widht:100vw to the fixed element which makes wider than the body because vw doesn't care about the scrollbar it will be difficult to work with, i suggest you use width:100%
Also because you have box-sizing set to content-box the padding and border won't be considered as content so they will influence the width, and let's not forget about the default margin:8px on the body
to accommodate for all this we can use calc()
instead of 100vw you should use 100% because 100% gives us the exact width of the parent excluding the width of the scrollbar.
Solution
After you set position:fixed
You also add
left:8px; // to push it 8px from the left because of the default margins on the body
width:calc(100% - 48px);
Why 48x ?
left padding (16p) + right padding(16px) + left body margin(8px) + right body margin(8px) = 48px
Why left body margin ? didn't we use left:8px to deal with it ?
Yes we did and by pushing it we simply added it the other end.
my question is rather complicated.
In my layout i have a left column and a right column. For example 30% and 70% width. below them there is another item, now theres the challenge:
if my 30% column is higher than the 70% column the "challengeblock" should fill on the right side.
if the right side is the higher one the "challengeblock" should be on the bottom with 100% width.
Here I made an example:
https://jsfiddle.net/by6tkg7L/
The green one should fit on the right in this code.
I tried it with
flex-grow
in this case, but also had a try with grid (not to experienced there so seems like I need to read some more first)
I´m also open for masonary layouts like with isotope, but found no way so far to make it fill OR make it grow depending on the rest.
I would ofcourse prefer a CSS-only way and would like to avoid calculating with JS.
Tahnks in advance
Css only solution. Working fiddle: https://jsfiddle.net/by6tkg7L/1/
To be able to see it working you have to change height of the blue block (class .right_top).
I only modified the css, i used block and inline-block on the child elements (with float: left) and i've set flex only on the question element setting a min-width and a max-width instead of a static width.
CSS:
.wrapper{
display: block;
width: 100%;
flex-wrap: wrap;
flex-direction: row;
}
.left{
background-color: red;
height: 500px;
width: 30%;
display:inline-block;
float:left;
}
.right_top{
background-color: blue;
height: 500px;
width: 70%;
display:inline-block;
float:left;
}
.question{
min-width: 70%;
width: auto;
max-width: 100%;
background-color: green;
height: 300px;
display:flex;
}
HTML:
<div class="wrapper">
<div class="left">
</div>
<div class="right_top">
</div>
<div class="question">
</div>
</div>
I have a single container div with two child div's. The container div is 100% width. The child div's are left floated. The left div's width is not set because it's contents must decide it's width. The right div's width must be 100% minus the width of the left div.
HTML:
<div class="container">
<div class="message-name"><p>User :</p></div>
<div class="message-msg"><p>Some message</p></div>
</div>
<div class="container">
<div class="message-name"><p>User : </p></div>
<div class="message-msg"><p>Some really long message that breaks to new line because it is too long to stay on this line. mmmm mmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmmm mmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmm</p></div>
</div>
CSS:
*{margin:0;pading:0;}
.container{
width:100%;
min-height: 20px;
overflow: auto;
}
.message-name{
height: 20px;
text-align: left;
float: left;
border: 1px solid red;
}
.message-msg{
border: 1px solid red;
min-height: 20px;
float: left;
}
This is my attempt at using JQuery to dynamically set the width of the right div when it is added to the page dynamically:
$(document).ready( function(){
var nameWidth = $(".message-name").last().width();
alert(nameWidth);
$(".message-msg").last().css("width","100%").width($(".message-msg").last() - nameWidth);
});
But it doesn't change anything.
How can I get the width of the left div and then subtract that from the width of the right div to ensure the right div does not break to a new line?
Here is a JSFiddle of my attempt.
Use flexbox, it's support is wide enough for most reasonable purposes.
No scripting required, much more FLEXible!
* {
margin:0;
padding:0;
}
.container {
width:100%;
min-height: 20px;
overflow: auto;
display: flex;
flex-direction: row;
}
.message-name {
height: 20px;
text-align: left;
border: 1px solid red;
flex-shrink: 0;
}
.message-msg {
border: 1px solid red;
min-height: 20px;
flex-grow: 1;
flex-shrink: 1;
}
<div class="container">
<div class="message-name"><p>User :</p></div>
<div class="message-msg"><p>Some message</p></div>
</div>
<div class="container">
<div class="message-name"><p>User : </p></div>
<div class="message-msg"><p>Some really long message that breaks to new line because it is too long to stay on this line. mmmm mmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmmm mmmmmmmmmm mmmmmmmmmm mmmmmmmmm mmmmmmmm</p></div>
</div>
Also on JSFiddle
A more efficient way to use flexbox is to just declare the .message-msg block to be flex: https://jsfiddle.net/84vocLbk/. It'll be situated horizontally next to the .message-name and stretch the available width.
CSS:
.message-msg {
border: 1px solid red;
min-height: 20px;
display: flex;
}
Please try this
$(".message-msg").last().width($(".message-msg").last().width() - nameWidth);
Border 2px for each div is present. If you want to place it to the left then try this
$(".message-msg").last().width($(".message-msg").last().width()-2 - nameWidth-2);
DEMO without removing border
DEMO after removing the border
Add this
$(".message-msg").last().css("width","100%").width($(".message-msg").last().width() - nameWidth);
In thaat line you're setting the width to 100% then changing that width to 100% minus the variable nameWidth You have to get width of last div to do calculations
You can achieve this with CSS.
fiddle: https://jsfiddle.net/zof15z6c/7/
This works by setting the overflow of the second div to hidden or auto. if your content is just a text I suggest setting it to hidden since the text would just wrap around.
Changes to the css
.message-msg{
border: 1px solid red;
min-height: 20px;
overflow:hidden;
}
Advantages:
Works on most browsers (tested in IE7)
The browser takes care of window resizes
Cleaner code
Disadvantages
Overflow should either be hidden or auto. This will not be an issue for you since you just have text.