CSS Formula for Precisely Offsetting Text - javascript

On my website, I am aligning a body of text precisely as exemplified in the following snippet.
html, body {
width: 100%;
height: 100%;
font-family: arial;
font-size: 48px;
text-transform: uppercase;
}
body {
margin: 0;
background: skyblue;
}
div {
width: 200px;
height: 100vh;
padding-top: calc(100vh - (1.5rem * 1.35));
box-sizing: border-box;
border: solid red 1px;
}
span {
line-height: 1.35;
display: inline-block;
border: solid black 1px;
}
<div><span>This</span> <span>is</span> <span>a</span><span>body</span><span>of</span> <span>text.</span></div>
However, I was hoping to take it one step further. For instance, I want to be able to place the top of the text as close as possible to, say, 60vh from the top of the page while still displaying half of the last line. Below is an example of what I mean in JS.
Note: Just noticed the second snippet does not display properly unless you open it to edit it. If you transfer it to codepen, it should work properly.
const
div = document.querySelector('div'),
span = document.querySelector('span'),
lineHeight = parseFloat(getComputedStyle(span).lineHeight),
target = innerHeight * 0.6,
remainder = (innerHeight - target) / lineHeight % 1 * lineHeight
div.style.paddingTop = target + remainder - lineHeight / 2 + 'px'
html, body {
width: 100%;
height: 100%;
font-family: arial;
font-size: 48px;
text-transform: uppercase;
}
body {
margin: 0;
background: skyblue;
}
div {
width: 200px;
height: 100vh;
position: absolute;
box-sizing: border-box;
border: solid red 1px;
}
span {
line-height: 1.5;
display: inline-block;
border: solid black 1px;
}
<div><span>This</span> <span>is</span> <span>a</span> <span>body</span> <span>of</span> <span>text.</span></div>
Notably, I know you can obviously find the "remainder" using calc, viewport units, and rem, but the rest is what is confusing because I am not great at math and also lacking sleep.
Hence I was hoping that somebody out there, who is better at math than me, would be able to tell me whether or not a pure CSS solution without preprocessors is possible (i.e. using only calc, viewport units, rem units, etc) before I waste any more time thinking about this. I know there are some nifty CSS formulas for fluid typography, but is something like this possible?
[ edit ] I thought about this some more while laying in bed. I do not believe it is possible without being able to calculate the "remainder." And there does not seem to be any way to calculate the "remainder" with only addition, subtraction, multiplication, and division. Please correct me if I am wrong.

The goal is to have the DIV tag be 100% of the document's height and then the text is offset a little bit within the DIV?
I think just adding another tag within the DIV to offset all the text can work. You said you want 60vh. Line Height should also be used when dealing with text height.
html, body {
width: 100%;
height: 100%;
font-family: arial;
font-size: 48px;
text-transform: uppercase;
}
body {
margin: 0;
background: skyblue;
}
div {
width: 200px;
height: 100vh;
box-sizing: border-box;
border: solid red 1px;
}
p
{ margin: 0;
padding-top: 60vh;
margin-top: -0.8em;
line-height: 1.6em;
}
span {
line-height: 1.35;
display: inline-block;
border: solid black 1px;
}
<html>
<body>
<div><p><span>This</span> <span>is</span> <span>a</span><span>body</span><span>of</span> <span>text.</span></p></div>
</body>
</html>
Or is this not quite it?

Related

Measuring the space that text takes up when it extends past the boundaries of the div

I've been relentlessly trying to resize the text of my buttons to fit within the parent div, and have had no success with fitty and other external plug-ins which work inconsistently or not at all.
I'm attempting to make my own simplified version that simply reduces the font-size of my answer_button_1_text element by 1px until it's smaller than the parent answer_button_1 element.
Using clientWidth returns 281 for answer_button_1 and 253 for answer_button_1_text regardless of if the text in the button extends past the boundaries.
How can I get the actual length of the text?
I've attempted to use the canvas.measureText method, but am unfamiliar with using canvases and when I apply a canvas to the entire HTML in this codepen, none of the elements on my screen are visible. I'm sure I'm making a basic mistake, but if anyone could help me find a way to return the actual space that my answer_button_1_text element takes up, I would really appreciate it.
Here is a codepen:
https://codepen.io/TheNomadicAspie/pen/oNWpZrg
Here is my code:
<button id="button" class="button lower-button">
<div id="button_text">Really long button</div>
</button>
<div id="question_text">Test</div>
body {
background-color: gray;
}
.button {
display: block;
position: relative;
height: 20%;
width: 10%;
background-color: black; /*Button Color*/
color: #f5f5f5;
font-family: open_sans;
font-size: 1.5rem;
font-size: min(6vw, clamp(1rem, 4.5vh, 4rem));
border-radius: 20px;
text-decoration: none;
box-shadow: 0.1em 0.2em black;
transition: 0.2s;
}
.lower-button {
white-space: nowrap;
}
#question_text {
position: absolute;
color: blue;
font-size: 40px;
margin-top: 100px;
}
const question_text = document.getElementById('question_text')
let text_var = button.clientWidth + ' ' + button_text.clientWidth
question_text.innerText = text_var

