Centering an <img> vertically inside of a table <td> - javascript

I am trying to center these images vertically inside of the table without having to edit the picture so that they are the same size. Tried a few things... I know whenever I want to center something horizontally I use margin-left: auto; margin-right: auto; So I thought maybe the same would apply here, but with top and bottom, but no dice.
EDIT: Here is another idea... would it be possible to set up a javascript to run as the page is opened to position all of the text spans as low as the lowest span in that row?
Just a thought... let me know what you think
Any help would be much appreciated.
Here is the fiddle: http://jsfiddle.net/58u4g/1/
Thanks in advance

CSS vertical alignment is different across all browsers - especially if you want to keep the text in the same cell.
I recommend creating a fixed height block for the images to go in, and using a vertical align hack to get the image vertically centered within that div (I know, hacks are bad).
JSFiddle: http://jsfiddle.net/58u4g/8/
Vertical align hack: http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
Relevant CSS:
.valign {
width: 100%;
display: block;
display: table;
height: 100%;
#position: relative;
overflow: hidden;
}
.valign > span {
display: block;
#position: absolute;
#top: 50%;
display: table-cell;
vertical-align: middle;
}
.valign> span > span {
display: block;
#position: relative;
#top: -50%;
}
#posiflex_directory td .image {
height: 160px;
display: block;
}

I'd do it differently for the sake of separating elements to have better control over them, even though my fiddle is not clean and is a mash of your sample plus the bits I through in :)
<table id="posiflex_directory">
<tr class="theimgs">
<td>
<a href="../posiflex/tx_overview.aspx" id="posiTXIcon">
<span class="valigner"></span>
<img height="125" src="https://www.metsales.com/MetropolitanSales/microsite/posiflex/images/home_icons/tx-4200.png" width="200"/>
</a>
</td>
<td>
<a href="../posiflex/cd_overview.aspx" id="posiCDIcon">
<span class="valigner"></span>
<img height="103" src="https://www.metsales.com/MetropolitanSales/microsite/posiflex/images/home_icons/CR6300.png" width="200"/>
</a>
</td>
</tr>
<tr>
<td class="imgtext"><span>TX Fan-Free Series</span></td>
<td class="imgtext"><span>Cash Drawers</span></td>
</tr>
</table>
#posiflex_directory {
text-align: center;
}
#posiflex_directory a {
color: inherit;
position: relative;
}
#posiflex_directory td {
border: solid 1px;
}
#posiflex_directory .theimgs {
width: 215px;
height: 225px;
padding: 5px;
border: solid 1px;
}
#posiflex_directory span {
left: 0;
right: 0;
top:100%;
bottom: 5px;
text-decoration: underline;
font-weight: bold;
}
img {
border: solid 1px;
}
.valigner {
display: inline-block;
height: 100%;
vertical-align: middle;
}
.imgtext{
height:40px;
}

Related

HTML - Fitting images in multiple rows to fit viewport

I am developing a website, in which I display N amount of images. A good example of how I would like to display them is how DeviantArt does it. Images are shown in rows in such a way that it fills the width of the current viewport and does not deform any images.
My attempt was the following:
#CSS
.item {
display: inline-block;
vertical-align: top;
position: relative;
overflow: hidden;
padding: 0.5em;
background: lightcoral;
border: black solid 1px;
}
.item img{
max-height: 200px;
object-fit: scale-down;
}
HTML
<div style="display: block; width: 100%">
<!-- A vue directive, used in this example to render this element n amount of times per images -->
<div class="item" v-for="(i, index) in images" :key="index">
<img :src="i.url">
<div style="display: flex; flex-direction: column;">
<div>{{i.title}}</div>
<div>By User1234</div>
</div>
</div>
</div>
Which results in the following:
As you can see, there are gaps left at the end of each row. Id like for each row to be able to fit all possible images so that the grid fits the viewport, like this:
Im very interested to know how I can achieve this, either by using pure HTML / CSS or Javascript if needed.
You probably want to use flexbox with flex-grow.
CSS-Tricks has a great article on this here: https://css-tricks.com/piecing-together-approaches-for-a-css-masonry-layout/
Here's a codepen from the article:
codepen
body {
margin: 0;
padding: 1rem;
}
.masonry-with-columns {
display: flex;
flex-wrap: wrap;
div {
height: 150px;
line-height: 150px;
background: #EC985A;
color: white;
margin: 0 1rem 1rem 0;
text-align: center;
font-family: system-ui;
font-weight: 900;
font-size: 2rem;
flex: 1 0 auto;
}
#for $i from 1 through 36 {
div:nth-child(#{$i}) {
$h: (random(400) + 70) + px;
width: $h;
}
}
}

