How to vertical middle align div with uncertain height img? - css

UI told me to make a list, the list item height is not fixed, it depends on the images uploaded by user, and the user may upload a 10x1000 image or 1000x10 image, whatsoever, the image width is fixed to 100px, but height is auto. At right side of the image, there are some text written by user, which is not a one line text, it is multiline text which we don't know how many lines there will be.
html like below:
<ul>
<li class="container">
<img src="https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
<div class="aaa">
aaa<br>bbb<br>ccc
</div>
</li>
<li class="container">
<img src="https://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/9358d109b3de9c822f4d68126981800a19d84307.jpg">
<div class="aaa">
ddd<br>eee<br>ffff
</div>
</li>
</ul>
css as below:
.container {
border: 1px solid green;
padding: 1px;
position:relative;
}
.container img {
width: 300px;
vertical-align: middle;
}
.aaa {
display: inline-block;
font-size: 16px;
border: 1px solid red;
box-sizing: border-box;
}
.bbb {
border: 1px solid blue;
}
But the result is as below:
How can I make the text box vertical align middle to the image at left side?
All code is at Codepen, you can try it there.
Thank you!

Declare vertical-align: middle on the sibling element (.aaa) as well.
To display x2 sibling inline block-level elements vertically center to each other, both elements should have the property vertical-align: middle.
Code Snippet Demonstration:
.container {
border: 1px solid green;
padding: 1px;
position:relative;
}
.container img {
width: 300px;
vertical-align: middle;
}
.aaa {
display: inline-block;
font-size: 16px;
border: 1px solid red;
box-sizing: border-box;
vertical-align: middle; /* additional */
}
.bbb {
border: 1px solid blue;
}
<ul>
<li class="container">
<img src="https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
<div class="aaa">
aaa<br>bbb<br>ccc
</div>
</li>
<li class="container">
<img src="https://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/9358d109b3de9c822f4d68126981800a19d84307.jpg">
<div class="aaa">
ddd<br>eee<br>ffff
</div>
</li>
</ul>

You can use the power of flex.
Use align-items: center to do the trick.
Check it out: https://codepen.io/anon/pen/dJmrvB

