Expanding a `div` while taking its children `max-width` into consideration - javascript

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.

Related

On element resize, resize the sibling elements too

I'm trying to horizontaly resize one div using css property resize: horizonatal. There are other elements right to this div with a padding of 10px that need to follow resizable div whenever it is resized. I'm not sure what would be the best approach to do the resizing? I found some articles about DOM Monitoring, but was wondering if there is a "simpler" way to do this.
You can wrap your elements in a container with display: flex. If you tell your non-resizable element to take up the remaining space, they should flow with the resized elements before them automatically.
Here's a runnable example:
.container {
display: flex;
}
.non-resizable {
flex-grow: 1;
background: pink;
}
.resizable {
resize: horizontal;
overflow: auto;
border: 1px solid black;
margin-right: 12px;
}
<div class="container">
<div class="resizable">Hello</div>
<div class="non-resizable">world!</div>
</div>

Keep vertical scrollbar in a fixed position independent of horizontal scroll

I currently have a grid set up that looks something like this:
<div class="grid-container">
<div class="headers"> <!-- ... --></div>
<div class="row-container">
<div class="row"> <!-- ... --></div>
<!-- ... -->
</div>
</div>
Essentially what I'd like to do is place an overflow-x on the entire grid-container (so that scrolling horizontally will scroll both the headers and the rows together), but just place an overflow-y: overlay on the row-container (so that scrolling down will only scroll through the rows and keep the grid headers in a fixed position.
I was able to do that and it looks okay, however, the vertical scrollbar on the row-container is at the far right of the row-container. I'd like it to be visible and in a fixed position (similar to how it would look if you were to place an overflow-y on the entire grid-container except without affecting the headers).
Sorry I know I probably explained this poorly, but here's a JSFiddle that should hopefully illustrate the problem I'm having: https://jsfiddle.net/4xwd5yzp/
Notice in that fiddle, you can only see the vertical scrollbar when you scroll to the end of the row-container.
Thank you in advance for any help. Ideally, I'd prefer a solution using just HTML + CSS, but I'm also open to use vanilla JS + jQuery if absolutely necessary.
EDIT: Here is an example of how it currently works (not ideal):
And here is a photo of how I want it to look:
You were very close, if you take the overflow-y style off of .row-container and add it to .grid-container and also add position: sticky; and background: white; to .headers then I believe it'll work how you want it to.
Update the width in % rather than px.
`
.grid-container {
border: 1px solid black;
height: 200px;
width: 99%x;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.row-container {
height: 150px;
width: 99%x;
overflow-y: overlay;
}
.grid-cell {
display: inline-block;
width: 250px;
}
.headers {
border-bottom: 1px solid black;
height: 50px;
width: 99%;
}
.row {
border-bottom: 1px solid lightgray;
height: 30px;
width: 99%;
}
`

How to make text flow to next line up, and hide the top?

I'm working on the display portion of a calculator. I have a div, with two divs, each with text, inside it.
<div>
<div>I'm text</div>
<div>I'm text</div>
</div>
The user can use buttons to add text to the divs. I want the top div to be a maximum of two lines and vertically-aligned to the bottom. When it exceeds this length, the overflow should be out of the top and hidden. I.e. the overflow should show the bottom part of the excessive text, and hide the top part.
I have searched similar questions relating to hiding images or links and tried their solutions. These generally revolve around using the following properties: position, width, height, bottom, overflow, vertical-align, word-wrap. I've understood most of these, but haven't been able to get them to work. One solution I haven't been able to successfully attempt appears to try and use some combination of the above with an additional nested div.
At this point, I've got the height & width controlled. The top div will only display two lines of text. I also have the overflow working. When it's too long, it is hidden.
The problem is that the bottom is hidden, instead of the top.
This is what it looks like. Notice the twos aren't visible, they're hidden:
This is what I want. Notice the twos are visible:
Here's relevant HTML & CSS, and below that is the link to a codepen if you need more information:
HTML (trouble div is #memory):
<div id=calculator>
<div id=displaybox>
<div id=memory>
0
</div>
<div id=display>0</div>
</div>
</div>
CSS:
#calculator {
border-style: solid;
height: 325px;
width: 260px;
margin:auto;
margin-top:10px;
border-radius:8px;
background-color: #494949;
font-family: 'Audiowide';
}
#displaybox {
border-style:solid;
border-width:3px;
width:227.5px;
margin-left:12px;
margin-right:auto;
border-radius: 8px;
text-align:right;
margin-top:20px;
padding-right:12px;
padding-left:3px;
font-size:30px;
background-color:#D4D7A1;
height: 75px;
}
#memory {
font-size:15px;
padding-right:3px;
line-height: 15px;
margin-top:5px;
padding-left:12px;
color:#767676;
margin-bottom:-7px;
word-wrap: break-word;
height:30px;
width:207px;
overflow:hidden;
vertical-align: top !important;
}
Codepen: https://codepen.io/ethan-vernon/pen/WyQqzM"https://codepen.io/ethan-vernon/pen/WyQqzM
This change to the #memory block did it:
Added display: flex and flex-flow: column-reverse
#memory{
font-size: 15px;
padding-right: 3px;
line-height: 15px;
margin-top: 5px;
padding-left: 12px;
color: #767676;
margin-bottom: -7px;
word-wrap: break-word;
height: 30px;
width: 207px;
overflow: hidden;
display: flex;
flex-flow: column-reverse;
}
I have not found an answer yet still for CSS/HTML solution. However, I turned to jQuery/JavaScript and have solved my problem by calling the below function after each update to the #memory div.
function heightCheck(str) {
console.log(str.substr(1));
console.log('memory: ' + $("#memory").height());
while ($("#memory").height()>30) {
str=str.substr(1);
$("#memory").text(str);
console.log(str);
console.log($("#memory").height());
}
}

