dynamic font size over image css\html\vue.js - javascript

I need to set text over image. The size of the image\div containing the image is fixed. I got some input above the image that the user insert some text.
the text is injected via props to the "image component" and then i need to display it over the image. the trick is that the text have fixed place to be. at the bottom of the image. the text should not overflow the image borders of course and need to span at the maximum. I mean that if the text is "short" (low amount of characters) the font size should increase and vice versa using java script function.
the problem with my function its not "flexible" enough, the ratio between the font size and the text length is too "hard coded" with fixed values that changed the desired result.
<template>
<div class="img-container z-depth-4">
<img class="img-to-edit" :src="this.urlChanges">
<p class="text-append">{{textToAppend}}</p>
</div>
</template>
<script>
export default{
props: ['urlChanges', 'textToAppend'],
data () {
return {
limit: 25,
font: 35,
offset: 0
}
},
mounted() {
let self = this
$( document ).ready(function() {
//that's an input from the parent component
$('#textarea1').on('keypress', function(e) {
let that = $(this);
let textLength = that.val().length;
if(textLength+self.offset > self.limit) {
$('.text-append').css('font-size', self.font + 'px');
self.font -= 5;
self.offset -=5;
}
});
});
},
}
</script>
and the style
<style scoped>
.img-container {
width: 800px;
height: 430px;
overflow: hidden;
background: #ccc;
margin: 10px;
line-height: 150px;
position: relative;
text-align: center;
color: white;
}
.img-to-edit {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
flex-shrink: 0;
min-width: 100%;
min-height: 100%;
}
.text-append{
position: absolute;
top: 80%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
</style>
im not sure about my css definition.

You can use the vh or vw for font size the ratio will remain the same for almost very resolution
font-size: 5vh
or
font-size: 10vw

Related

How to keep size proportions for div's child elements

TL;DR: How to keep the div children proportional to the div itself?
I have a div, containing various elements like text, images, icons etc. It keeps 16:9 aspect ratio and fills as much viewport it can, while resizing the browser window, the div (with background different from the body background) changes size well, though the contents are staying the same size which is bad because I'm trying to make a presentation website which needs to look the same at various resolutions. How do I make the child elements align and resize properly inside the div?
I tried using viewport units though it didn't turn out really well.
My Code:
I tried using % units to set font size and then use em to scale other things but it didn't work. I also tried using only % units to set all properties but it did not work either
body {
background: black;
user-select: none;
margin: 0;
height: 100vh;
}
.container2 {
overflow: auto;
box-sizing: border-box;
resize: both;
overflow: auto;
max-width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
.presentation-place {
user-select: none;
background: white;
top: 50%;
transform: translate(0, -50%);
position: absolute;
align-items: center;
aspect-ratio: 16 / 9;
}
#media screen and (max-aspect-ratio: 16 / 9) {
.presentation-place {
width: 100vw;
}
}
#media screen and (min-aspect-ratio: 16 / 9) {
.presentation-place {
height: 100vh;
}
}
.slide {
font-size: 100%;
position: absolute;
top: 0;
bottom: 0;
margin: 0 auto;
width: 100%;
height: 100%;
overflow: hidden;
background: red;
background-position: center center;
}
.title1 {
margin-left: 1em;
font-size: 6em;
position: absolute;
margin-top: 2em;
}
<html>
<body>
<div class="container">
<div class="presentation-place">
<div class="slide s1">
<h1 class="title1">test</h1>
</div>
</div>
</div>
</body>
</html>
Make sure to avoid specific units like cm, px etc because those are fixed units no matter the scale of the site itself or the monitor, the use of Units like % since vh/vw didnt work. % scales relative to the size of the monitor or website, so this should help. Alternativly you could use aspect-ratio because it scales relative to the size of the parent element

MouseEvent.clientX and MouseEvent.clientY Unexpected Results With CSS Scale Transform