Solution1: Just apply vertical-align: middle; to .aaa class
.container {
border: 1px solid green;
padding: 1px;
position: relative;
}
.container img {
width: 300px;
vertical-align: middle;
}
.aaa {
display: inline-block;
font-size: 16px;
border: 1px solid red;
box-sizing: border-box;
vertical-align: middle;
}
.bbb {
border: 1px solid blue;
}
<ul>
<li class="container">
<img src="https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
<div class="aaa">
aaa<br>bbb<br>ccc
</div>
</li>
<li class="container">
<img src="https://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/9358d109b3de9c822f4d68126981800a19d84307.jpg">
<div class="aaa">
ddd<br>eee<br>ffff
</div>
</li>
</ul>
Solution2: Try to make use of flex CSS
.container {
border: 1px solid green;
padding: 1px;
position: relative;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.container img {
width: 300px;
}
.aaa {
font-size: 16px;
border: 1px solid red;
box-sizing: border-box;
}
.bbb {
border: 1px solid blue;
}
<ul>
<li class="container">
<img src="https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
<div class="aaa">
aaa<br>bbb<br>ccc
</div>
</li>
<li class="container">
<img src="https://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/9358d109b3de9c822f4d68126981800a19d84307.jpg">
<div class="aaa">
ddd<br>eee<br>ffff
</div>
</li>
</ul>

Related

CSS: How to control the render order of borders?

I have a container with some tabs:
<div class="tabbed-container">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="active nav-link">Tab 1</a>
</li>
<li class="nav-item">
<a class="nav-link">A longer tab name</a>
</li>
<li class="nav-item">
<a class="nav-link">Last tab</a>
</li>
</ul>
<div class="tab-content">
<p>
Hey look, some content!
</p>
<p>
More content!
</p>
</div>
</div>
.
body {
background-color: white
}
*, *::after, *::before {
box-sizing: border-box;
}
.tabbed-container {
display: flex;
flex-direction: column;
margin: 2em;
background-color: white;
}
.nav {
display: flex;
padding-left: 0;
margin-bottom: 0;
list-style: none;
justify-content: space-between;
}
.nav-tabs .nav-item {
margin: 0 3px -1px 3px;
flex: 1 1 auto
}
.nav-tabs > .nav-item:first-child {
margin-left: 0px;
}
.nav-tabs > .nav-item:last-child {
margin-right: 0px;
}
.nav-tabs .nav-item a {
border-radius: 10px 10px 0 0;
padding: 1em;
border: 0px;
border-bottom: 1px solid transparent;
background-color: #e4e4e4;
text-align: center;
}
.nav-tabs .nav-item a.active,
.nav-tabs .nav-item a:active {
background-color: white;
border: 1px solid #e4e4e4;
border-bottom: 1px solid white;
}
.nav-link {
display: block;
}
.tab-content {
padding: 1em;
width: 100%;
border: 1px solid #e4e4e4
}
fiddle: https://jsfiddle.net/pqmefsbr/34/
I would like for there not to be any border between the content and the active tab. To this end, I've changed the margin on .nav-tabs .nav-item from margin: 0 3px to margin: 0 3px -1 3px, and added border-bottom: 1px solid white to the active tab. This doesn't seem to have accomplished anything, though.
After playing around with the border color and thickness to see what is actually going on, it looks like the border of the content div is always being rendered on top of the tab's border, so my white border-bottom is accomplishing nothing. What can I do to get the tab's border to render on top instead? Is there possibly some other way to accomplish what I'm trying to do?
Stacking without the z-index property | MDN
When the z-index property is not specified on any element, elements
are stacked in the following order (from bottom to top):
The background and borders of the root element Descendant
non-positioned blocks, in order of appearance in the HTML Descendant
positioned elements, in order of appearance in the HTML
Short answer is:
.nav-tabs {
position: relative;
...
}
Related examples:
.a {
height: 20px;
background: pink;
margin-bottom: -10px;
}
.b {
height: 40px;
border: 10px solid gray;
}
.relative {
position: relative;
}
.z-index {
z-index: 1;
}
<h3>Example 1: all default</h3>
<div class="a"></div>
<div class="b"></div>
<h3>Example 2: 1st position: relative</h3>
<div class="a relative"></div>
<div class="b"></div>
<h3>Example 3: both position: relative</h3>
<div class="a relative"></div>
<div class="b relative"></div>
<h3>Example 4: both position: relative + 1st z-index: 1</h3>
<div class="a relative z-index"></div>
<div class="b relative"></div>

Z-index doesn't work with flex elements? [duplicate]

This question already has answers here:
Flexbox, z-index & position: static: Why isn't it working?
(1 answer)
Understanding z-index stacking order
(1 answer)
Closed 5 years ago.
I'm trying to have two columns, one being a menu which can expand and overlap the other column. But I used a flex element to wrap these columns and my menu expands behind the other element, even with a greater z-index.
The render is something like this:
.main {
font-family: 'Open Sans', Helvetica, sans-serif;
display: flex;
background-color: #99baef;
}
nav {
height: 100%;
width: 8em;
background-color: black;
z-index: 1;
}
.navbox {
box-sizing: border-box;
background-color: black;
color: white;
height: 4em;
width: 100%;
text-align: center;
line-height: 4em;
border-top: 1px dotted #99baef;
transition: all 1s;
}
.navbox:hover {
width: 130%;
border-top: none;
background-color: #4a77c4;
color: black;
}
.container {
padding: 1em;
}
a {text-decoration: inherit;}
<div class="main">
<div class="maincolumn">
<nav>
<a href="">
<div class="navbox">
Nav 1
</div>
</a>
<a href="">
<div class="navbox">
Nav 2
</div>
</a>
</nav>
</div>
<div class="maincolumn">
<div class="container">
<h2>Title</h2>
<p>This is a text.</p>
</div>
</div>
</div>
See? I want my menu to overlap the rest of my page when expanding. How can I do that?
The z-index property only effects elements that have a position value other than static (the default) or are flex items (direct children of display: flex or display: inline-flex).
There are two options to make the z-index work in your case:
Set the z-index to the 1st .maincolumn, which is a flexbox item:
.maincolumn:first-child {
z-index: 1;
}
.main {
font-family: 'Open Sans', Helvetica, sans-serif;
display: flex;
background-color: #99baef;
}
.maincolumn:first-child {
z-index: 1;
}
nav {
height: 100%;
width: 8em;
background-color: black;
}
.navbox {
box-sizing: border-box;
background-color: black;
color: white;
height: 4em;
width: 100%;
text-align: center;
line-height: 4em;
border-top: 1px dotted #99baef;
transition: all 1s;
}
.navbox:hover {
width: 130%;
border-top: none;
background-color: #4a77c4;
color: black;
}
.container {
padding: 1em;
}
a {text-decoration: inherit;}
<div class="main">
<div class="maincolumn">
<nav>
<a href="">
<div class="navbox">
Nav 1
</div>
</a>
<a href="">
<div class="navbox">
Nav 2
</div>
</a>
</nav>
</div>
<div class="maincolumn">
<div class="container">
<h2>Titre</h2>
<p>This is a text.</p>
</div>
</div>
</div>
or
Set position: relative to nav:
nav {
position: relative;
height: 100%;
width: 8em;
background-color: black;
z-index: 1;
}
.main {
font-family: 'Open Sans', Helvetica, sans-serif;
display: flex;
background-color: #99baef;
}
nav {
position: relative;
height: 100%;
width: 8em;
background-color: black;
z-index: 1;
}
.navbox {
box-sizing: border-box;
background-color: black;
color: white;
height: 4em;
width: 100%;
text-align: center;
line-height: 4em;
border-top: 1px dotted #99baef;
transition: all 1s;
}
.navbox:hover {
width: 130%;
border-top: none;
background-color: #4a77c4;
color: black;
}
.container {
padding: 1em;
}
a {text-decoration: inherit;}
<div class="main">
<div class="maincolumn">
<nav>
<a href="">
<div class="navbox">
Nav 1
</div>
</a>
<a href="">
<div class="navbox">
Nav 2
</div>
</a>
</nav>
</div>
<div class="maincolumn">
<div class="container">
<h2>Titre</h2>
<p>This is a text.</p>
</div>
</div>
</div>
Flex items are only direct children of flex-container.
Flex items respect z-index order, but you are applying z-index not to flex-items but to their descendants.
From w3c flexbox spec:
Flex items paint exactly the same as inline blocks CSS21, except that order-modified document order is used in place of raw document order, and z-index values other than auto create a stacking context even if position is static.
So for this to work you should apply greater z-index to your first flex item. Demo:
.main {
font-family: 'Open Sans', Helvetica, sans-serif;
display: flex;
background-color: #99baef;
}
.maincolumn:first-child {
z-index: 1;
}
nav {
height: 100%;
width: 8em;
background-color: black;
}
.navbox {
box-sizing: border-box;
background-color: black;
color: white;
height: 4em;
width: 100%;
text-align: center;
line-height: 4em;
border-top: 1px dotted #99baef;
transition: all 1s;
}
.navbox:hover {
width: 130%;
border-top: none;
background-color: #4a77c4;
color: black;
}
.container {
padding: 1em;
}
a {text-decoration: inherit;}
<div class="main">
<div class="maincolumn">
<nav>
<a href="">
<div class="navbox">
Nav 1
</div>
</a>
<a href="">
<div class="navbox">
Nav 2
</div>
</a>
</nav>
</div>
<div class="maincolumn">
<div class="container">
<h2>Title</h2>
<p>This is a text.</p>
</div>
</div>
</div>

top align 2 divs of dynamic height within a containing div

I am trying to top-align two child divs in a containing div. The child divs contain different content and may be of varying heights. Is there a way I can make the two child divs top-align?
Here's a fiddle to illustrate the problem - http://jsfiddle.net/billafy/Rhj36/3/
HTML
<div class="headerStuff">
Header
</div>
<div class="sectionArea">
<div class="leftPanel">
<div><img src="http://placekitten.com/50/50" alt="some image1" /></div>
<div><button>test</button></div>
</div>
<div class="rightPanel">
<div><img src="http://placekitten.com/50/50" alt="some image2" /></div>
<div>
<span>Some other text</span>
<div>
<span>And some additional content</span>
</div>
</div>
</div>
</div>
<div class="footerStuff">
Footer
</div>
CSS
.headerStuff {
font-size: 20pt;
background-color: purple;
border: 1px solid lime;
}
.sectionArea {
width: 100%;
display: inline-block;
height: 370px;
text-align: center;
vertical-align: middle;
border: 1px solid lime;
}
.leftPanel {
display:inherit;
border: 1px solid orange;
}
.rightPanel {
display:inherit;
border: 1px solid blue;
}
.footerStuff {
font-size: 20pt;
background-color: red;
border: 1px solid lime;
}
Use vertical-align: top; to both panels.
CSS:
.leftPanel {
display:inherit;
border: 1px solid orange;
vertical-align: top;
}
.rightPanel {
display:inherit;
border: 1px solid blue;
vertical-align: top;
}
You could use vertical-align:text-top; in your right and left panels.

Display blocks in line with scroll

I have folowing code:
html:
<div class="container">
<div class="content">
<ul>
<li class="item">a</li>
<li class="item">bb</li>
<li class="item">ccc</li>
<li class="item">dddd</li>
<li class="item">eeeee</li>
</ul>
</div>
</div>
css:
.container{
width: 200px;
background-color: red;
overflow: hidden;
}
.content ul{
padding: 0px;
margin: 0px;
}
.item{
padding: 1px 10px 1px 10px;
background-color: green;
border: 1px black solid;
margin: 1px;
display: inline-block;
}
http://jsfiddle.net/VSfHS/183/
And i need to display items in one row with scrollable overflow.
Number of items is dynamic, so I can't preset width of content.
Here you go.
http://jsfiddle.net/VSfHS/184/
The solution is white-space: nowrap

CSS grid with single line on hover

I have created a grid with div boxes on http://jsfiddle.net/TsRJy/.
The problem
I don't know how to make the a:hover work.
Info
Rewrite the HTML code as a table is not an option for me.
http://www.normann-copenhagen.com/Products succeded with this issue.
I prefer CSS before Javascript.
HTML (in case jsfiddle don't work)
<div class="container">
<div class="grid">
<div class="item">
<a href="#">
</a>
</div>
<div class="item">
<a href="#">
</a>
</div>
<div class="item">
<a href="#">
</a>
</div>
<div class="item">
<a href="#">
</a>
</div>
<div class="item">
<a href="#">
</a>
</div>
<div class="item">
<a href="#">
</a>
</div>
<div class="item">
<a href="#">
</a>
</div>
</div>
</div>
CSS
.container {
margin: 0 auto;
width: 500px;
}
.item {
border: 1px solid #ccc;
float: left;
margin: 0 -1px -1px 0;
}
.item a {
display: block;
height: 100px;
width: 100px;
background: #f5f5f5;
}
.item a:hover {
border: 1px solid black;
}​
​
You can use box-sizing property for this. Write like this:
.item a:hover {
border: 1px solid black;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
}
Check this http://jsfiddle.net/TsRJy/1/
try this one,just minor change in css
.container {
margin: 0 auto;
width: 500px;
}
.item { float: left; }
.item a {
display: block;
height: 99px;
width: 99px;
background: #f5f5f5;
border: solid 1px #d6d6d6;
border-width: 0 1px 1px 0;
}
.item a:hover {
border: solid 1px #f00;
margin: -1px 0 0 -1px;
}
http://jsfiddle.net/GtR3P/
for more accurate result try this one also hope this one solve your issue
.container {
margin: 0 auto;
width: 506px;
}
.item { float: left; }
.item a {
display: block;
height: 100px;
width: 100px;
background: #f5f5f5;
border: solid 1px #d6d6d6;
border-width: 0 1px 1px 0;
}
.item a:hover {
border: solid 1px #f00;
margin: -1px 0 0 -1px;
}
.grid .item:nth-child(5n+1) a { border-left-width:1px; }
.grid .item:nth-child(5n+1) a:hover { margin:-1px 0 0 0; }
Since you have put border, the hover effect is not working properly.
.item a:hover {
box-shadow: 2px 2px 2px #333;
background-color:Teal
}​
Look at this fiddle
Also here is a useful link
Also another way to go, it's to set border-color the same color as the box's background-color and change it to black on hover:
.item a {
display: block;
height: 100px;
width: 100px;
background: #f5f5f5;
border: 1px solid #f5f5f5;
}
.item a:hover {
border-color: black;
}​
Demo: http://jsfiddle.net/TrXT9/1/
I see your wrapper has a width of 500px. If you make a div with a width of 100px, a border of 1px and a margin-right of -1px, the div is still 101px.
box-sizing:border-box is a beautiful way to solve this problem, but it is not supported in IE7
If you want IE7-support, you need to adjust your width and height like this:
http://jsfiddle.net/TsRJy/5/

Resources