I want the item (inner div) to be fully contained inside the container/wrapper (outer div). That is, even if the content overflows in the inner div it will not spill over and overlaps with the outer div padding.
Code Sample Of The Problem
.inner {
/* Overflow */
overflow-wrap: break-word;
word-break: break-all;
overflow: hidden;
color: white;
}
.outer {
width: 100px;
height: 100px;
display: inline-block;
background-color: black;
padding-top: 15px;
padding-bottom: 15px;
overflow: hidden
}
<div class="outer">
<div class="inner">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since
</div> </div>
I expect it to be like this: enter image description here
where the inner div can be as long as it needs to.
I have tried multiple different kinds of overflow settings. I also used "border" instead of padding. The inner div keeps overflowing the outer div regardless.
.inner {
/* Overflow */
height: 100%;
overflow-wrap: break-word;
word-break: break-all;
overflow: hidden;
color: white;
}
Adding height: 100% to the .inner container solves this problem - you need to tell the inner container how tall you want it to display - or it will display to the height of the content inside of it.
Height: 100% only works here because you have explictly set a height on one of the parent containers of .inner, in this case .outer has a height of 100px
Related
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());
}
}
I have the following HTML and CSS
div
{
width: 450px;
background-color: pink;
}
h1
{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-color: yellow;
}
button
{
float: right;
}
<div>
<h1>LONGTEXTLONGTEXTLONGTEXTLONGTEXTLONGTEXTLONGTEXT
<button type="button">X</button>
</h1>
</div>
https://jsfiddle.net/0k49bvo9/
The problem I have is how to make the 'x' button go up on same line with text and float right (like how it looks when text is smaller).
I can't modify the HTML, I only need to achieve this by CSS or, if it's really necessary, by JS.
Rather than making the button float right, you might want to position it absolutely.
button {
position: absolute;
top: 0;
right: 0;
}
For the button positioning to be relative to the parent element h1, that one has to be positioned either relative or absolute as well.
So you add
h1 {
position: relative;
}
In a last step, you add some padding-right to your h1 to make sure your ellipsis (or text) don't overlap with the button:
h1 {
padding-right: 20px;
}
https://jsfiddle.net/0k49bvo9/2/
Could you maybe do something like this?
div
{
width: 450px;
background-color: pink;
}
h1
{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-color: yellow;
position:relative; /* adding this */
}
button
{
position:absolute;
right:0px;
top:0px;
}
Adding the position relative to the H1 means that the button with absolute positioning won't break the boundaries of the h1, meaning it will sit on top of the text
When I add dynamic content to .innerright. Why doesn't the width of .a increase dynamically. What should I do it to make sure .a takes width of .innerright container dynamically. I use javascript code to add the content dynamically.
var list = '';
for (var i = 0; i < 100; i++) {
list = list + i + 's';
}
$('.innerright').append(list);
.outer {
width: 500px;
height: 200px;
background-color: red;
}
.innerleft {
width: 20%;
float: left;
height: 100%;
background-color: yellow;
}
.innerright {
width: 80%;
height: 100%;
float: left;
background-color: green;
overflow: scroll;
}
.a {
height: 20px;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="outer">
<div class='innerleft'>
</div>
<div class='innerright'>
<div class="a">
</div>
</div>
</div>
It's because you set a calculated width on the container element and specifically tell the container to deal with overflowing content by adding a scroll bar.
As far the css is concerned the element is always at it's calculated width and the extra content just expands into the overflow area rather than affecting the container's width.
I'm not sure this is fixable in css alone while maintaining the overflow property to scroll. Everything is doing as it should, the elements are taking the widths they should take and that is being maintained throughout dynamic content editing - overflow is not part of width.
You could use the javascript scrollWidth value and use that to dynamically edit the width of the .a element.
See the fiddle here
The important bit is:
$('.a').width($('.innerright')[0].scrollWidth);
which gets the scroll width of the .innerright element, that includes the width and the overflow and uses that to set the width of the .a element, which also now goes into the overflow area.
And of course, you'll need to call and recall this after you add any dynamic content!
NB, the [0] means get the first element in the array of DOM nodes returned by the JQuery call.
As others pointed out, block elements don't grow, they overflow. You're CSS makes that overflow scrollable. In order to acheive your goal, wrap the content (<a> and text) in an inline-block element, which will grow, and now you're <a> will receive it's parent (grown) width, and the <div> will still have scrollable overflow:
var list = '';
for (var i = 0; i < 100; i++) {
list = list + i + 's';
}
$('.contentspan').append(list);
.outer {
width: 500px;
height: 200px;
background-color: red;
}
.innerleft {
width: 20%;
float: left;
height: 100%;
background-color: yellow;
}
.innerright {
width: 80%;
height: 100%;
float: left;
background-color: green;
overflow: scroll;
}
.a {
height: 20px;
border: 1px solid red;
}
.contentspan {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="outer">
<div class='innerleft'>
</div>
<div class='innerright'>
<span class='contentspan'>
<div class="a">
</div>
</span>
</div>
</div>
By the way, this has nothing to do with dynamic content or JS. If the text was inlined in the HTML you'd get the exact same results.
For example, I have a div :
<div>I am a square</div>
Inside style.css :
div:nth-child(1) {
height: 200px;
width: 200px;
border-radius:0;
background-color: pink;
color: #fff;
text-align: center;
}
The text-align: center property aligns the text in the center of a div, but the text remains on the top inside the square, I want to push the text to the bottom of a square. So it looks like in this diagram. How can I accomplish this without wrapping the text in any sort of tag?
__________________
| |
| |
| |
| |
| |
|_I am a square__|
If you really don't want to wrap your text
You can do this by setting the display of the block to be table-cell, and then vertical-align to bottom. This is the only way I can think of to align the text to the bottom of the div without wrapping it in another element. This will cause a slew of other problems with your div placement, though; and you will probably have to wrap the div anyway.
div {
height: 200px;
width: 200px;
border-radius:0;
background-color: pink;
color: #fff;
text-align: center;
/* Here is my addition */
display: table-cell;
vertical-align: bottom;
}
JsFiddle example.
If you wrapping your text is an option (AKA the right way)
You really should wrap your text. Aside from semantics, you can get a lot more flexibility in your styling options.
Once you do that, your div can be set to position: relative so that it can act as a container for the child, who will get the position: absolute style. Then you add bottom: 0 and voila! It's glued to the bottom.
This method is preferred as you can still style your div as you'd expect.
HTML:
<div>
<p>test</p>
</div>
<div>
<p>test</p>
</div>
CSS:
div {
height: 200px;
width: 200px;
border-radius:0;
background-color: pink;
color: #fff;
text-align: center;
margin : 0 3px 3px 0;
/* Make sure that it contains the child properly */
position: relative;
}
div p {
position : absolute;
bottom : 0;
}
Example
Is there a CSS way to vertically align my div within the body element?
The thing is my div will have a different height each time, so its not constant.
These are the things I've tried but they dont work:
body { vertical-align: middle; }
#mainContent {
vertical-align: middle;
}
// Also this
body { margin-top: 20%; margin-bottom: 20%; }
I did it without table: (demo on dabblet.com)
The main trick in this demo is that in the normal flow of elements going from top to bottom, so the margin-top: auto is set to zero. However, for an absolutely positioned element acts the same distribution of free space, and similarly can be centered vertically at the specified top and bottom (does not work in IE7).
This trick will work with any sizes of div.
HTML:
<div></div>
CSS:
div {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
A common problem indeed. I have seen many people offering straight css solutions for this but they all require knowing the height of the element needing to be centered, so no help there.
I usually do it this way using jquery:
$(document).ready(function(){
site.resize();
$(window).resize(function(){
site.resize();
});
});
var site = {
resize: function(){
var new_margin = Math.ceil(($(window).height() - $('#mainContent').height()) / 2);
$('#mainContent').css('margin-top', new_margin + 'px');
}
};
Surprisingly (or not), the vertical-align tool actually works best for this job. Best of all, no Javascript is required.
In the following example, I am positioning the outer class in the middle of the body, and the inner class in the middle of the outer class.
Preview: http://jsfiddle.net/tLkSV/513/
HTML:
<div id="container">
<span></span><div class="outer">
<span></span><div class="inner">
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
padding: 0; }
#container {
text-align: center;
height: 100%; }
span {
height: 100%;
vertical-align: middle;
display: inline-block; }
.outer {
width: 100px;
height: 200px;
padding: 0;
border: 1px solid #000;
vertical-align: middle;
display: inline-block; }
.inner {
background: red;
width: 30px;
height: 20px;
vertical-align: middle;
display: inline-block; }
Vertical align works by aligning the centers of elements that are next to each other. Applying vertical-align to a single element does absolutely nothing. If you add a second element that has no width but is the height of the container, your single element will move to vertically center with this no-width element, thus vertically centering it. The only requirements are that you set both elements to inline (or inline-block), and set their vertical-align attribute to vertical-align: middle.
Note: You may notice in my code below that my <span> tag and <div> tag are touching. Because they are both inline elements, a space will actually add a space between the no-width element and your div, so be sure to leave it out.
You can do it without using tables, and without adding extra elements:
<ul>
<li>One short item</li>
<li>Any real long text...</li>
<li>Another short item</li>
</ul>
And then the CSS:
ul {
list-style-type: none;
display: table-row;
}
li {
display: table-cell;
vertical-align: middle;
}
You can see it here
It would work with any other kind of hierarchy, including div, p, etc.
Honestly, my opinion is often that if you're doing vertical alignment you should still be using a table. I know it's often frowned upon, but it is still the simplest and cleanest way to vertically center something.
HTML
<table>
<tbody>
<tr>
<td>
<div>Your DIV here.</div>
</td>
</tr>
</tbody>
</table>
CSS
td {vertical-align: middle;}