How to define the width of a HTML element dynamically - javascript

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.

Related

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

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.

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>

make a div fit into whitespace if possible, else grow in size

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>

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%;
}
`

Width of overflowed content

I'm working on a tag scroller that will basically allow users to scroll through chunks of tags left or right if there are more tags than fit their current containing div. My plan was to have the component div set to overflow:hidden so the tags (and their parent div) would not wrap. Then I'd have left and right arrows that would animate the tag wrapper to the left or right.
I need to determine if the width of the tag-wrapper is greater than the tag-scroller itself. If so, then I know that there are more tags than fit within the tag-scroller and I should make the arrows visible so a user can click to scroll and view some more. The layout and everything looks as expected however my problem is, using $('.tag-wrapper').width(); always returns a different value depending on window width which shouldn't be the case since the actual content hasn't changed. If the screen is wide enough, I may not need to show the arrows so I need to check the width on window resize, etc.
Any ideas why $('.tag-wrapper').width(); would give me different sizes based on the actual window width even thought the scrollable content itself hasn't changed?
Here is my markup:
.tag-scroller {
overflow: hidden;
white-space: no-wrap;
display: block;
width: 100%;
height: 50px;
}
.tag-wrapper {
white-space: nowrap;
display: inline-block;
border: 1px solid green;
}
.tag {
display: inline-block;
width: initial;
text-align: center;
padding: 5px 10px 6px 10px;
}
<div class="tag-scroller">
<div class="tag-wrapper">
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
</div>
</div>
I used the jQuery outerWidth method.
$(function() {
$(document).on('DOMNodeInserted DOMNodeRemoved', '.tag-wrapper', function(e) {
$('#p').text('tag-wrapper width: ' + $('.tag-wrapper').outerWidth() + 'tag-scroller width: ' + $('.tag-scroller').outerWidth());
if ($('.tag-wrapper').outerWidth() > $('.tag-scroller').outerWidth()) {
alert('ok');
}
});
$('#btn').click(function(e) {
$('.tag-wrapper').append($('<div class="tag">1</div>'));
});
$('#btnWidth').click(function(e) {
$('#p').text('tag-wrapper width: ' + $('.tag-wrapper').outerWidth() + 'tag-scroller width: ' + $('.tag-scroller').outerWidth());
});
});
.tag-scroller {
overflow:hidden;
white-space:no-wrap;
display:block;
width:100%;
height:50px;
}
.tag-wrapper {
white-space: nowrap;
display:inline-block;
border:1px solid green;
}
.tag {
display:inline-block;
width:initial;
text-align:center;
padding: 5px 10px 6px 10px;
}
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<div class="tag-scroller">
<div class="tag-wrapper">
<div class="tag">1</div>
<div class="tag">2</div>
<div class="tag">3</div>
<div class="tag">4</div>
</div>
</div>
<button id="btn">Click Me</button>
<button id="btnWidth">Check Widths</button>
<p id="p"></p>

Categories

Resources