CSS div dynamic width with two values - html

I'd like my div to be 175px width if the text inside is shorter than this value or to take 100% of cointainer width if the text is bigger than 175px. How can I achieve this?
So far I tried to play with width, min-width and max-width but can figure it out.
.text-div {
min-width: 175px;
max-width: 100%;
border: dotted 2px;
}
<div id="container">
<div class="text-div">
Short Text
</div>
<div class="text-div">
Loooooooooooooog Text
</div>
</div>

A hacky approximation using clamp(). You need an extra wrapper that has a shrink-to-fit behavior (I used float but you can consider inline-block). 100% of the child width will refer to its own width since its parent is shrink-to-fit.
I use clamp and compare 100% with 175px.
If 100% > 175px we have (100% - 175px)*10000 a big positive value clamped to 100vw, your full width behavior (we have to hide the overflow)
If 100% < 175px we have (100% - 175px)*10000 a big negative value clamped to 175px
#container {
overflow:hidden;
}
.text-div {
width: clamp(175px, (100% - 175px)*10000, 100vw);
background:yellow;
margin:5px;
}
.wrap {
float: left;
clear: left;
}
<div id="container">
<div class="wrap">
<div class="text-div">
Short Text
</div>
</div>
<div class="wrap">
<div class="text-div">
Looooooooooooooooooooooooooong Text
</div>
</div>
</div>

Here is how you could achieve the desired result by adding some Javascript.
document.querySelectorAll('.text-div').forEach( div => {
if(div.clientWidth > 175){
div.classList.add('long-text');
}else{
div.classList.add('short-text');
}
})
.text-div {
display: table;
border: dotted 2px;
}
.short-text{
width: 175px;
}
.long-text{
width: 100%
}
<div id="container">
<div class="text-div">
Short Text
</div>
<div class="text-div">
Looooooooooooooooooooooooong Text
</div>
</div>

Related

css not calculating width correctly when children have percent assigned

This is another css weirdness..
Inline-block container will calculate width correctly when using px,vw,em etc. But not when using % measure.
percent :
pixels ( correct ) :
HTML
.clip{
width: 100%; overflow:hidden;
position:relative;
}
.show-width-con{
min-width: 100%;
display:inline-block;
white-space:nowrap;
}
.element-perc{
width:24%;
display:inline-block;
vertical-align: top;
position: relative;
}
.element-px{
width:300px;
display:inline-block;
vertical-align: top;
position: relative;
}
<div class="clip">
<div class="show-width-con">
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
</div>
</div>
<br><br>
<div class="clip">
<div class="show-width-con">
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
</div>
</div>
the pen is https://codepen.io/digitalzoomstudio/pen/BYWEoG
The 25% is 25% of the container which is 100% of the window. So, if your window is 1200px 25% of that will be 300px; 300px * 6 (the number of divs you have) = 1800px. So, you want to know why the first parent container measures 1200 and the second at 1800.
The 100% width refers to the container, not the content inside. If you take the min-width off of .show-width-con you will see that your 25% containers have no width either (because 25% of nothing is nothing). Since you have a min-width of 100%, that gives the first container a width of 1200px (which is 100%) and therefore your 25% containers are now 300px wide. And the overflow is clipped but it doesn't change the width of the holding container.
However, since it is a minimum width and not a total width, the container holding the 300px will grow to its max size which is 1800 (300 * 6). However, if you change min-width to width, you will see that this container also measures 1200px, which is 100% of the window.
Or, maybe it helps to think about it like this: It would make no sense if the parent container measured 1800px, if it did 300px would not be 25%, 450px would be. But then 450px * 6 = 2700, but 25% of 2700 is 675 and 675 * 6 = 4050, and on and on. However, no matter what your window size is, 300px is 300px.
.clip{
width: 100%;
max-width: 100%;
position:relative;
}
.show-width-con {
font-size: 0;
min-width: 100%;
max-width: 100%;
display:inline-block;
}
.element-perc {
font-size: 16px;
width:25%;
display:inline-block;
vertical-align: top;
position: relative;
}
.element-px{
font-size: 16px;
width:300px;
display:inline-block;
vertical-align: top;
position: relative;
}
<div class="clip">
<div class="show-width-con">
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
<div class="element-perc">25%</div>
</div>
</div>
<br><br>
<div class="clip">
<div class="show-width-con">
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
<div class="element-px">300px</div>
</div>
</div>
Inline-block elements contain pseudo spaces, one of the quirks still around.
Which can be solved using html comments between elements.
Or by setting the font size of the parent container to 0; and to reset the font size back in the child elements.
For creating layouts i would recommend a float grid (if you need to worry about browser support), flexbox, or css grid though.
More flexbox or css grid since you seem to want to vertically align things.
hope this helps.
Resources:
css-tricks
treehouse-post