How do I create this hover button Using HTML, css and javascript

`
/* Button */
.button {
margin: 1em 0em;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
background: #1A718A;
position:relative;
}
.button h3{
position:relative;
top:3.4em;
left:.5em;
color: white;
font-weight: 400!important;
font-size:.9em!important;
z-index: 1;
}
.circle:hover {
position:relative;
top:1em;
left:3em;
}
<div class="button">
<div class="text"><h3>- View <span>Work</span></h3></div>
<div class="circle"></div>
</div> <!--button-->
`How do I create this hover button Using HTML, css and javascript.
The circle moves to the right(no effects) whilst the view turns grey and the work turns white(inverse).
Also a code newbie :)
Default State
Hover state
Thankyou
Recreation
HTML
We want to animate an element and its text "- View Work", so the simplest HTML we can have is:
<p>- View Work</p>
Styling
Default style
We can then style it as much as necessary. To place the line in the middle, we can trick a little by setting line-height to the element's height with a bit of JavaScript:
const p = document.querySelector('p');
p.style = '--height:' + getComputedStyle(p).getPropertyValue('height');
p {
position: relative;
border: 1px solid black;
color: black;
background-color: #f3f3f3;
width: 14rem;
height: 10rem;
font-weight: bold;
font-family: sans-serif;
text-align: center;
line-height: var(--height);
text-transform: uppercase
}
<p>- View Work</p>
With flashlight-effect
Now we want to add the circle, in which the text's color is different.
We could probably use mix-blend-mode in some way, however I don't understand it well enough to make it work with it.
Because of that, we fall back to using pseudo-elements (more specifically, ::after).
The pseudo-element needs to ...:
... have the same text in a different color, and have the texts overlap
... be big enough to fit the revealing circle in all its positions inside
... clip out the rest not inside the revealing circle
The first two bullet points are as simple as styling the pseudo-element and the parent mostly the same way.
To get the text, we can again use JavaScript by setting a custom data-attribute (e.g. data-text) to have the text. The pseudo-element can then display the text with content: attr(data-text).
For the revealing circle, we give the pseudo-element a background-color. Then, we use clip-path to cut out what should be "revealed".
And on hover, we transition between two different positions of the revealing circle.
const p = document.querySelector('p');
p.dataset.text = p.innerText;
p.style = '--height:' + getComputedStyle(p).getPropertyValue('height');
p {
position: relative;
border: 1px solid black;
color: black;
background-color: #f3f3f3;
}
p, p::after {
width: 14rem;
height: 10rem;
font-weight: bold;
font-family: sans-serif;
text-align: center;
line-height: var(--height);
text-transform: uppercase
}
p::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
color: white;
background-color: #1A718A;
clip-path: circle(3rem at 70px 55px);
transition: clip-path 0.15s;;
pointer-events: none;
}
p:hover::after {
clip-path: circle(3rem at 155px 100px);
}
<p>- View Work</p>
End note
This sample-code only works for one-liners, and requires the element to have a fixed size.
The effect can also be achieved by using mostly JavaScript, where one could mock-up such
a pseudo-element with actual HTML-elements, and then overlay said element over the original.

How to remove white space between iframe and div

I'm trying to remove the white space between the iframe and div as I can. Initially there are a huge white space, but after adding in margin: 0px; to my iframe, div, and h1 for my div as well, the white space still remain but become smaller. Anyone know how to remove the strange white space?
iframe {
margin: 0px;
padding: 0px;
}
.footer {
margin: 0px;
padding: 0px;
line-height: 160px;
width: 100%;
color: white;
background-color: black;
}
.footer h1 {
margin: 0px;
padding: 0px;
}
Without seeing any actual code from you I can give my best guess but no promises.
First make sure that the margins on the children are 0. Then set the font size to 0 on the parent, and reset the font size to whatever you want (default = 16px) in the children. This will make the white space have no size.
HTML:
<div id="parent">
<iframe>
<p>Hello World</p>
</div>
CSS:
#parent {
font-size: 0;
}
#parent > * {
margin: 0;
font-size: 16px;
}
But please update the question to include some example code so we can provide a more complete answer.
Use Margin, Padding 0. ex:
margin: 0;
padding: 0;
in CSS. for both div and iframe

Make Dynamic square div for an memory game

