I have the following problem. I have a div inside of which there are 2 elements. First element can have children inside of it. Second element has only text.
I want to display text if only there are no elements inside of the previous element.
Ok, this is hard to understand, so here is a reproducible fiddle. As you see I have 2 boxes (inside of the first element) and text in the second element. So in this way I want the div with text to be hidden. But if I will remove the boxes, the text should appear.
Using javascript there were no problems with this at all (calculate the size of the elements inside of the span and if 0 - show text, not 0 - hide text). The problem is that I am trying to achieve the same with pure HTML and CSS.
Is there a way to do this?
You can fake it;
give the container a fixed height and an hidden overflow;
give the text a min-width of 100% and an inline-block display;
If there is something before it, the text will be pushed down, and hidden:
Running demo
HTML
With squares, Text doesn't show:
<div class="content">
<span>
<div class="box"></div>
<div class="box"></div>
</span>
<div class="content-empty">Text</div>
</div>
Without, it does:
<div class="content">
<span></span>
<div class="content-empty">Text</div>
</div>
CSS
.content {
border: 2px dashed #bbb;
margin-top:20px;
height: 94px; /* new */
overflow: hidden; /* new */
}
.box {
width: 80px;
height: 80px;
border: 2px solid #444;
display: inline-block; /* new */
margin: 5px;
background-color: #eee;
}
.content-empty {
text-align: center;
vertical-align: middle;
line-height: 94px;
font-size: 26pt;
display: inline-block; /* new */
min-width: 100%; /* new */
background: silver;
}
No, it is not possible in CSS to have a selector that would select an element according to whether its sibling has children or not.
You can use css3 for this
.content > span:empty + .content-empty{display: none;}
or
.content > span + .content-empty{display: none;}
Check Jsfiddle Demo
Related
is it possible just with pure css to attach last two divs inside span with its last word so it would wrap with the last word? Even when you dynamically resize window?
Here is html :
<span>Some text that will be here
<div class="class1" style=""></div>
<div class="class2"></div>
</span>
Here is css :
.class1 {
display: inline-block;
width: 19px;
height: 19px;
margin-left: 5px;
vertical-align: text-bottom;
background-image: url(some.png);
background-repeat: no-repeat;
cursor: pointer;
}
.class2 {
float: none;
display: inline-block;
vertical-align: text-bottom;
width: 20px;
height: 20px;
margin-left: 5px;
background: url(some2.png) -154px 0px no-repeat;
cursor: pointer;
}
I want the span to wrap only with the use of last word when i try to resize the window. What happens now is that it first wrap the class2 div, then class1 div and after then it starts to wrap the text. Ive seen many solutions using just display:inline but when i use display:inline on the divs it losts it width so i dont think its a possible solution here. Is there any way with pure css solution to attach those two divs with last word of the text so it wraps together when you resize the window? I cant encapsulate last word with those two divs inside another element like this :
<span>Some text that will be
<span class="encaps">here
<div class="class1" style=""></div>
<div class="class2"></div>
</span>
</span>
Because the text is always different length and i dont know before what the last word will be.
Thank you in advance for your responses.
UPDATE
I am writing down some examples of behaviour that i want to accomplish when the window is resizing:
Bad behaviour:
1.)
Some text will be here*div*
*div*
2.)
Some text will be here
*div**div*
Good behaviour:
Some text will be
here*div**div*
You can wrap all of the text in a span and then allow line breaks inside that span, but not between it and the divs. You will need to apply that styling to the container span. This works as follows.
Note that I made some very minor changes to your example (changed divs in spans into spans to make the HTML valid, changed image URLs so they resolve to something, minor style changes), but the main idea is the styling of the .wrap and .nowrap elements. The .wrap element is an added element, a span wrapping the text.
I have created a JSFiddle as well, so it is easier to change the viewport size and test the wrapping.
.class1 {
display: inline-block;
vertical-align: text-bottom;
width: 19px;
height: 19px;
margin-left: 5px;
background-image: url('https://placehold.it/19');
background-repeat: no-repeat;
cursor: pointer;
}
.class2 {
display: inline-block;
vertical-align: text-bottom;
width: 20px;
height: 20px;
margin-left: 5px;
background: url('https://placehold.it/20') no-repeat;
cursor: pointer;
}
.nowrap {
white-space: nowrap;
/* no line breaking */
font-size: 0;
/* hide text between text and divs */
}
.wrap {
white-space: normal;
/* allow line breaks in span */
font-size: 1rem;
/* normal font size */
}
<span class="nowrap">
<span class="wrap">Some text that will be here</span>
<span class="class1"></span>
<span class="class2"></span>
</span>
I found this stackoverflow answer very interesting. It works to vertically center text of any length in a div of any height. Basically it uses a empty <span> tag directly in front of the node containing text, and
HTML:
<div>
<span></span><p>This is really really long text but it will be centered vertically.</p>
</div>
CSS:
div {
background: yellow;
color: red;
width: 200px;
text-align: center; /* horizontally center */
height: 300px; /* any height */
padding: 0 20px
}
div span:first-child {
height: 100%;
vertical-align: middle;
display: inline-block;
}
div p {
margin: 0;
vertical-align: middle;
display: inline-block;
}
Also even more interesting is if you separate closing span tag (</span>) and opening paragraph tag (<p>) on two separate lines, or if you add a whitespace between the two, the trick breaks.
My question is - how does this trick work? How is span helping center the text? And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?
I have created a fiddle to demonstrate both points: https://jsfiddle.net/axRxE/385/
My question is - how does this trick work? How is span helping center the text?
Since you give the span inline-block property, the span then inherits it's parent height (with height: 100%) - which in you example is a fixed 300px. And since you gave also the same property to the paragraph, those two elements are one next to each other. See an example:
#parent {
height: 300px;
}
span {
height: 100%;
display: inline-block;
/* some width and background-color for demonstration */
width: 5px;
background-color: red;
}
p {
margin: 0;
display: inline-block;
}
<div id="parent">
<span></span>
<p>foobar</p>
</div>
And you also put vertical-align: middle (which works with inline-block) on both of them, which gives them that align (you only need to add that property to the larger one):
#parent {
height: 300px;
}
span {
height: 100%;
display: inline-block;
/* some width and background-color for demonstration */
width: 5px;
background-color: red;
/* added vertical-align */
vertical-align: middle;
}
p {
margin: 0;
display: inline-block;
}
<div id="parent">
<span></span>
<p>foobar</p>
</div>
And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?
That's simple - when you use inline-block there is always a whitespace issue between them. And since you didn't add some width to the paragraph, it takes all the width it can take, and with that additional width from the whitespace, the paragraph goes below the span.
In your example, your parent has 120px width, the span uses 0px, so the paragraph takes all of the parents width, which is 120px. Now, with the additional whitespace (which is ~ 4px), since she paragraph uses all the width, the whitespace doesn't fit so the paragraph "breaks" - it goes below the span.
Also check:
inline-block element with no text renders differently
Vertical-Align: All You Need To
Know.
I want to have two divs in a single row with the left div's text getting clipped based on the right div's width(the text in the div is dynamically generated) hence we cannot fix the widths of these divs(the text in the right div must be completely visible whereas the text in the left div can be clipped).This image shows the sample output:
here is the fiddle:
http://jsfiddle.net/UzqLZ/1/
here is the html part of code:
<div class="parent">
<div class="text">This text must be hidden if it is overflowing</div>
<div class="number">88818888.333346</div>
</div>
Can someone help me with this.
How does this look: http://jsfiddle.net/P6Nbg/
I've given the parent position relative and a background colour of white for the number div so it hides the text below.
.parent {
width: 30%;
position: relative;
overflow: hidden;
}
.number {
display: inline-block;
position: relative;
background-color: white;
float:right;
}
.text {
display: inline-block;
position: absolute;
background-color: transparent;
white-space:no-wrap;
overflow:hidden;
float:right;
}
Here is one way of doing it.
You need to add an inner wrapper element around your text as follows:
<div class="parent">
<div class="text">
<div class="inner">This text must be hidden if
it is overflowing</div>
</div>
<div class="number">88818888.333346</div>
</div>
Now use the following CSS:
.parent {
display: table;
width: 30%;
border: 1px dotted blue;
font-size: 1.00em;
line-height: 1.50em;
}
.number {
display: table-cell;
border: 1px dotted blue;
}
.text {
display: table-cell;
}
.inner {
height: 1.50em;
overflow: hidden;
word-break: break-all;
}
Apply display: table to .parent and specify the font-size and line-height.
Apply display: table-cell to .number and .text.
The .inner block will fill up the rest of the width not taken up by .number,
and the text will wrap onto two or more lines. If you specify the height to be one line, then you can use overflow: hidden to hide the extra text.
Using word-break: break-all may be a good idea.
See demo at: http://jsfiddle.net/audetwebdesign/QBQVg/
I am trying to display 2 values on the same row and give the one on the right priority to grow (it is a mobile app and needs to detect the width of the screen and "squash" the left cell to be smaller.
Here is my attempt: http://jsfiddle.net/rodneyjoyce/TxBhD/
HTML
<div id="screen">
<div id="leftDesc">This is a Long Description</div>
<div id="rightDesc">1000</div>
</div>
CSS
#screen
{
width: 200px;
}
#leftDesc
{
display: inline-block;
overflow: hidden;
float: left;
height: 20px;
max-width:160px;
color: blue;
}
#rightDesc
{
float: right;
display: inline-block;
text-align: right;
color: red;
}
What should happen: Increase "1000" to "1000 000". Blue text should chop off the end of the word "Description" and the red and blue text should stay on the same line.
Disclaimer: I am not very good at CSS - in XAML I use the * value on width so that a cell auto-grows and shrinks the others.
I do not want to use Javascript or JQuery.
I'm not sure if you can dynamically change the size of your floated elements with CSS based on the content, but part of the problem can be solved with:
Adding to #leftDesc:
text-overflow:ellipsis;
white-space:nowrap;
The white-space property keeps the text on one line; text-overflow should be pretty self-explanatory.
JSFiddle
Use the flexible box layout:
#screen
{
width: 200px;
display: -webkit-flex;
display: -moz-flex;
display: flex;
}
#leftDesc
{
overflow: hidden;
height: 20px;
color: blue;
white-space:nowrap;
}
#rightDesc
{
text-align: right;
color: red;
}
I've removed your floats and your inline-blocks, and added display: flex to get the boxes to behave.
I've also added white-space:nowrap; to make sure the description gets cut off, like you've asked.
I've also removed max-width:160px;, because it didn't appear to have any effect in this scenario.
Keep in mind that this will not work in IE.
Here is the jsfiddle
In my example, giving either of the children elements a bottom margin causes its sibling to be pushed down by whatever margin I specify; I hadn't anticipated seeing anything move since the container is larger than each div. Why is this the case?
HTML
<div class=container>
<section></section>
<aside></aside>
</div>
CSS
.container {
background: whitesmoke;
height: 12em;
width: 12em;
}
.container section {
background: slategray;
display: inline-block;
height: 04em;
margin-bottom: 20px;
width: 04em;
}
.container aside {
background: gold;
display: inline-block;
height: 04em;
width: 04em;
}
Add vertical-align: top to your section element. As these elements are ìnline-block, they are not simply behaving as boxes anymore - they have flowing text properties. It is not really the margin that is pushing down the other element, it is the default vertical-align property they have.
jsFiddle Demo
Other Demo that shows the effect with text - the key is vertical-align