Align figcaption to bottom edge of scaled image - css

As seen in example, position:relative; to parent (figure) and position:absolute; to child (figcaption) due to transform:scale(1.3); does not achieve desired result (figcaption to inside of bottom edge of the img). Any ideas how to tackle the issue?
.wrapper {
display: grid;
justify-content: center;
}
article {
max-width: 20rem;
margin: 3rem;
background-color: lightblue;
}
* {
padding: 0;
margin: 0;
}
img {
max-width: 100%;
display: block;
}
figure {
position: relative;
}
figure img {
object-fit: cover;
height: 400px;
width: 100%;
transform: scale(1.3);
}
figcaption {
position: absolute;
bottom: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.7);
color: white;
}
h1 {
margin-top: 10rem;
}
<div class="wrapper">
<article>
<header>
<figure>
<img src="https://www.funcage.com/blog/wp-content/uploads/2016/07/Random-Photo-Dump-24.jpg" alt="Your Image">
<figcaption>Your caption text goes here.</figcaption>
</figure>
<h1>Main heading h1</h1>
</header>
<h2>Heading h2</h2>
<p>text text text</p>
</article>
</div>

Related

Two scrolling blocks in flex container

I need to build a card with two scrolling areas. Initial idea was to use flexbox so I came up with this:
.card {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 50%;
min-width: 100px;
min-height: 0;
max-width: 80%;
max-height: 80%;
border: solid 1px black;
padding: 10px;
}
.photo {
background-color: silver;
margin-bottom: 10px;
aspect-ratio: 3;
}
.body {
display: flex;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 10px;
}
.title {
background-color: silver;
margin-bottom: 10px;
}
.text {
flex: 1;
background-color: cyan;
min-height: 0;
overflow: auto;
}
.photos {
width: 100px;
min-height: 0;
overflow: auto;
}
.photos * ~ * {
margin-top: 10px;
}
.thumbnail {
background-color: lightgreen;
aspect-ratio: 3;
}
<div class="card">
<div class="photo">Photo</div>
<div class="body">
<div class="content">
<div class="title">Title</div>
<div class="text" contenteditable>
Full text<br>
Can be multiline and with vertical scroll
</div>
</div>
<div class="photos">
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
</div>
</div>
</div>
link to fiddle: https://jsfiddle.net/SkyLight/jxobz8qn/
The card has maximum width and height and Full text section (cyan one) can have pretty long content so that it should have scroll when needed. Thumbnails section can also have big amount of items so will also need to have scroll.
I know that overflow needs block to have height set in order to work but I can't figure out how to set it properly because the content should be limited mainly by Card's max size.
So can it be achieved with flexbox only or I'll need some other stuff? Would like to achieve the result with pure css.
Make the card element a flexbox container then use flex:1 on the body:
.card {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 50%;
min-width: 100px;
min-height: 0;
max-width: 80%;
max-height: 80%;
border: solid 1px black;
padding: 10px;
/* added */
display: flex;
flex-direction: column;
/**/
}
.photo {
background-color: silver;
margin-bottom: 10px;
aspect-ratio: 3;
}
.body {
display: flex;
flex:1; /* added */
min-height:0; /* added to make sure the content will shrink */
}
.content {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 10px;
}
.title {
background-color: silver;
margin-bottom: 10px;
}
.text {
flex: 1;
background-color: cyan;
min-height: 0;
overflow: auto;
}
.photos {
width: 100px;
min-height: 0;
overflow: auto;
}
.photos * ~ * {
margin-top: 10px;
}
.thumbnail {
background-color: lightgreen;
aspect-ratio: 3;
}
<div class="card">
<div class="photo">Photo</div>
<div class="body">
<div class="content">
<div class="title">Title</div>
<div class="text" contenteditable>
Full text<br>
Can be multiline and with vertical scroll
</div>
</div>
<div class="photos">
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
</div>
</div>
</div>

Positioning of a Absolute Element in relation to a responsive image