$('body').on('mousemove', function (ev) {
$('span').text(`x: ${ev.clientX}, y: ${ev.clientY}`)
})
body {
padding: 0;
margin: 0;
}
div {
display: inline-block;
width: 100px;
height: 100px;
background: #333;
transform: scale(2, 2);
}
span {
position: absolute;
left: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="my-div"></div>
<span id="my-span"></span>
I was just wondering why the scaled div returns x and y MouseEvent coordinates in the range from 0 to 150 instead of from 0 to 200? The scale property is set to 2, so I thought it would be the second range instead of the first. Could someone explain? Here's a link to the js fiddle page.
I noticed a lot of similar questions on Stackoverflow, so this might be a duplicate. However, I couldn't find anything that specifically asked this question about pixels, coordinates, and the scale transformation in CSS. I may have missed something, though...
Thanks!
because transform-origin is center by default so half the div is outside the screen from the top/left.
Either update the transform-origin:
$('body').on('mousemove', function (ev) {
$('span').text(`x: ${ev.clientX}, y: ${ev.clientY}`)
})
body {
padding: 0;
margin: 0;
}
div {
display: inline-block;
width: 100px;
height: 100px;
background: #333;
transform: scale(2, 2);
transform-origin:0 0;
}
span {
position: absolute;
left: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="my-div"></div>
<span id="my-span"></span>
Or add some margin:
$('body').on('mousemove', function (ev) {
$('span').text(`x: ${ev.clientX}, y: ${ev.clientY}`)
})
body {
padding: 0;
margin: 0;
}
div {
display: inline-block;
width: 100px;
height: 100px;
background: #333;
transform: scale(2, 2);
margin:50px;
}
span {
position: absolute;
left: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="my-div"></div>
<span id="my-span"></span>
The div is scaled relative to its center, so part of it ends up being off screen. (One way to notice this: add a border to the div and see that it doesn't go all the way around.)
Try using transform-origin: top left; on the div - I think that will do what you expect.

What's the cleanest way to set dynamic style elements?

I want my website to scale a <div> based on the resolution of the screen on which it's viewed.
I'm currently using this code in a function which runs as the body loads (gameCanvas is the <div> I'm talking about):
var WIDTH = window.screen.availWidth/2,
HEIGHT = window.screen.availHeight/2;
var c = document.getElementById("gameCanvas");
c.setAttribute("style","width:"+WIDTH+"px;height:"+HEIGHT+"px");
c.style.width=WIDTH;
c.style.height=HEIGHT;
It does the job, but it also overwrites my CSS stylesheet and it forces me to put all the styling information in the javascript instead of separating the style from the logic.
Is there a way to dynamically determinate those parameters in the CSS, or to just change those two parameters without overriding the whole stylesheet? I've already tried
c.setAttribute("height", HEIGHT);
c.setAttribute("width", WIDTH);
but it does nothing since they're not attribute by themselves.
EDIT:
My stylesheet (for now it's embedded in the index.html but it's already in the CSS form):
<style>
body {
background-color: black;
}
#gameCanvas {
background-color: black;
width: 800px;
height: 600px;
margin: auto;
align: center;
}
#scoreboard {
text-align: center;
font-family: Segoe UI, Helvetica, Ubuntu, sans-serif;
color: white;
}
#scores {
font-size:600%;
padding:0;
margin:0;
color: white;
}
#title {
background-color: white;
color: black;
}
</style>
Using JavaScript is one option. As an alternative I'll offer 2 CSS-only solutions. There are 2 solutions that come to mind first.
Option #1
The first is pretty standard - set the height and width to 100%. The caveat here is every parent parent container needs it's height and width set to 100% too. Like this:
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
main {
width: 100%;
height: 100%;
}
#gameCanvas {
background-color: red;
width: 100%;
height: 100%;
}
<main>
<div id="gameCanvas"></div>
</main>
Option #2
The more elegant solution would be to use vw and vh units. vw and vh units are equal to 1% viewport width and height respectively. So 1vw would be 1% of the viewport width. To make an element full-screen you can set the width and height to 100vw and 100vh respectively. Like this:
html,
body {
margin: 0;
padding: 0;
}
#gameCanvas {
background-color: red;
width: 100vw;
height: 100vh;
}
<main><div id="gameCanvas"></div></main>

Header banner with css only?