What is the easiest way to make responsive dynamic div-s square, like in memory game (image below).
I have problem that user need to scroll down to see whole bottom part of game. How can I calculate (easiest solution) that whole my game is always visible. And also I want that to be dynamic (on image we can see 4x4 game, there should work for any number, 7x7, 10x10 and so on...).
Snippet of my code is: http://jsbin.com/nucovakevu/edit?html,css,output.
Everything in is added dynamically by JavaScript.
It also does not work where I do zoom in.
I am beginner in front-end developing and I mixed here bootstrap and plain css, which is probably not good solution.
Also I used this css trick to make my div as responsive square:
width: 23%;
height: 15vw;
It supposed to be something like:
width: 23%;
height: 23vw;
but I get rectangle in this case, because I obviously do not understand very well how this work.
Just call the function size(); whenever you want to update the grid.
Look at the comments within the code to understand better how this functions.
https://jsfiddle.net/xn5j4rcf/
window.addEventListener('load', function() {
size();
});
function size() {
var container = document.getElementById('container');
container.innerHTML = '';//don't want any extra boxes when you call this function again
var x = Math.floor(window.innerWidth / 50);//width of boxes that can fit; remove any decimal places
var y = Math.floor(window.innerHeight / 50);//height of boxes that can fit; remove any decimal places
for (var i = 0; i < x * y; i++) {//multiply x*y to get total area of boxes that can fit
var box = document.createElement('div');//create a div
box.className = 'box';//assign class
container.appendChild(box);//append
}
}
window.addEventListener('resize', function() {
size();//call the function again when the window is resized
});
.box {
width: 50px;
height: 50px;
padding: 4px;
-o-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
border: 4px solid #fff;//border for margin but use border-box to make sure the width and height are still 50px
background-color: #ddd;
}
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#container {
font-size: 0;//remove annoying margin from display:inline-block;
}
<div id="container">
</div>
This approach can be achieved, but a little odd kinky skills and compatibility is not good:
DEMO: response divs with full screen
Here is the use of a table-cell flexibility and writting-mode to change the direction of the flow
css code blow:
html,body{
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.wrap{
width: 100%;
height: 100%;
-webkit-writing-mode: vertical-lr;
display: table;
table-layout: fixed;
background-color: #000;
}
.row-wrap{
display: table-cell;
}
.row{
width: 100%;
height: 100%;
display: table;
table-layout: fixed;
-webkit-writing-mode: horizontal-tb;
}
.item{
display: table-cell;
height: 100%;
border: 1px solid #ffffff;
box-sizing: border-box;
}

How to build sliding horizontal menu. CSS

I'm trying to build a simple slider that consists of a static 'window' and movable list of items.
where parent container shows only one item and hides all the rest.
I've tried to do something like this but appears this is wrong:
<div id="category-selector">
<div class="categories-list clearfix">
<a class="category">sports</a>
<a class="category">fashion</a>
<a class="category">health</a>
</div>
</div>
#category-selector {
width: 300px; margin: 0 auto; position: relative; z-index: 1;
border: 2px solid #ccc;
-moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; height: 55px;
overflow: hidden;
}
.categories-list {
position: absolute; top: 0; left: 0; display: block;
}
a.category {
display: block; float: left; width: 100%; padding: 10px;
font-size: 30px; font-family: Cambria, 'Segoe UI', sans-serif; line-height: 35px;
text-decoration: none; text-align: center; color: #42a6ce;
}
How do I achieve this functionality?
Try this:
.categories-list {
display: block;
white-space: nowrap;
/*margin-left: -300px;*/
}
a.category {
display: inline-block;
width: 280px;
padding: 10px;
font-size: 30px; font-family: Cambria, 'Segoe UI', sans-serif; line-height: 35px;
text-decoration: none; text-align: center; color: #42a6ce;
}
If you want to have links arranged from left to right, you should set them fixed width. If you set 100% then they will always try to fill container. Setring display to inline-block allows us to avoid wraping line by setting white-space: nowrap; on container.
To scroll it just set margin on container for example margin-left: -300px;
Working sample: http://jsfiddle.net/N9R2E/
Alternatively you may try this:
.categories-list {
display: block;
white-space: nowrap;
margin-left: -300px;
width: 10000px; /* long enough to fit all links */
}
a.category {
display: block;
float:left;
width: 280px;
padding: 10px;
font-size: 30px; font-family: Cambria, 'Segoe UI', sans-serif; line-height: 35px;
text-decoration: none; text-align: center; color: #42a6ce;
}
This uses display:block and float:left like in your attempt, but widths are fixed. To have all links in one line categories-list must be wider then all links together.
Working sample: http://jsfiddle.net/N9R2E/3/
If you don't mind using JS or buttons, this is one way to do it.
$(document).ready(function() {
var slider = $("#categoriese_list");
var leftProperty, newleftProperty;
// the click event handler for the right button
$("#right_button").click(function() {
// get value of current left property
leftProperty = parseInt(slider.css("left"));
// determine new value of left property
if (leftProperty - 100 <= -900) {
newLeftProperty = 0; }
else {
newLeftProperty = leftProperty - 100; }
// use the animate function to change the left property
slider.animate( {left: newLeftProperty}, 1000);
}); // end click
// the click event handler for the left button
$("#left_button").click(function() {
// get value of current right property
leftProperty = parseInt(slider.css("left"));
// determine new value of left property
if (leftProperty < 0) {
newLeftProperty = leftProperty + 100;
}
else {
newLeftProperty = -800;
}
// use the animate function to change the left property
slider.animate( {left: newLeftProperty}, 1000);
}); // end click
}); // end ready
However, I would recommend making your categories list out of a <ul> to keep it more in line.
What you're talking about is essentially a carousel or slider. Rather than trying to code it from scratch I would just use one of the million jQuery plugins out there to build this. I personally like bxslider a lot for things like this because it's responsive and very simple to implement.

Categories

Resources