Is there a jQuery way to make a <div> appear at the lower left of a table cell that won't destroy responsiveness?

I need to get a <div> to be at the bottom left corner of a table cell. Something like float: left; and float: bottom; together.
A typical cell is:
<td id="x0900A"> <!-- 0900 room A -->
<p class="classTitle">
</p>
<div class="classDescrip">
</div>
<p class="instructor">
</p>
<p class="gender">
</p>
<div class="instructorBio">
</div>
<div class="instructorImg">
</div>
<div id="x0900A-roomCount" class="roomCount">
<p id="x0900A-attending" class="attending">attending</p>
<p id="x0900A-capacity" class="capacity">capacity</p>
</div>
</td>
The CSS is:
td {
position: relative;
}
div[id$=roomCount] {
position: absolute;
bottom: 0;
left: 0;
width: 80px;
margin: 10px 10px 0 5px;
text-align: left;
opacity: 0.60;
}
.classTitle {
float: left;
margin: 5px 10px 10px 5px;
padding: 0 5px 0 5px;
line-height: 1.25em;
font-size: 1.05em;
text-align: left;
color: #00b8b8;
}
.instructor {
width: 50%;
float: right;
margin: 3px 0 10px 0;
padding: 0 3px 5px 3px;
line-height: 1.25em;
font-size: 0.95em;
text-align: right;
color: #00b8b8;
}
.classDescrip,
.instructorBio,
.instructorImg,
.gender {
display: none;
}
This locks .roomCount to the <td>'s bottom left but destroys responsiveness. I get horizontal overflow scrolling of the whole <body>. You can see the result here.
I tried putting a wrapper <div> inside the <td> and making it
position: relative;
height: 100%;
but it's only so tall as the wrapped content requires which, for many cells, is only partway down.
So, I need a CSS/jQuery way to anchor .roomCount that doesn't break responsiveness.
Note:
This is a resubmission of an earlier question that was too wordy and had much irrelevant content. I'm resubmitting it here in the hope that it will garner notice.
Edit/Update:
In response to #UdoE's comment: I have included the code and edited the "wordiness." At least, I hope I have and made it a better question.
In response to #ChrisG's labeling this a possible duplicate: I already noted that this is a resubmission of that question and the reason why I did it. There are no answers or comments to that question as of this writing.
If you set overflow: hidden; on the div that wraps around the element:
<div class="sqs-block code-block sqs-block-code" data-block-type="23" id="block-4f3956fa4071adb2096e">
...the horizontal scroll on the body will go away. There is already a rule affecting this element in site.css on line 13:
.sqs-block:not(.sqs-block-html):not(.sqs-block-markdown) {
clear: both;
overflow: hidden; /* add this */
}
For keeping the .roomCount element positioned in the lower left of the cell, maybe this approach can help:
.schedule td {
position: relative;
padding-bottom: 30px;
}
div[id$="roomCount"] {
margin: 0;
position: absolute;
bottom: 0;
left: 0;
max-height: 30px;
overflow: hidden;
}
What this does is place 30px of padding at the bottom of the td. Then uses absolute positioning to move the .roomCount element into the lower left corner.
This way, even though absolute positioned elements are out of flow, the padding gives you an area to work with that is going to be accounted for when the table is resizing. I added a max-height and overflow: hidden on that element just in case. It will probably take some tweaking to get right for you.
Here is a jsFiddle

Show one element if another is above a certain height

