CSS placing an absolute div beside another div (pure CSS popover) - css

I have a sidebar with a user profile picture (pink color). When the viewer hover on the image, a div (blue color) appears and it contains user details. Basically, I want an absolute positioned div appear next to its sibling.
It is functionally a popover, but I want to do it with pure CSS, is it possible?
I am using boostrap 4, it will be nice if the suggestion can co-exists with Bootstrap CSS. It will be awesome if the div can have an arrow associate with it.
My code is:
<div>
<div><figure class="figure"><img ... /></figure></div>
//css-popover
<div class="css-popover">User detail: ... bla bla bla ...</div>
</div>
I tried to search in Stackoverflow, most of the question is related to float div and makes it beside, but I want something absolute positioned, and display on top of the body.
Update:
Most of the suggestions provided fulfill part of the requests. The suggested .css-popover width and height are bounded by the parents, but I wish the popover dimension be independent from the parent, i.e. just "popup" and it doesn't "change" the layout beneath.
And when the popup appear, it doesn't change the parent height too. I wish the sidebar "icon" (light pink icons) stay in place whenever a popup appear.
If it is not possible with CSS, then I just go for JS solution...
You can try your luck here. https://jsfiddle.net/byanjiong/nohno2bd/13/
(Note: the user content is long, so it height usually will exceed the profile image's height)
Update 2:
Thanks to #Gezzasa, his solution is working. ^_^
Guy, this is the working example of pure CSS popover! Amazing!
https://jsfiddle.net/byanjiong/nohno2bd/15/
Thanks, guy...

https://jsfiddle.net/dqwtvf1g/3/
hover set on the parent and set the child to display: block;
You'll need to add the absolute position etc but this is how I've done it before.
.figure {background-color: #fff; width: 100px; height: 100px;}
.css-popover {display: none; width: 50px; height: 50px; background-color: #fff;}
.parent:hover .css-popover{display: block;}
UPDATE: Made the parent display: inline-block but you can always just add a width.
UPDATE2: I've added some css animation for you as well.
UPDATE3: Edited your fiddle https://jsfiddle.net/byanjiong/nohno2bd/15/

hi you can try something like this
html
<div class="container">
<div class="img-con">
<img src="https://images.google.com/images/branding/googleg/1x/googleg_standard_color_128dp.png" alt="" />
<div class="info-con">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam modi, distinctio nostrum reprehenderit explicabo amet exped
</div>
</div>
</div>
css
.img-con
{
height:150px;
width:150px;
position: relative;
}
.info-con
{
position: absolute;
top:0;
right:0;
background-color: #5C6BC0;
bottom:0;
left:0;
height:100%;
width:100%;
margin:auto;
transition:all ease 0.4s;
padding:3px;
opacity:0;
}
.info-con::after
{
content:"";
position: absolute;
left:-40px;
top:0;
bottom:0;
margin:auto;
height:0;
border:20px solid transparent;
border-right-color:#5C6BC0;
}
.img-con:hover .info-con
{
right:-110%;
left:auto;
opacity:1;
}
link for reference

This is one pure CSS solution.. But i recomend using JS
body {
margin: 0px;
}
.figure {
height: 20px;
width: 100px;
background: pink;
float: left;
margin: 0px;
}
.figure+.css-popover {
height: 50px;
width: 0px;
background: lightblue;
transition: all 0.3s ease;
float: left;
position: relative;
visibility: hidden;
left: 5px;
overflow: hidden;
padding: 10px;
}
.figure+.css-popover::before {
content: '';
display: inline-block;
height: 0px;
width: 0px;
border: 5px solid transparent;
border-right: 5px solid lightblue;
position: absolute;
top: 5px;
left: -10px;
}
.figure:hover+.css-popover,
.css-popover:hover {
width: 100px;
visibility: visible;
overflow: visible;
}
.clearfic,
.clearfix:after,
.clearfix:before {
content: "";
clear: both;
display: table;
}
<div class="clearfix">
<figure class="figure"></figure>
<div class="css-popover">User detail: ... bla bla bla ...</div>
</div>
<div>Some content</div>
EDIT : Added arrow

Change dimensions as per your need
.popover-container{
position: relative;
}
.css-popover{
position: absolute;
}
.css-popover {
background: #88b7d5;
border: 4px solid #c2e1f5;
}
.css-popover:after, .css-popover:before {
right: 100%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.css-popover:after {
border-color: rgba(136, 183, 213, 0);
border-right-color: #88b7d5;
border-width: 30px;
margin-top: -30px;
}
.css-popover:before {
border-color: rgba(194, 225, 245, 0);
border-right-color: #c2e1f5;
border-width: 36px;
margin-top: -36px;
}
<div>
<div class = "popover-container" ><figure class="figure"><img ... /></figure><div class="css-popover">User detail: ... bla bla bla ...</div></div>
</div>

1) With Pure css.
.wrap {
position: relative;;
}
.im {
width: 200px;
}
img {
width: 100%;
}
.css-popover{
display: none;
}
.im:hover + .css-popover {
display: block;
}
figure {
margin: 0;
}
<div class="wrap">
<div class="im">
<figure class="figure"><img src="http://www.mrwallpaper.com/wallpapers/cute-bunny-1600x900.jpg" /></figure>
</div>
<div class="css-popover">User detail: ... bla bla bla ...</div>
</div>
2) With Jquery
$(document).ready(function(){
$('.figure img').hover(function(){
$('.css-popover').css('display','block');
},function(){
$('.css-popover').css('display','none');
})
})
.css-popover {
display: none;
}
img {
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div>
<div>
<figure class="figure"><img src="http://www.mrwallpaper.com/wallpapers/cute-bunny-1600x900.jpg" /></figure>
</div>
<div class="css-popover">User detail: ... bla bla bla ...</div>
</div>

Related

Is there a way to create a header that overlaps on the top of the border of a box using CSS? [duplicate]

I'd like to have a div that looks like this:
Is this possible to do with HTML + CSS? I will also be animating this div with jQuery. When the div is hidden I would like the title and the top line to show.
Yes, but it's not a div, it's a fieldset
fieldset {
border: 1px solid #000;
}
<fieldset>
<legend>AAA</legend>
</fieldset>
You can do something like this, where you set a negative margin on the h1 (or whatever header you are using)
div{
height:100px;
width:100px;
border:2px solid black;
}
h1{
width:30px;
margin-top:-10px;
margin-left:5px;
background:white;
}
Note: you need to set a background as well as a width on the h1
Example: http://jsfiddle.net/ZgEMM/
EDIT
To make it work with hiding the div, you could use some jQuery like this
$('a').click(function(){
var a = $('h1').detach();
$('div').hide();
$(a).prependTo('body');
});
(You will need to modify...)
Example #2: http://jsfiddle.net/ZgEMM/4/
I know a bit late to the party, however I feel the answers could do with some more investigation/input.
I have managed to create the situation without using the fieldset tag - that is wrong anyway as if I'm not in a form then that isn't really what I should be doing.
/* Styles go here */
#info-block section {
border: 2px solid black;
}
.file-marker > div {
padding: 0 3px;
height: 100px;
margin-top: -0.8em;
}
.box-title {
background: white none repeat scroll 0 0;
display: inline-block;
padding: 0 2px;
margin-left: 8em;
}
<aside id="info-block">
<section class="file-marker">
<div>
<div class="box-title">
Audit Trail
</div>
<div class="box-contents">
<div id="audit-trail">
</div>
</div>
</div>
</section>
</aside>
This can be viewed in this plunk:
Outline box with title
What this achieves is the following:
no use of fieldsets.
minimal use of CSS to create effect with just some paddings.
Use of "em" margin top to create font relative title.
use of display inline-block to achieve natural width around the text.
Anyway I hope that helps future stylers, you never know.
Text in Border with transparent text background
.box{
background-image: url("https://i.stack.imgur.com/N39wV.jpg");
width: 350px;
padding: 10px;
}
/*begin first box*/
.first{
width: 300px;
height: 100px;
margin: 10px;
border-width: 0 2px 0 2px;
border-color: #333;
border-style: solid;
position: relative;
}
.first span {
position: absolute;
display: flex;
right: 0;
left: 0;
align-items: center;
}
.first .foo{
top: -8px;
}
.first .bar{
bottom: -8.5px;
}
.first span:before{
margin-right: 15px;
}
.first span:after {
margin-left: 15px;
}
.first span:before , .first span:after {
content: ' ';
height: 2px;
background: #333;
display: block;
width: 50%;
}
/*begin second box*/
.second{
width: 300px;
height: 100px;
margin: 10px;
border-width: 2px 0 2px 0;
border-color: #333;
border-style: solid;
position: relative;
}
.second span {
position: absolute;
top: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
}
.second .foo{
left: -15px;
}
.second .bar{
right: -15.5px;
}
.second span:before{
margin-bottom: 15px;
}
.second span:after {
margin-top: 15px;
}
.second span:before , .second span:after {
content: ' ';
width: 2px;
background: #333;
display: block;
height: 50%;
}
<div class="box">
<div class="first">
<span class="foo">FOO</span>
<span class="bar">BAR</span>
</div>
<br>
<div class="second">
<span class="foo">FOO</span>
<span class="bar">BAR</span>
</div>
</div>
<fieldset>
<legend> YOUR TITLE </legend>
<p>
Lorem ipsum dolor sit amet, est et illum reformidans, at lorem propriae mei. Qui legere commodo mediocritatem no. Diam consetetur.
</p>
</fieldset>
You can use a fieldset tag.
<!DOCTYPE html>
<html>
<body>
<form>
<fieldset>
<legend>Personalia:</legend>
Name: <input type="text"><br>
Email: <input type="text"><br>
Date of birth: <input type="text">
</fieldset>
</form>
</body>
</html>
Check this link: HTML Tag
For a duplicate, here another option with transform, no fieldset ( and rounded border required in the duplicates) :
Question
Help. I am not great at UX. I am creating an app in React and using Material UI for the look. I really want to create something like this
Where the "Some Title" is a dynamic field from my database as well as the contents. The thing I cannot figure out is what is the best (non skanky) way to add the title into the outline? Thoughts?
Answer position or transform can help you too :
* {
margin: 0;
padding:0;
box-sizing:border-box;
}
.fieldset {
border: solid;
color: #353fff;
border-radius: 1em;
margin: 2em 1em 1em;
padding:0 1em 1em;
}
.legend {
transform: translatey(-50%);
width: max-content;
background: white;
padding: 0 0.15em;
}
.fieldset li {
list-style-type: " - ";
}
<div class="fieldset">
<h1 class="legend">Some Title</h1>
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
If you are not in a position to add a field set, you can add a background to the element. In my situation, I had different colors in the input element and outside the input element, and also we have a hover color for the input element. So this is a fix I added linear-gradient background with outside color in the top half and transparent color in the bottom half.
I added the transparent color to the bottom half inorder to see the hover color when hovered.
.class-name {
background: linear-gradient(to bottom, #2a2b2d 50%, transparent 50%);
}
From a practical perspective, I think PeterS has the best answer. It's also presented in a very clear, didactical style.
Just to save others a few minutes converting it into more production-style code, I've done the following. Basically, it's what you would think you need: One div box inside another, with the outer div box providing the border, the inner providing the title contents with a negative margin shifting it up. A third div then contains the actual content.
This is the CSS:
.outer-border-box {
border: 2px solid black; border-top:3px solid black;}
.label-source-box {
padding: 0 3px; height: 100px; margin-top: -0.8em; }
.box-title {
background: white none repeat scroll 0 0;
padding: 0 2px;
margin-left: 4em;
font-weight:700; font-size:18px;
font-family: 'Avenir Next',Helvetica, sans-serif; }
This is the html:
<div class="outer-border-box">
<div class="label-source-box">
<span class="box-title">Promotional </span>
<div class="box-contents">
<h2>this is the contents</h2>
</div> </div> </div>
It is possible by using the legend tag.
Refer to http://www.w3schools.com/html5/tag_legend.asp

How do I make a dynamic background image opaque in React?

I have blog posts each with a cover image. I want to use these images in my post listing page as an experiment to see if it will liven up the page a little bit.
The images are too bright. I either want the opacity lowered or an overlay must be added.
Changing the opacity will change the opacity of the text. Adding an overlay has positioned itself on top of the anchors rendering them useless.
I am using the Gatsby Casper Starter Kit in the event that you are interested.
PostListing.jsx
...
<PostFormatting className={className} key={title} cover={cover}>
<PostHeader>
<h2 className="post-title">
<Link to={path}>{title}</Link>
</h2>
...
PostFormatting.jsx
...
const style = cover ? { backgroundImage: `url(${cover})` } : {};
return <article className={className} style={style}>{children}</article>;
...
Generated HTML
<article class="post" style="background-image: url("https://picsum.photos/1280/500/?image=800");">
<header class="post-header">
<h2 class="post-title">
Test Post
</h2>
</header>
<section class="post-meta">
<span>
<span class="tag">Mindset</span>
<span class="tag">Productivity</span>
</span>
<time class="post-date" datetime="2017-06-27">27 June 2017</time>
</section>
<section class="post-excerpt"><p>...</p></section>
</article>
CSS
All the styles I have for the post element.
<element.style> {
background-image: url(https://picsum.photos/1280/500/?image=800);
}
.home-template .content .post,
.tag-template .content .post {
background-color: rgba(0, 0, 0, .1);
padding: 30px 50px 50px 50px;
}
.post {
position: relative;
width: 80%;
max-width: 710px;
margin: 4rem auto 0em auto;
padding-bottom: 4rem;
border-bottom: #1a232c 3px solid;
word-wrap: break-word;
}
I know about this method but I don't know how to get the image into the after pseudo element.
div {
width: 200px;
height: 200px;
display: block;
position: relative;
}
div::after {
content: "";
background: url(image.jpg);
opacity: 0.5;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
z-index: -1;
}
Note: Try Radium for pseudo classes
U will have to put the overlay as a sibling of the content, and make it absolute.And also u will have to increase the z-index of the the content, so that it can be interactive.
In your case, all the elements inside the article should be grouped and put inside the content class.
Try this
.parent{
height:300px;
padding:50px;
position:relative;
}
.overlay{
position:absolute;
top:0;right:0;left:0;bottom:0;
background-color:rgba(0,0,0,0.5);
z-index:0;
}
.content{
position:relative;
z-index:1;
font-size:25px;
color:white;
}
<div class="parent" style="background-image:url(http://via.placeholder.com/350x150)">
<div class="overlay"></div>
<div class="content">Test Test</div>
</div>

css <hr class="divider"> responsive

Problem is about , it works great on desktop but on mobile fails....
[http://jsfiddle.net/9vv914uL/][1]
i want to make this divider responsive... because it is working very well on higher resolutions , as you can see....
and bonus is to make words inside tag in different colors...
this is css stylesheet:
.divider {
text-align:center;
font-family: 'montserrat';
}
.divider hr {
margin-left:auto;
margin-right:auto;
width:40%;
}
.left {
float:left;
}
.right {
float:right;
}
this is
<div style="padding-top:10px; padding-bottom:20px;"class="divider">
<hr class="left" style="margin-top:12px;"/>BLUE RED<hr class="right" style="margin-top:12px;"/>
</div>
I dont know what to say about this problem, this is just plain text. I must go back to the stars <3
:)
There are other ways that this can be handled that would work better for what you are trying to do. In my example, I am using both a heading element and an empty div. The text in the heading element can be expanded as much as you would like without needing to worry about available space, and the solution is responsive out of the box.
HTML
<h3 class="divider">
<span>Title</span>
</h3>
<div class="divider">
<span></span>
</div>
CSS
.divider {
border-color: #000;
border-style: solid;
border-width: 0 0 1px;
height: 10px;
line-height: 20px;
text-align:center;
overflow: visable;
}
.divider span {
background-color: #FFF;
display: inline-block;
padding: 0 10px;
min-height: 20px;
min-width: 10%;
}
Fiddle: http://jsfiddle.net/6uux0cbn/1/
I'd probably do it like this rather than messing with floats:
.divider {
text-align: center;
}
.divider:after {
content: "";
height: 1px;
background: #000;
display: block;
position: relative;
top: -8px; /* this value depends on the font size */
}
.divider > span {
background: #fff;
padding: 0 10px;
position: relative;
z-index: 1;
}
<div class="divider"><span>BLUE RED</span></div>
HTML:
<div style="padding-top:10px; padding-bottom:20px;"class="divider">
<hr class="left" style="margin-top:12px;"/>
<div class="title">BLUE RED</div>
</div>
CSS:
.divider {
text-align:center;
font-family: 'montserrat';
position:relative;
height: 68px;
}
.div hr {
width:100%;
position: absolute;
z-index: 888;
}
.title {
position: absolute;
left:50%;
width:100px;
margin-left: -50px;
z-index: 9999;
top:15px;
background: white;
}

text on top of image css

I am trying to place a div with text on top of an image but for some reason it doesn't work. My code is:
<div id="pics">
<div class="inner">
<img src=".." class="pic" height="310" width="310">
<div class="cover">blah blah</div>
</div>
</div>
my CSS is:
#pics{
overflow:hidden;
display:block;
}
.inner a{
position:relative;
margin:3px;
padding:10px;
top:10px;
}
.inner{
position: relative;
display: inline-block;
}
.cover{
position: absolute;
background-color: black;
color: white;
left: 0;
right: 0;
bottom: 0;
top: 0px;
}
I have tried many things but it doesn't seem to work. I might have messed up my cs somewhere
That's because you're targetting an ID and not a class.
In other words, in the CSS you have the definition for an ID (#cover) and the HTML code has a class:
<div class="cover">blah blah</div>
Either change the HTML to have an ID:
<div id="cover">blah blah</div>
or change the CSS to target the class name:
.cover{
position: absolute;
background-color: black;
color: white;
width: 100%;
height: 100%;
border-style: solid 5px;
top: 0px;
}
UPDATE:
You are giving the .cover a width and height of 100%, but absolute positioned elements don't really "understand" that, so I suggest changing it to:
(place the left, bottom and right to the edges, this will fit the div as 100% width and height of the relative parent)
.cover{
position: absolute;
background-color: black;
color: white;
left: 0;
right: 0;
bottom: 0;
border-style: solid 5px;
top: 0px;
}
How about setting the picture as background via the background-image: attribute.
You then could make your div clickable with <div onclick="window.location="url";>
In detail your css would look like this:
.image {
width:310px;
height:310px;
background-image:url('pathtoimage');
}

Transition on hover, except if hovering over a certain element

I have an element that looks something like this:
___
| X|
‾‾‾
So essentially a tiny box with a button to close it.
I have also applied CSS to the element, so that when hovered, it will turn to something like this:
___________________
| X|
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
Simply put, it'll just become wider.
Now. what I want to do is that whenever the user hovers over the close button (X), the box will not change its size.
But when the user hovers on anywhere else on the box, it would behave as suggested.
Is this possible with pure CSS?
EDIT: Sorry that I added this late, but the answers should be based around this example: http://jsfiddle.net/fpY34
Using the markup you have, I have no clue how to do it without fixed widths, and absolute nastiness. But here's me giving my all! http://jsfiddle.net/fpY34/15/
<div id='outer'>
<div id='notOuter'>
<div id='content'>
<div id='img'>
</div>
<div id='label'>
Text example
</div>
<div id='closeButton'>
X
</div>
</div>
</div>
</div>​
and the beauty:
#outer { height: 30px; }
#notOuter {}
#content { float: left; position: relative; }
#closeButton { background: #0f0; position: absolute; top: 0; left: 30px; width: 30px; height: 30px;}
#img { background: #f0f; width: 30px; height: 30px; position: absolute; left: 0; top: 0; }
#label { display: none; position: absolute; left: 0; top: 0; width: 60px; height: 30px; background: #f00; }
#img:hover { width: 60px; z-index: 10; }
#img:hover + #label,
#label:hover { display: block; z-index: 20; }
#img:hover ~ #closeButton,
#label:hover + #closeButton { left: 60px; }
​
would you check this please and tell me if that what you want ?
http://jsfiddle.net/UjPtv/10/
<style>
.divs
{
height: 20px;
width: 100px;
border: 1px solid;
padding: 5px 3px;
}
.divs:hover
{
width: 50px;
padding-left: 150px
}
</style>
<div class="divs"><span>X</span></div>​
You could float them:
<div class="box">
<div>
Content
</div>
<span>X</span>
</div>​​​​​​​
.box {display:inline-block;border:1px solid black}
.box div {width:100px;float:left}
.box div:hover {width:200px}
.box span {float:left}​
Might not work in older browsers though.

Resources