How to have two sub-divs the same height as each other

I need to make two .tinted-containers the same height as each other (using CSS if possible) but each one is under a grid column.
I can't tint the grid columns because they use padding to create the
gutters and I'd have no white space between the tinted containers if
I tint the background.
It's a %-based grid so adding a margin to both
columns takes the width to over 100%.
<div class="grid-row">
<div class="grid-column-half">
<div class="tinted-container">
<p>Taller</p>
<p>column</p>
<p>on</p>
<p>left</p>
</div>
</div>
<div class="grid-column-half">
<div class="tinted-container">
<p>This container should be the same height as the other one.</p>
</div>
</div>
</div>
How can I make the containers the same height?
Flexbox can do that:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.grid-row {
display: flex;
}
.grid-column-half {
border: 1px solid grey;
width: 50%;
padding: 10px
}
.tinted-container {
height: 100%;
background: pink;
}
<div class="grid-row">
<div class="grid-column-half">
<div class="tinted-container">
<p>Taller</p>
<p>column</p>
<p>on</p>
<p>left</p>
</div>
</div>
<div class="grid-column-half">
<div class="tinted-container">
<p>This container should be the same height as the other one.</p>
</div>
</div>
</div>
You will need to set heights of the div elements to get them to the same size.
The reason you need to do this is because the divs are not all set as one specific height or width, it depends on what is contained within them, and what they are contained in. With a simple example like this, simply setting it to a static height of 200px and putting a border, you can see that the divs are the same height. Without declaring a height, both divs would be different heights, and you could play with that on the fiddle.
To see this working, check out the fiddle here: https://jsfiddle.net/john_h/rnnjx28m/
You can add this CSS to set the heights on your class:
.tinted-container {
height: 200px;
border: 1px solid black;
}
.grid-column-half {
float: left;
display: inline-block;
}
And your html can stay the same:
<div class="grid-row">
<div class="grid-column-half">
<div class="tinted-container">
<p>Taller</p>
<p>column</p>
<p>on</p>
<p>left</p>
</div>
</div>
<div class="grid-column-half">
<div class="tinted-container">
<p>This container should be the same height as the other one.</p>
</div>
</div>
</div>
You will need to play with your spacing to get your intended look!

Set width of element to width of sibling

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);

CSS nested div height 100% doesn't work

I hope that someone can help me about this problem. I have structure like this
<div id="Div1" style="height:auto">
<div id="Div2" style="height:100%;">
<div id="Div3" style="min-height:100%;"></div>
<div id="Div4" style="height:100%;"></div>
</div>
</div>
Also I put in my css file
html,body
{
height: 100%;
}
Problem is that neither Div3 nor Div4 have the expected height of 100%, I check size of first two divs with firbug and they are ok, filling the whole screen.
Sorry for my bad English, I hope that you understand my question :)
Have a look at this. When using a percentage, each div will be affected by the height of it's parent.
In this example the html,body has a height of 100% and the percentage of each div child is then relative to it's parent. Note how each div is half the size of it's parent div, each step it shrinks by half the size.
Updated with all percentage example
Simple example
HTML
<div>
<div>
<div>
<div></div>
</div>
</div>
</div>
CSS
html, body {
height: 100%;
}
div {
height: 100%;
background: #F00;
}
div div {
background: #FF0;
height: 50%;
}
div div div {
background: #000;
height: 50%;
}
div div div div {
background: #F30;
height: 50%;
}
First of all write height in inline style
<div id="Div4" height:100%;"></div>
change to
<div id="Div4" style="height:100%;"></div>
The key is to set the height of the div with id "Div1" to something other than "auto". Try 100% or a specific value like this
<div id="Div1" style="height:100%;">
<div id="Div2" style="height:100%;">
<div id="Div3" style="min-height:100%;"></div>
<div id="Div4" height:100%;"></div>
</div>
</div>