I’m trying to create a responsive design where a sections section is always flush to the bottom edge of an image.
The section is a grid divided into three grid-areas:
“section1 section3”
“section2 section3"
I want the bottom of section1 to always align with the bottom of a responsive 3/2 image.
The closest I’ve been able to get to achieve what I’m looking for is by applying padding-bottom: min(50px, 3.5vw);
img{
object-fit: contain;
/* aspect-ratio: 3/2;*/
width: 100%;
padding-bottom: min(50px, 3.5vw);
}
div section{
position: absolute;
bottom: 0;
}
What I’m looking for is something like calc(heightOfTheContainer + XXpx)
I know I can do this in JavaScript document.getElementById("myImg").offsetHeight + XXpx;
Can I achieve what I want with just CSS using calc() minmax() or ??.
main{
height:100%;
width: 100%;
padding: 3.5vh;
}
div{
position: relative;
max-width: 800px;
margin: 0 auto;
}
img{
object-fit: contain;
/* aspect-ratio: 3/2;*/
width: 100%;
padding-bottom: min(50px, 3.5vw);
}
div section{
position: absolute;
display: grid;
grid-template-columns: 30% 70%;
grid-template-rows: 50% 50%;
grid-template-areas:
"section1 section3"
"section2 section3";
bottom: 0;
height:8vw;
width:100%;
}
.section1, .section2, .section3{
width:100%;
height:100%;
font-size: 20px;
font-weight:bold;
color:black;
}
.section1{
grid-area: section1;
background-color: red;
}
.section2{
grid-area: section2;
background-color: blue;
}
.section3{
grid-area: section3;
background-color: green;
opacity: .5;
}
<main>
<div>
<img src="../../images/portfolio/mainbnw.jpg" />
<section>
<div class="section1">
section 1
</div>
<div class="section2">
section 2
</div>
<div class="section3">
section 3
</div>
</section>
</div>
</main>
If you remove any bottom padding from the main and position the grid element relative rather than absolute it will end up immediately below the image.
So then translate it upwards by 50% of its height and the bottom of the first cell will always be aligned with the bottom of the image (whatever height you give the cell).
main {
height: 100%;
width: 100%;
padding: 3.5vh;
}
div {
position: relative;
max-width: 800px;
margin: 0 auto;
}
img {
object-fit: contain;
/* aspect-ratio: 3/2;*/
width: 100%;
}
div section {
position: relative;
transform: translateY(-50%);
display: grid;
grid-template-columns: 30% 70%;
grid-template-rows: 50% 50%;
grid-template-areas: "section1 section3" "section2 section3";
bottom: 0;
height: 8vw;
width: 100%;
}
.section1,
.section2,
.section3 {
width: 100%;
height: 100%;
font-size: 20px;
font-weight: bold;
color: black;
}
.section1 {
grid-area: section1;
background-color: red;
}
.section2 {
grid-area: section2;
background-color: blue;
}
.section3 {
grid-area: section3;
background-color: green;
opacity: .5;
}
<main>
<div>
<img src="https://picsum.photos/id/1015/600/400" />
<section>
<div class="section1">
section 1
</div>
<div class="section2">
section 2
</div>
<div class="section3">
section 3
</div>
</section>
</div>
</main>
If you use grid, you can a set few elements inside the same cell without the need of absolute.
here is an example made of 3 rows to show the idea:
img {
object-fit: contain;
aspect-ratio: 3/2;
}
.section1,
.section2,
.section3 {
font-size: 20px;
font-weight: bold;
color: black;
}
section {
display: grid;
grid-template-columns: 30% 70%;
grid-template-rows: 8fr auto auto;
grid-template-areas: "img img" "sec1 sec3" " sec2 sec3"
}
img {
grid-column: 1/3;
grid-row: 1/3;
width: 100%;
}
.section1 {
grid-area: sec1;
background-color: red;
}
.section2 {
grid-area: sec2;
background-color: blue;
}
.section3 {
grid-area: sec3;
background-color: rgba(0,128,0,0.5);
}
<section>
<img src="https://picsum.photos/id/1015/300/200" />
<div class="section1">
section 1
</div>
<div class="section2">
section 2
</div>
<div class="section3">
section 3
</div>
</section>

How to extend the pseudo element placed absolutely until the page content gets the best?