I'm a beginner in css and i'm trying to create a hero banner with css only and make it responsive, i'm quite confused with positioning of the texts on top of the image, if i zoom the page or resize it down the texts don't respond.
<header class="main-header">
<img src="imgs/header.jpg"/>
<div class="title">
<h1>This is a title</h1>
<p>some texts here</p>
</div>
</header>
css:
.main-header img {
max-width: 100%;
margin: 0 auto;
position: relative;
}
.title {
position: relative;
top: -450px;
left: 10%;
text-align: center;
display: inline-block;
color: white;
margin: 0 auto;
width: 80%;
text-transform: uppercase;
}
.title h1 {
font-size: 2.7rem;
font-weight: 700;
margin: 0 auto;
width: 80%;
margin-bottom: 1.5%;
}
.title p {
font-size: .60rem;
width: 33%;
margin: 0 auto;
line-height: 1.8;
}
Is it even possible to create a hero banner with css only? cuz i can't see any tutorial for that..
Example: Responsive Hero Banner with Image and Text
Here's a very minimal example of a full width, responsive hero banner with image and text, using only css.
The HTML:
<div class="hero-wrapper">
<header class="hero">
<div class="hero-sizing"></div>
<div class="hero-content">
<h1>Hero Title</h1>
<p>Hero paragraph text.</p>
</div>
</header>
</div>
The only unusual element there is the "hero-sizing" div. It's there to ensure the banners image maintains its aspect ratio at different window size (more on "hero-sizing" later).
On to the css. First is the outermost hero-wrapper class:
.hero-wrapper {
clear: both;
position: relative;
width: 100%;
text-align: center;
font: 18px helvetica, sans-serif;
color: white;
}
Nothing too confusing here, mostly just setting up some formatting. Note that width: 100% makes the banner extend the full width of the window.
Next is the hero class, which specifies the banner image and how it is displayed:
.hero {
background-image: url(http://lorempixel.com/image_output/people-q-c-1200-400-6.jpg);
background-repeat: no-repeat;
background-attachment: scroll;
background-position: center;
background-size: 100% auto;
}
This hero class specifies the image, centers it, and sets it to the full width of its container.
Next comes the hero-sizing class that's responsible for maintaining the banner's aspect ratio when it's resized:
.hero-sizing {
padding-top: 33%;
}
To maintain the image's aspect ratio, padding-top must match the image's height:width ratio. Since the image in this example is 1200 wide by 400 high, we've set padding-top to 33%. hero-sizing serves an important function -- it stretches and shrinks the height of div containing the background image, so the div's aspect ratio and the image's aspect ratio always match.
With just the above css, we now have a full-width, responsive banner image that maintains its aspect ratio, but we still would like to be able to add some text to the banner and have it look decent. That's what the hero-content class and 'hero-content:before pseudo-class are for:
.hero-content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.hero-content:before {
content: ' ';
display: block;
height: 40%;
}
Our content ought to be placed at roughly the same spot over the image, regardless of the image's size. To accomplish this, we're employing a little trick with :before pseudo-class to push our content down the page by 40% of the banner's current height. This positioning 'trick' means our content's position is responsive, as it will stay at the same place over the image.
The final css just sets some formatting preferences:
.hero-content h1,
.hero-content p {
margin-top: 0px;
margin-bottom: 6px;
}
And we're done.
Granted, this is just a bare minimum example which could be improved for small screens with #media queries (like reducing the font size), but this example shows how to implement two very useful capabilities:
full width, responsive hero banner images that maintain aspect ratio
consistent content positioning over the image
.hero-wrapper {
clear: both;
position: relative;
width: 100%;
text-align: center;
font: 18px helvetica, sans-serif;
color: white;
}
.hero {
background-image: url(https://picsum.photos/id/1062/1200/400);
background-repeat: no-repeat;
background-attachment: scroll;
background-position: center;
background-size: 100% auto;
}
.hero-sizing {
padding-top: 33%;
}
.hero-content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.hero-content:before {
content: ' ';
display: block;
height: 40%;
}
.hero-content h1,
.hero-content p {
margin-top: 0px;
margin-bottom: 6px;
}
body {
margin: 0;
background-color: #d0d0d0;
}
<div class="hero-wrapper">
<header class="hero">
<div class="hero-sizing"></div>
<div class="hero-content">
<h1>Hero Title</h1>
<p>Hero paragraph text.</p>
</div>
</header>
</div>

Best way to center div in responsive div

I've been trying for several hours to both vertically and horizontally center a div with no specific width or height in a parent div that has a max-width and max-height but will be responsive. I've looked at both CSS and JS/jQuery options with nothing working properly.
As you can see, it's a thumbnail preview for a video. When in a normal state, it just shows the thumbnail with a play icon above it. In a hover state, it changes the play button to an orange one, displays the title, and has a black transparent overlay above the thumbnail.
Now, this would be easy to do with CSS if the site wasn't responsive. But, as the browser width decreases, the thumbnail sizes decrease.
Here's the HTML I'm using:
<article class="movie"><a href="#">
<div class="movie-overlay">
<div class="movie-play"></div>
<h2 class="movie-title">Title Goes Here</h2>
</div> <!-- end .movie-overlay -->
<div class="movie-thumb"><img src="thumbs/thumb.jpg"/></div>
</a></article> <!-- end #post- -->
And here's my CSS:
.movie-archive .movie {
width: 50%;
height: auto;
max-width: 480px;
position: relative;
overflow: hidden;
float: left;
}
.movie-archive .movie .movie-overlay {
width: 100%;
height: 100%;
position: absolute;
text-align: center;
}
.movie-archive .movie:hover .movie-overlay {background: rgba(0, 0, 0, 0.6);}
.movie-archive .movie .movie-play {
background: url("images/play-icon#2x.png") no-repeat center 0;
background-size: 94px 190px;
width: 100%;
height: 95px;
}
.movie-archive .movie:hover .movie-play {background-position-y: -95px;}
.movie-archive .movie .movie-title {
font-size: 17px;
letter-spacing: -0.01em;
font-weight: 700;
color: #ffffff;
display: none;
padding: 10px 50px 0;
}
.movie-archive #latest-top.movie:hover .movie-title, .movie:hover .movie-title {display: block;}
.movie-archive .movie .movie-thumb img {
width: 100%;
height: 100%;
display: block;
}
I've tried various things from adding another div and using the display: table trick to adding padding as a percentage, and using JS. Nothing seems to work. Does anyone have any suggestions? I would really appreciate it. Thanks!
Not that it really matters, but I am using WordPress for this site.
The container and the elemented you want centered should have properties like this:
.movie-archive .movie {
width: 50%;
height: auto;
max-width: 480px;
position: relative;
overflow: hidden;
float: left;
}
.movie-archive .movie .movie-overlay {
width: 100%;
height: 100%;
left: 50%;
margin-left: -50%; //half of width
top: 50%;
margin-top: -50%; //half of height
position: absolute;
text-align: center; //only if you want the text to be centered
}
Source: http://designshack.net/articles/css/how-to-center-anything-with-css/
try this:
$(document).ready(function() {w = $(window).width();
h = $(window).height();
jQuery.each($('.centerony'), function(i, val) {
lung = $(val).css('height');
a = (h * 0.5) - ((parseInt(lung)) * 0.5);
$(val).css('position', 'absolute');
$(val).css('top', a + 'px')
});
jQuery.each($('.centeronx'), function(i, val) {
larg = $(val).css('width');
a = (w * 0.5) - ((parseInt(larg)) * 0.5);
$(val).css('position', 'absolute');
$(val).css('left', a + 'px')
});
$(window).resize(function() {
k = $(window).width();
z = $(window).height();
jQuery.each($('.centeronx'), function(i, val) {
larg = $(val).css('width');
a = (k * 0.5) - ((parseInt(larg)) * 0.5);
$(val).css('left', a + 'px')
})
jQuery.each($('.centerony'), function(i, val) {
lung = $(val).css('height');
a = (z * 0.5) - ((parseInt(lung)) * 0.5);
$(val).css('position', 'absolute');
$(val).css('top', a + 'px')
});
});
});
Add to the element you want to center class 'centerony' and class 'centeronx', and set parent's div (the one which has max-width and max-height with position:relative. It should work.
<div id="outdiv" class="outside" style="position:relative">
<div class="in_div centerony centeronx">I am centered!</div>
</div>
You have to use include jQuery to use it. :)
PAY ATTENTION -------
the code i wrote works according to window's size, and not parent's div size.
If you want to adapt to your case, change the values of vars w,h,k,z, making their value in relation with parent's div size instead of window size. for example w = $('#outdiv').width() instead of w = $(window).width();

Categories