How to define the width of a HTML element dynamically

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.

child div overlapping rounded (with radius) container when at width of 2%

I have a long rectangle shape container with a radius.
And I also have 3 child divs, in the container.
Here it is:
As you can see in the picture above, the first child container (white) and the third (red) have also been set a radius to match to containers radius.
Now, the child containers width will be dynamic (changeable by the user). So the user will be able to change the widths of all three child containers to meet their needs.
But take a look at what happens when I give the third container a width of 2%:
the same thing happens when i do the same to the first child (it overlaps the containers rounded borders).
Child container 1 (white) is floating to the left and child container 3 (red) is floating to the right.
I need a way to stop the overlapping from happening.
I am able to use JS and JQuery incase your wondering.
Thanks
EDIT:
CSS:
.parent {
border: 1px solid #5B5B5B;
height: 30px;
width: 80%;
right: 0%;
position: relative;
margin-right: auto;
margin-left: auto;
<? set_radius("25px",true);
set_box_shadow("1px","1px","#F8F8F8");?>
overflow: hidden;
z-index: 3;
}
.child_class {
display: inline-block;
position: relative;
width: auto;
height: 100%;
margin: 0px;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #5C5C5C;
box-sizing: border-box;
}
#child1 {
width: 33.33;
background-repeat: repeat-x;
background-position: center center;
<? set_radius("25px",false,false,true,false,true);?>
float: left;
background-color: #fff;
}
#child2 {
width: 33.33;
background-repeat: repeat-x;
background-position: center center;
background-color: #0CF;
}
#child3 {
<? set_radius("25px",false,true,false,true,false);?>
background-repeat: repeat-x;
background-position: center center;
width: 33.33;
float: right;
background-color: #F00;
}
HTML:
<div class="parent">
<div class="child_calss" id="child1"></div><div class="child_calss" id="child2"></div><div class="child_calss" id="child3"></div></div>
In your CSS:
parent{
overflow: hidden;
}
Then you won't have to bother with matching the border-radius on the children, either.
Edit
I've created this jsfiddle to demonstrate:
Not needing border-radius on the children
overflow: hidden rounds the children when they overlap
Unnecessary background- properties on the children are removed
Expected behavior at small percentages
Update
Another note on this:
If you want the CSS/HTML to perform logic for you (not drop the last element out of the bar), you have a clear misunderstanding of what CSS and HTML do.
I've updated the jsfiddle to provide a sort of patch-fix to that issue. The third child is positioned absolutely at the far right, so that it will always stay in the bar.
Update
Finally, here's the bug in Webkit that doesn't correctly clip the background. It appears there's nothing you can do right now except possibly something like this:
<div class="hasBorder hasBorderRadius">
<div class="hasBorderRadius hasHiddenOverflow">
<div class="containsContent">
</div>
</div>
</div>
have you tried giving them a z-index so they have a stack order? also what about an overflow hidden on the parent?

Categories

Resources