I wrote such a code. I write this code so that .vertical_catch p: after is from the position where the element is absolutely placed to the bottom where the page content exists
body {
margin: 0;
}
.hero {
height: 100vh;
position: relative;
margin: 0 auto;
overflow: hidden;
background: #000;
}
.vertical_catch {
position: absolute;
top: 58%;
left: 4%;
height: 100%;
}
.vertical_catch p {
font-size: 1.8vw;
color: #ffffff;
writing-mode: vertical-rl;
height: 100%;
}
.vertical_catch p:after {
z-index: 50;
margin: 1em 0;
content: "";
position: absolute;
left: 50%;
height: 100%; /* I want to get 100% height of page content */
display: inline-block;
width: 1.7px;
transform: translateX(-50%);
background-color: #fff;
}
.box {
width: 100%;
}
.minibox {
height: 100vh;
padding: 150px;
background-color: #333;
}
h1 {
margin: 40px 0px;
color: #fff;
text-align: center;
}
.content {
margin: 0 auto;
width: 50%;
color: #fff;
overflow-wrap: break-word;
}
<body>
<div class="hero"></div>
<div class="vertical_catch">
<p>TEXTTEXTTEXTTEXT</p>
</div>
<div class="box">
<section class="minibox">
<h1>heading1</h1>
<section class="content">
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
</p>
</section>
</section>
</div>
<div class="box">
<section class="minibox">
<h1>heading2</h1>
<section class="content">
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
</p>
</section>
</section>
</div>
</body>
However, height: 100% only worked up to 100vh, and could not extend the border to the bottom of the content.
According to the developer tool verification,in html and body, the height includes all page content, but the element of absolute arrangement could not obtain the height. height: 100% only worked up to 100vh.
How can I extend the border?
You are setting 100% height for ::after element; it will take up the full height of the p, its main element. Consider editing as below:
body {
margin: 0;
height: auto;
position: relative;
}
.hero {
height: 100vh;
position: relative;
margin: 0 auto;
overflow: hidden;
background: #000;
}
.vertical_catch {
position: absolute;
top: 10%;
left: 4%;
height: 90%;
}
.vertical_catch p {
font-size: 1.8vw;
color: #ffffff;
writing-mode: vertical-rl;
height: 100%;
}
.vertical_catch p:after {
z-index: 50;
margin: 1em 0;
content: "";
position: absolute;
left: 50%;
height: 80%;
display: inline-block;
width: 1.7px;
transform: translateX(-50%);
background-color: #fff;
}
.box {
width: 100%;
}
.minibox {
height: 100vh;
box-sizing: border-box;
padding: 150px;
background-color: #333;
}
h1 {
margin: 40px 0px;
color: #fff;
text-align: center;
}
.content {
margin: 0 auto;
width: 50%;
color: #fff;
overflow-wrap: break-word;
}
<body>
<div class="hero"></div>
<div class="vertical_catch">
<p>TEXTTEXTTEXTTEXT</p>
</div>
<div class="box">
<section class="minibox">
<h1>heading1</h1>
<section class="content">
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
</p>
</section>
</section>
</div>
<div class="box">
<section class="minibox">
<h1>heading2</h1>
<section class="content">
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
</p>
</section>
</section>
</div>
</body>
body {
margin: 0;
height: auto;
position: relative;
}
.hero {
height: 100vh;
position: relative;
margin: 0 auto;
overflow: hidden;
background: #000;
}
.vertical_catch {
position: absolute;
top: 10%;
left: 4%;
height: 90%;
}
.vertical_catch p {
font-size: 1.8vw;
color: #ffffff;
writing-mode: vertical-rl;
height: 100%;
}
.vertical_catch p:after {
z-index: 50;
margin: 1em 0;
content: "";
position: absolute;
left: 50%;
height: calc(100% - 388px);
display: inline-block;
width: 1.7px;
transform: translateX(-50%);
background-color: #fff;
}
.box {
width: 100%;
}
.minibox {
height: 100vh;
box-sizing: border-box;
padding: 150px;
background-color: #333;
}
h1 {
margin: 40px 0px;
color: #fff;
text-align: center;
}
.content {
margin: 0 auto;
width: 50%;
color: #fff;
overflow-wrap: break-word;
}
<body>
<div class="hero"></div>
<div class="vertical_catch">
<p>TEXTTEXTTEXTTEXT</p>
</div>
<div class="box">
<section class="minibox">
<h1>heading1</h1>
<section class="content">
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
</p>
</section>
</section>
</div>
<div class="box">
<section class="minibox">
<h1>heading2</h1>
<section class="content">
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext
</p>
</section>
</section>
</div>
</body>

Accurate text position over an image in flexbox [duplicate]