css - How do I make the height of two right divs equal the height of the left divs

I have a site that is divided into two classes: right and left. The left had 3 boxes in it and the right had one. The box on the right's height would stretch or shrink to be the same as the sum of the height's of the left boxes. I have added another box underneath the box on the right and I want the same effect now with the two boxes (the sum of the height of the two boxes on the right should always equal the sum of the height of the three boxes on the left. Here is the old code that worked with the one box on the right:
<div class="right">
<div class="boxx details-history">
<div class="boxx-content">
Box content goes here
</div>
</div>
</div>
And here is the css:
.right{ float: right; display: inline; width:404px; position:relative; }
.boxx { margin-top:11px; }
.boxx:first-child { margin-top:0; }
.boxx .boxx-content { background: #fff; padding:4px 18px; color:#a7a7a7;
font-family: 'Roboto', sans-serif; font-weight:300; border-radius: 0 0 3px 3px; }
.details-history .boxx-content { padding: 0 0 0 0!important; position:absolute;
left:0; right:0; bottom:0; top:22px; }
Here is the new code:
<div class="right">
<div class="boxx details-history">
<div class="boxx-content">
Box content goes here
</div>
</div>
<div class="boxx details-coursework">
<div class="boxx-content custom-scroll">
Box content goes here
</div>
</div>
</div>
I've been trying for several hours now to write some css to make this work, but i can't seem to get it right. I think the trick has something to do with taking the 'position: absolute;' out of .details-history and putting it into a new class called details-coursework, but i can't figure out exactly what to do.
I used some sort of the task. In my example, there are two boxes: left and right. The right box should automatically adjust its height according to left box's height (which may be arbitrary). There is a lot of scrollable text in the right box.
#container {
width: 200px;
}
#left-positioner-parent {
position: relative;
/* Width of the left box relative to #container.
Could be in pixels too. */
width: 50%;
}
/* Contained style to exclude use of calc()
with border width and height in #right-box */
#left-box {
border: 15px solid red;
}
#right-box {
position: absolute;
/* To exclude use of calc() */
box-sizing: border-box;
left: 100%;
width: 100%;
top: 0;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
border: 5px solid black;
}
#right-content {
/* No need of styling for this example */
}
<!-- A container for useful example width -->
<div id="container">
<!-- A different div for the left content is to allow
the left div to have borders without using CSS calc()
and border width and height in right div's style. -->
<div id="left-positioner-parent">
<div id="left-box">Left<br>block of text.</div>
<div id="right-box">
<!-- Some long scrollable content -->
<div id="right-content">Right<br>block<br>of<br>text<br>with<br>multiple<br>lines.</div>
</div>
</div>
</div>
Only way I can see this working without JS is to set heights for all the elements
HTML
<div class="wrapper">
<div class="left">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
<div class="right">
<div class="one"></div>
</div>
</div>
CSS
.left {
width : 50%;
height : 1000px;
background : rgba(0,0,200,0.1);
float : left;
}
.right {
width : 50%;
height : 1000px;
background : rgba(200,0,0,0.1);
float : right;
}
.left div {
margin : auto;
margin-top : 20px;
width : 90%;
height : 100px;
background : rgba(200,0,0,0.1);
border : #FFFFFF 1px solid;
}
.right .one {
margin : 20px auto;
width : 90%;
height : 344px;
background : rgba(200,0,0,0.1);
border : #FFFFFF 1px solid;
}
Check out this Fiddle
You have to fake it. You simply can't do this with CSS. Percentage based heights with known number of boxes could help, but you would need JS to at least calculate and set the height of the parent. Without knowing your design, the easiest way to do this is something like this:
<div class="container">
<div class="right">
Whatever Content You Want
</div>
<div class="left">
Whatever Content You Want
</div>
<div class="clear"></div>
</div>
.right {
float:right;
width:404px;
}
.left { margin-right:404px; }
.clear { clear:both; } /* Or another clearing method */
This will create what you have for columns inside of a container that is as tall as the tallest element. What you would then do is put a backgound-image on the .container element that has a 404px graphic of some sort just on the right side of it. That would make it look like the right side appear as if it is as tall as the left side, but without it actually being that tall.