I have a following HTML:
<span class="day-number">{{day-number}}</span>
<div class="event-box">
<div class="event-container">
</div>
<div class="more-events">more ...</div>
</div>
Event-container is filled with an unknown number of .event elements like the following:
<div class="event">{{event-name}}</div>
I want to show or hide the .more element based on if the .event-container has a height of over 76px (equal to the height of four .event elements stacked).
The styling for the above elements:
.event {
text-align: left;
font-size: .85em;
line-height: 1.3;
border-radius: 3px;
border: 1px solid #3a87ad;
background-color: #3a87ad;
font-weight: normal;
color: whitesmoke;
padding: 0 1px;
overflow: hidden;
margin-bottom: 2px;
cursor: pointer;
}
.event-box {
max-height: 76px;
overflow: hidden;
position:relative;
}
.event-box .more-events {
height: 10px;
position: absolute;
right: 0;
bottom: 10px;
display: none;
z-index: 5;
}
No styling for .event-container
I can do what I want with Javascript (jQuery):
$(".event-box").each(function(){
var $this = $(this);
if($this.children(".event-container").height() > 76){
$this.children(".more-events").css("display", "block");
} else {
$this.children(".more-events").css("display", "");
}
});
And run that every time a make a change, but I'd rather do it with CSS.
Is this possible? Maybe with pseudo elements or media queries or something?
JSFIDDLE: http://jsfiddle.net/pitaj/LjLxuhx2/
If changing the markup is acceptable there is a possibility to achieve a somewhat similarly looking page without using JavaScript to show or hide, here is the Fiddle
I have removed <div class="more-events">more ...</div> line and made elements of event class to get hide when it is necessary I also made them to appear when hovering over more ... .
The CSS I have added:
.event:nth-child(n){
display: none;
}
.event:nth-child(1),.event:nth-child(2),.event:nth-child(3),.event:nth-child(4){
display: block;
}
.event:nth-child(5){
text-indent: -9999px;
position: relative;
display: block;
color: black;
border: none;
background-color: #FFF;
}
.event:nth-child(5)::before{
position: absolute;
text-indent: 0px;
content: "more ...";
display: block;
}
.event:nth-child(5):hover{
position: static;
text-indent: 0;
border: 1px solid #3a87ad;
background-color: #3a87ad;
color: whitesmoke;
}
.event:nth-child(5):hover::before{
display:none;
}
.event:nth-child(5):hover ~ .event:nth-child(n){
display: block;
}
And for .event-box class I have commented out max-height: 76px; because in my browser 76px was not equal to the height of four .event elements stacked. Also removed update function.
I dont think it's possible using css only. but for better approach in what you are trying to do.instead of using max-height for .event-box I use this css which is add display:none to +4.event on your event container:
.event-box .event-container .event:nth-child(n+5){
display: none;
}
and now when it's more than 4 .event your more text appears. FIDDLE
UPDATE:
HERE I make little change in you js as well and make it more professional,
while you are using template to render the page, maybe you can do it as follow
<div class="event-container">
{{#each events}}
<div class="event">{{event-name}}</div>
{{/each}}
</div>
{{#if canshowmore}}
<div class="more-events">more ...</div>
{{/if}}
and
function canshowmore() {
return events.length >= 4;
}

Table Fix Height For All Row

I want table content to align center for horizontal and vertical. I've done for that. But I need help to fix some code. Check out this JSFiddle and example code below: http://jsfiddle.net/yiedpozi/a8ZLJ/
CSS example code:
div.container {
width: 500px;
height: 200px;
}
table {
width: 500px;
height: 300px;
table-layout: fixed;
}
td, tr {
border: 1px solid red;
}
td {
text-align: center;
vertical-align: middle;
padding: 20px;
}
span.description {
display: none;
}
JS example code:
$('td').hover(
function () {
$(this).find('span.description').css({
'display': 'block'
});
},
function () {
$(this).find('span.description').css({
'display': 'none'
});
}
);
You can see, if hover, it will show description, but height of table row will increase. I want it to be fix, so, before hover, title will center, when hover, all content will center, but not affect table content height. How can I do this?
Try setting a height in td, to a value which can hold both default and hover content.
td {
text-align: center;
vertical-align: middle;
padding: 20px;
height: 120px;
}
JSFiddle
Update the following css classes:
td {
text-align: center;
vertical-align: middle;
padding: 20px;
height:100px;
}
span.description {
display: none;
height:80px;
overflow:auto;
}
look at the updated JSFillde
You need to add a div tag inside each with class on div.
Just like that.
<td>
<div class="setHeight">
<span class="title">This Is Title</span>
<span class="description">Here is description. Here is description. Here is description. Here is description. Here is description.</span>
</div>
</td>
You can add setHeight class as well.
div .setHeight{
width:auto;
height:100px;
}
http://jsfiddle.net/CodeAstro/a8ZLJ/2/

Conflicting hover/mouseover functions

Relative newbie here. I have two different mouseover/hover functions I can get to work just fine: one, an inline mouseover that 'darkens' an image/box by making it lose opacity; and the second, text that appears over this image/box on hover (jumping up from a hidden position).
The problem is, I want to get them working together without this text losing opacity, which it does when part of the same div class as the image/box. But when I try two separate div classes and position them on top of each other (using z-index), whichever one I put on top seems to block the other one. Is there any way to have it so the image/box loses opacity, but the text that appears doesn't, all in the same mouseover/hover action?
These are the relevant bits in my stylesheet, mostly covering the text part:
.rightbox {
background: rgb(140, 183, 98);
width: 290px;
height: 160px;
margin-bottom: 18px;
padding: 2px;}
.rightboxtext {
display: table-cell;
height: 160px;
width: 290px;
vertical-align: bottom;
text-align: center;
font-weight: bold;
font-size: 20px;
color: #8CB762;
}
.rightboxtext span {
display: block;
height: 0px;
overflow: hidden;
}
.rightboxtext:hover span {
height: 80px;
}
This is the inline stuff that I used where everything, including text, gets the opacity treatment. (In this case the image is attached to the rightboxtext div class, but I also tried it attached to the rightbox div class.)
<div class="rightbox"
onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"
onmouseover="this.style.opacity=0.6;this.filters.alpha.opacity=60">
<div class="rightboxtext"
style="background-image: url(image.jpg); height: 160px; width: 290px;">
<span>Hello text.</span></div>
</div>
Otherwise I achieved this mangled bit of code, where one seems to block the other:
<div class="rightboxcontainer">
<div class="rightboxtext"
style="position: absolute; z-index: 100; height: 160px; width: 290px;">
<span>Hello text.</span></div>
<div class="rightbox"
style="position: absolute; z-index: 50; height: 160px; width: 290px;"
onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"
onmouseover="this.style.opacity=0.6;this.filters.alpha.opacity=60"><img
src="image.jpg">
</div>
</div>
With this extra bit in the stylesheet:
.rightboxcontainer { width: 290px; height: 160px; margin-bottom: 18px;}
Thanks in advance!
As a commenter pointed out above, you can do this entirely with CSS:
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 250px;
height: 250px;
overflow: hidden;
}
.box img {
width: 250px;
height: 250px;
}
.box .message {
background: rgba(0, 0, 0, 0.5);
opacity: 0;
width: 250px;
height: 250px;
position: relative;
top: -256px;
color: #fff;
font-size: 32px;
line-height: 250px;
text-align: center;
font-weight: bold;
font-family: arial;
}
.box .message:hover {
opacity: 1;
}
</style>
<div class="box">
<img src="http://www2.le.ac.uk/departments/geology/people/clark-n/personal/copy_of_images/Satellite-map-of-Antarctica/image">
<div class="message">Antarctica</div>
</div>
.message is positioned on top of the container, .box. When you hover over .message, it fades in from 0 opacity. Its background is semi-opaque (using RGBA, where the fourth value is the opacity), so it dims the image. You could make the image the background-image of the .box if you wanted to.
http://jsfiddle.net/dgGG3/4/
Fist of all, try to avoid inline event handling as you can achieve the desired result with css :hover.
The problem as you can see here http://jsfiddle.net/UjY5Q/ is with opacity on a parent element all child elements also get that opacity.
.rightbox:hover {
opacity:0.5;
}
You can cheat on that one by setting positions to the elements and overlap one to the other one. That's kind a tricky and may also need browser support.
so the easyest way to get what you want is on :hover show a transparent background image example here: http://jsfiddle.net/UjY5Q/1/
I would say that's the way to go

Categories

Resources