How can I centre align text over an <img> preferably using FlexBox?
body {
margin: 0px;
}
.height-100vh {
height: 100vh;
}
.center-aligned {
display: box;
display: flex;
box-align: center;
align-items: center;
box-pack: center;
justify-content: center;
}
.background-image {
position: relative;
}
.text {
position: absolute;
}
<section class="height-100vh center-aligned">
<img class="background-image" src="http://vignette2.wikia.nocookie.net/uncyclopedia/images/f/f8/Stand-out-in-the-crowd-300x300.jpg" />
<div class="text">SOME TEXT</div>
</section>
To center text over an image you don't need flexbox. Just use CSS positioning properties.
.height-100vh {
height: 100vh;
position: relative; /* establish nearest positioned ancestor for
absolute positioning */
}
.text {
position: absolute;
left: 50%; /* horizontal alignment */
top: 50%; /* vertical alignment */
transform: translate(-50%, -50%); /* precise centering; see link below */
}
body {
margin: 0px;
}
.height-100vh {
height: 100vh;
display: flex; /* establish flex container */
flex-direction: column; /* stack flex items vertically */
position: relative; /* establish nearest positioned ancenstor for absolute positioning */
}
.text {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: white;
font-weight: bold;
}
.center-aligned {
display: flex;
align-items: center;
justify-content: center;
}
<section class="height-100vh center-aligned">
<img class="background-image" src="http://vignette2.wikia.nocookie.net/uncyclopedia/images/f/f8/Stand-out-in-the-crowd-300x300.jpg/revision/latest?cb=20090904155448" />
<div class="text">SOME TEXT</div>
</section>
Revised Codepen
The code above centers the text both vertically and horizontally over the image:
For a more detailed explanation of the centering method see:
Element will not stay centered, especially when re-sizing screen
You can just wrap an image with relatively positioned inline-block <div> and give the text this way:
* {margin: 0; padding: 0; list-style: none;}
.img-holder {position: relative; display: inline-block;}
.img-holder img {display: block;}
.img-holder p {position: absolute; top: 50%; left: 0; right: 0; transform: translate(0, -50%); text-align: center; color: #fff; text-shadow: 0 0 15px;}
<div class="img-holder">
<img src="http://bit.ly/1YrRsis" alt="">
<p>Text Aligned Centrally Vertical & Horizontal.</p>
</div>
Now the <div> is an inline kinda element that you can style.
Preview:
I've added another wrapper div surrounding the img and text as well as using flex to position the text. See this codepen
HTML:
<section class="height-100vh center-aligned">
<div class="wrapper">
<img class="background-image" src="http://bit.ly/1YrRsis" />
<div class="text">SOME TEXT</div>
</div>
</section>
CSS:
#import "bourbon";
body {
margin: 0px;
}
.height-100vh {
height: 100vh;
}
.center-aligned {
#include display(flex);
#include align-items(center);
#include justify-content(center);
}
.wrapper {
position: relative;
}
.text {
justify-content: center;
align-items: center;
display: flex;
color: #fff;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
You also can center align text onto an image using display: inline-block; to the wrapper element.
.height-100vh {
display: inline-block;
position: relative;
}
.text {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: #fff;
}
<section class="height-100vh center-aligned">
<img class="background-image" src="http://vignette2.wikia.nocookie.net/uncyclopedia/images/f/f8/Stand-out-in-the-crowd-300x300.jpg" />
<div class="text">SOME TEXT</div>
</section>
I added 2 more divs
<div class="text box" >
<img src="images/woodenbridge.jpg" alt="Wooden Bridge" />
<div class="slide-box flex">
<div class="flex-item"></div>
</div>
</div>
and then styled as follows :
.flex-item {
display: inline;
align-self: center;
}
Responsive centered text content over image
.height-100vh {
height: 100vh;
background: lightgrey;
}
.center-aligned {
display: flex;
align-items: center;
justify-content: center;
}
.background-image {
opacity: .3;
width: 100%;
object-fit:cover;
height: 100%;
}
.text {
position: absolute;
color: white;
font-family: 'Gill Sans', 'Gill Sans MT';
background: darkcyan;
padding: 20px;
}
<section class="height-100vh center-aligned">
<img class="background-image" src="https://www.humanesociety.org/sites/default/files/styles/768x326/public/2018/08/kitten-440379.jpg?h=f6a7b1af&itok=vU0J0uZR" />
<div class="text">I'm in center</div>
</section>

Overlay text with color over an image

Right now I am overlaying color over an image inside a div.
CSS:
.thumb {width:300px;margin:auto;background:rgba(231, 207, 0, 0.5);}
.thumb img { display: block; }
.thumb:hover img { opacity: 0.5; }
HTML:
<div class="thumb">
<a href="url">
<img src="source"/>
</a>
</div>
How could I also overlay text on hover?
I found quite a few tutorials on this but am completely lost how to modify the current code to have text overlay as well.
You have to position text div abosolute and display it on hover.
.thumb {
width: 300px;
margin: auto;
background: rgba(231, 207, 0, 0.5);
position: relative;
}
.thumb img {
display: block;
width: 300px;
}
.thumb:hover img {
opacity: 0.5;
}
.overlay_text {
display: none;
position: absolute;
bottom: 0;
text-align: center;
width: 100%;
}
.thumb:hover .overlay_text {
display: block;
}
<div class="thumb">
<a href="url">
<img src="https://www.gravatar.com/avatar/4ee102e4ae1b9ab69077f7c471365f69?s=128&d=identicon&r=PG&f=1" />
</a>
<div class="overlay_text">test</div>
</div>
Go-through the CSS and HTML i did. Its working.
Here is Demo:
.thumb {
background: rgba(231, 207, 0, 0.5);
display: table;
margin: auto;
width: 300px;
}
.thumb img {
display: block;
margin: 0;
position: absolute;
top: 7px;
}
.thumb:hover img { opacity: 0.5; }
.caption {
display: table-cell;
height: 300px;
margin: 0;
opacity: 0;
text-align: center;
vertical-align: middle;
width: 300px;
}
.thumb:hover .caption{ opacity:1;}
<div class="thumb">
<a href="url">
<p class="caption"> CAPTION</p>
<img src="http://placehold.it/300"/>
</a>
</div>

Resources