I have a parent container that has some text (anonymous block) and a child element (a div or a pseudo-element).
I am taking a look to the Image Replacement Museum but am not sure about what is the best solution for my case.
I need to hide the text and still display the inner div.
<div class="parent">
Some text
<!--<div class="child">
</div>-->
</div>
.parent {
display:table;
}
.child,
.parent:after {
display:table-cell;
vertical-align: middle;
text-align: center;
}
.parent:after {
content: "Icon";
}
How can I hide "Some text" maintaining my child element in the flow (so no position:absolute; child should resize the parent) and vertically/horizontally centered?
Note: the only size I know is the width of the child; all the other measures should be flexible and assumptions should not be made.
[EDIT]
I need to maintain the support for screen readers so that the original text would be still read.
Moreover wrapping the text in an element is not always possible for me (I would like a CSS solution).
Given the contraints, I suspect font-size:0 on the parent and a font-size:1rem reset on the child would be optimal.
.parent {
display: table;
border: 1px solid grey;
font-size: 0;
margin-bottom: 1rem;
}
.child,
.pseudo:after {
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 1rem;
padding: 1em;
background: lightblue;
}
.pseudo:after {
content: "Icon";
}
<div class="parent pseudo">
Some text
<!--<div class="child">
</div>-->
</div>
<div class="parent">
Some text
<div class="child">Child
</div>
</div>
You can't. You need to wrap the text in a tag like span or that you want.
<div class="parent">
<span>Some text</span>
<div class="child">
</div>
</div>
.parent {
display:table;
}
.parent > span {
visibility : hidden;
}
.child {
display:table-cell;
vertical-align: middle;
text-align: center;
}
Related
This question already has answers here:
Align inline-block DIVs to top of container element
(5 answers)
Why is this inline-block element pushed downward?
(8 answers)
Closed last year.
I keep running into this problem - I have html like this:
<div class="line">
<div class="word">hello</div>
<div class="word">there</div>
<div class="word"></div>
</div>
and this css:
.line
{
background-color:red;
padding:10px;
}
.word
{
display:inline-block;
width:200px;
height:40px;
padding:10px;
background-color:white;
}
And I get this:
Why is it happening, and how do I fix it so that an empty string is formatted exactly the same as a string with values?
Vertical align
You could apply vertical-align:top to .word
.line {
background-color: red;
padding: 10px;
}
.word {
display: inline-block;
width: 100px;
height: 40px;
padding: 10px;
background-color: white;
vertical-align: top;
}
<div class="line">
<div class="word">hello</div>
<div class="word">there</div>
<div class="word"> </div>
<div class="word"></div>
</div>
Empty selector
Or add a rule for empty .word divs, but this would still be malformed for divs with spaces in them. Could be helpful if you can't change the vertical-align
.line {
background-color: red;
padding: 10px;
}
.word {
display: inline-block;
width: 100px;
height: 40px;
padding: 10px;
background-color: white;
}
.word:empty:before {
content: "\0020";
display: inline-block;
}
<div class="line">
<div class="word">hello</div>
<div class="word">there</div>
<div class="word"> </div>
<div class="word"></div>
</div>
Why is this happening
Vertical alignment determines how 'inline' elements are positioned in relation to each other. by default it's set to baseline
Baseline will try to put 'most' of the text above the baseline and some of the dangling bits like the g p and q and y under the baseline.
That would make sense for text, the browser will attempt to do that for all text. Even text that's wrapped in divs and styled with paddings.
The entire empty div is put on the baseline.
Browser manufacturers just agreed that this is how it should be done.
If you look at it as if it where a text editor, It would make sense for small inline images, the default would be to push the entire line down based on the dimension of the image
Equal height <div> elements can be achieved when applying the .line class style display: flex.
.line {
background-color:red;
padding:10px;
display: flex;
}
.word {
border: 1px solid red;
margin-left: 5px;
margin-right: 5px;
width: 200px;
height: 40px;
padding: 10px;
background-color: white;
}
<div class="line">
<div class="word">hello</div>
<div class="word">there</div>
<div class="word"></div>
</div>
would be glad if someone would help :)
Depending on the situation, there are two possibilities. Two divs with the same class side by side, and div with different classes, depending on the situation I would like to add css to the first div with class image when next to is albo div with class image
1.
<div class="image"></div>
<div class="image"></div>
.image {
padding-right: 40px;
}
Is it possible two give some rule like below but only for the first div with class image when the second div with class image is next to.
.image + .image {
padding-right: 5px
}
You cannot select depending on descendants or subsequent siblings; from any point you've already reached in your selector, you can only select onward/downward.
What you can do to achieve the desired result is to put a wrapper element around your elements, and then exclude :last-child:
.outer { font-size: 0; border: 1px solid #333; display: inline-block; }
.inner {
background-color: #ccc;
display: inline-block;
height: 40px;
width: 40px;
}
.inner:not(:last-child) {
margin-right: 20px;
}
<div class="outer">
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
</div>
I need to create a container div with a pulled-up toggle button (but this could be also a simple span, a label or everything else), but that can be also re-sizable.
Unfortunately (https://css-tricks.com/almanac/properties/r/resize/):
Super important to know: resize does nothing unless the overflow property is set to something other than visible, which is its initial value for most elements.
I tried to write a simple example to compare limits of each conflicting properties (below only an extract):
<div class="container">
<button>Toggle</button>
<div class="content">...</div>
</div>
<div class="container overflow-hidden">
<button>Toggle</button>
<div class="content">...</div>
</div>
.container {
border:solid 1px red;
position:relative;
resize:horizontal;
}
.overflow-hidden {
overflow:hidden;
}
button {
position:absolute;
top:-20px;
}
I can't figure out how to solve this problem, so how to have a resizable container that can show an overflowed item (Possibly with only CSS)?
how to have a resizable container that can show an overflowed item
For resize to work, the element need an overflow other than visible, so the answer to that is no.
I need to create a container div with a pulled-up toggle button
If you alter your markup a little, you can do like this
Fiddle demo
Stack snippet
.container {
position: relative;
display: inline-block;
}
.overflow-hidden {
border: solid 1px red;
width: 50%;
height: 80%;
margin-top: 18px;
resize: horizontal;
padding: 20px;
overflow: hidden;
}
button {
position: absolute;
top: 0;
left: 0;
}
.content {
border: solid 1px blue;
height: 100px;
}
<div class="container">
<button>Toggle</button>
<div class="overflow-hidden">
<div class="content">
WITH "overflow:hidden":
<br> "resize" feature is available <strike>but pulled-up button is obviously semi-hidden</strike>
</div>
</div>
</div>
Is there a way to achieve this whilst being responsive?
Right now the button inherits the height from the headline (its width also changes). I'd rather not have to set a fixed height on the button, or put it in a wrapper.
http://jsfiddle.net/frank_o/JfnjY/14/
I've tried with both table:
.container4 {
display: table;
}
.container4 h1, .container4 .button {
display: table-cell;
}
.container4 p {
display: table-row;
}
And flex:
.container1 {
display: flex;
}
.container1 .button {
margin-left: auto;
}
.container1 p {
/* Add something here to make the `p` go below the `h1` */
}
What should I do?
There could be many ways of realizing this layout. Here is one way of doing it.
Consider the following HTML snippets:
<div class="container container1">
<div class="button">Click me</div>
<h1>Table-cell lipsum</h1>
<p>This is how I want it, except the button shouldn't inherit any height.</p>
</div>
<div class="container container2">
<div class="button">Click me</div>
<div class="sub-wrap">
<h1>Table-cell lipsum</h1>
<p>This is how I want it, except the button shouldn't inherit any
height. Morbi consequat, purus nec suscipit luctus...</p>
</div>
</div>
and the following CSS:
.container {
border: 2px solid red;
margin: 20px;
}
.button {
padding: 5px 17px;
border: 2px solid;
display: inline-block;
white-space: nowrap;
float: right;
}
.container1 h1 {
background-color: beige;
overflow: auto;
margin: 0;
}
.container1 p {
background-color: pink;
}
.container2 .sub-wrap {
overflow: auto;
background-color: lightblue;
}
In both cases, I floated the button to the right and used display: inline-block to keep a shrink to fit width/height, and white-space: nowrap to keep the text on a single line.
In the first case, .container1, I used overflow: auto on h1 to keep the text from interfering with the button. The p will just be in normal flow below the title and button.
In the second case, .container2, I wrapped the title and paragraph in a block level element .sub-wrap which has overflow: auto, that way neither the paragraph nor the title wrap around the button.
See demo at: http://jsfiddle.net/audetwebdesign/Dap4M/
DEMO
You can keep the table-cell property but don't apply it directly on button class, instead make a wrap with table-cell & then define your button this way button wont have to apply full height!
HTML:
<div class="container container4">
<h1>Table-cell lipsum</h1>
<div class="button-wrap">
<div class="button">Click me</div>
</div>
<p>This is how I want it, except the button shouldn't inherit any height.</p>
</div>
CSS:
.container4 h1, .container4 .button-wrap {
display: table-cell;
vertical-align: top;
}
It's a good practice to keep the layout classes separate from the actual elements classes.
The task I encountered looks standard: I have a fixed height container and 3 div's inside it. I want the 2nd div to be stretched between the top and the bottom div's. When the contents of the 2nd div overflows - I would like to show the scroll bars.
I know how to accomplish this task using the absolute positioning. A question is: can I do it using the table on divs?
An additional requirement: if possible, I would like to avoid setting header's height as fixed.
I have tried to code it in my fiddle, but, as you see, I failed.
CSS:
.container {
height: 500px;
background-color: gainsboro;
}
.table {
display: table;
height: 100%;
}
.table > div {
display: table-row;
}
.table > div > div {
display: table-cell;
vertical-align: middle;
border: 1px solid black;
overflow: scroll;
}
.center > div {
height: 100%;
}
.content {
height: 700px;
}
HTML:
<div class="container">
<div class="table">
<div>
<div>XXX</div>
</div>
<div class="center">
<div>
<div class="content"></div>
</div>
</div>
<div>
<div>YYY</div>
</div>
</div>
</div>
Here is one possible solution:
<div class="container">
<div class="header">
<div>Top Header Block</div>
</div>
<div class="center">
<div class="content">
<p>Lorem ipsum ...</p>
<p>Lorem ipsum ...</p>
</div><!-- .content -->
</div><!-- .center -->
<div class="footer">
<div>Bottom Footer Block</div>
</div>
</div>
and the CSS:
.container {
height: 200px;
}
.header, .footer {
background-color: gainsboro;
}
.center {
height: inherit;
}
.content {
background-color: #F0F0F0;
height: inherit;
overflow: auto;
}
Since you are fixing the height of the container, you inherit the height both in the .center and the .content <div>'s.
If you tweak the container height, the center div expands but the header and footer div's stay the same height.
Use overflow on the content div to allow for scrolling.
Fiddle Reference: http://jsfiddle.net/audetwebdesign/nae5z/
Your way was right, just make a few changes (See this Fiddle):
html, body, .container, .table {
margin: 0;
height: 100%;
}
#header,#footer {
height: 1px;
}
This should work because tables cells get increased in height if the content needs it.
Just a hint: You may improve the whole thing, for example I would use HTML 5 and the <header/> and <footer/> elements. But that was not part of your question. Anyway, here is another update to your fiddle:
<div>
<header>
<div>XXX</div>
</header>
<main>
<div>
<div class="content"></div>
</div>
</main>
<footer>
<div>YYY</div>
</footer>
</div>
With CSS:
html, body, body > div {
margin: 0;
height: 100%;
}
body {
background-color: gainsboro;
}
body > div {
display: table;
width: 100%;
}
body > div > * {
display: table-row;
}
body > div > * > div {
display: table-cell;
vertical-align: middle;
border: 1px solid black;
}
header, footer {
height: 1px;
}
main is very new to HTML 5, just if you're wondering.