Customizing where a div wraps to - javascript

Is it possible to have two divs wrap as if their one line?
<div class="multiLine">
<div class="topLine"></div>
<div class="bottomLine"><div>
</div>
so if top line was all "A"'s and the bottom line was all "B"'s we would see it wrap like
AAAAAAAAA
BBBBBBBBB
AAAAAAAAA
BBBBBBBBB
I'm trying to accomplish this with JavaScript, jQuery, and css3.

This could actually be done just by using CSS and playing with the div positions and the line heights.
For example:
.multiLine {
position:relative;
width:100px;
eight:100px;
}
.topLine {
position:absolute;
word-break:break-all;
line-height:40px;
top:20px;
}
.bottomLine {
position:absolute;
word-break:break-all;
line-height:40px;
}
This would work although it may not be an optimal solution for what you want. It depends on the context and what you want to achieve with this effect.
EDIT: You can see an example of how it would look like here: http://jsfiddle.net/78f94/

You cannot do it with html/css alone. But with Javascript you can find viewport width, truncate the string and add it as content to new inner divs. This could get very complicated when you resize as width changes!
Here is more info on getting viewport width: Get the browser viewport dimensions with JavaScript

Related

How to align text to bottom, while floating css shape to side, so that text wraps to shape?

I have some text inside a <p> that is inside a <div>. I have a css image shape that floats to one side. I want the text in the two upper boxes to wrap to the shape but also align to the bottom of the div. The two lower boxes work fine because I do not need to vertically align the text within them. The problem is, the text can vary in length and so can the amount of lines, so I can not use a fixed height. Therefore absolute positioning will not work, plus the text will ignore my floating css image shape.
I have read dozens of questions and answers and all of them seem to use hacks. There is also one question that seems to ask the same as mine, but I can't find it anymore, besides there was only one answer which was javascript based. I tried using flexboxes with align-items:flex-end; but that doesn't work well with my floating shapes. I also tried using a table and vertical-align:bottom; but my text just breaks to another line and doesn't wrap to the shape.
A workaround I came up with is to use padding-top on the text, but not knowing the height of the text means the text does not always position it to the bottom of the div, especially if the length of text changes.
EDIT: I am totally open to any new ideas. This was just the best approach I could come up with. I even started toying around with the idea of using only one shape for all four boxes. But that seems a bigger challenge.
EDIT: I also updated the URL's so you can now run the code snippet.
EDIT: I have decided to go the Javascript route and am working on a solution. I am open to any ideas.
EDIT: What bothers me the most, is that every single idea I come up with requires an army of Javascript. The solution, in my opinion, should NOT require a nightmare. CSS should be able to solve this, but I can't seem to find a way without Javascript.
div, img, p {
margin:0px;
border:0px;
padding:0px;
}
#wrapper {
display:block;
position:absolute;
left:0px;
top:0px;
width:100%;
height:100%;
}
.box {
display:block;
position:absolute;
width:50%;
height:50%;
}
.box p { line-height:1.5em; padding:10px; }
/* The image shape is 300px x 300px. * /
/* I use 50vh because I want the shape size to always be half of the window height. */
/* This gives the illusion of one larger shape. */
.shape {
position:relative;
shape-margin:2em;
width:50vh;
height:50vh;
}
/* My workaround solution - #top_left p, #top_right p { padding-top:29vh; } */
#top_left { right:50%; top:0%; }
#bottom_left { right:50%; top:50%; }
#top_right { left:50%; top:0%; }
#bottom_right { left:50%; top:50%; }
#top_left p, #bottom_left p { text-align:right; }
#top_right p, #bottom_right p { text-align:left; }
#top_left .shape { float:right; shape-outside:url('https://i.stack.imgur.com/B1Dzu.png'); }
#bottom_left .shape { float:right; shape-outside:url('https://i.stack.imgur.com/Vxmz0.png'); }
#top_right .shape { float:left; shape-outside:url('https://i.stack.imgur.com/UL8uT.png'); }
#bottom_right .shape { float:left; shape-outside:url('https://i.stack.imgur.com/EGBRz.png'); }
<div id="wrapper">
<div id="top_left" class="box">
<img src="https://i.stack.imgur.com/B1Dzu.png" class="shape" />
<p>Here is some text. Here is some text. Here is some text.</p>
</div>
<div id="top_right" class="box">
<img src="https://i.stack.imgur.com/UL8uT.png" class="shape" />
<p>Here is some text. Here is some text. Here is some text.</p>
</div>
<div id="bottom_left" class="box">
<img src="https://i.stack.imgur.com/Vxmz0.png" class="shape" />
<p>Here is some text. Here is some text. Here is some text.</p>
</div>
<div id="bottom_right" class="box">
<img src="https://i.stack.imgur.com/EGBRz.png" class="shape" />
<p>Here is some text. Here is some text. Here is some text.</p>
</div>
</div>
I have created an image to illustrate. The pink borders are just to show the box boundaries.
shape_top_left.png
shape_top_right.png
shape_bottom_left.png
shape_bottom_right.png
The best you will probably achieve is through using the shape-outside property
Check out here for some documentation.
However, be warned as of 2019 this isn't supported in Internet Explorer or Microsoft Edge
A simple enough codepen example would be this
Well here is my Javascript solution. It requires a lengthy script so I will just get to the core of the solution.
The Workaround
With my CSS image shape floating to the right I can still get wrapping text, even though I want my text to align to the bottom. Since no working spec I have seen allows me to vertically align my text to the bottom and get it to wrap to a CSS shape, I need to create the illusion with padding-top. I solved the dilemma of not knowing my text height by running a series of checks through a loop in Javascript. Just check the initial height of the text, then add a single increment of padding-top, then compare with the parent container's height. Repeat this process until the text height reaches or exceeds the parent containers height. The important thing here is that each time you add an increment of padding-top, you change the height of the text. The more padding you add, and the closer the text gets to the CSS shape, the more the text wraps and flows differently. This is why we need to check the height on each increment. Since my text has a font size in EM units, I would have a hard time knowing it's computed height doing guesswork. Add in client zooming and it's a math nightmare! Rather we just check with single increments and no math needed, hooray!
My Javascript
This is just a core example, not the full script, but you should get the idea.
var counter = 0 ;
function checkHeight()
{
var container = document.getElementById("top_left") ;
var text = document.getElementById("top_left_text") ;
var container_height = container.offsetHeight ;
counter++ ;
text.style.paddingTop = counter + "vh" ;
var text_height = text.offsetHeight ;
if ( text_height < container_height ) { checkHeight() ; }
}
Another Future Solution
Using CSS Exclusions.
With CSS Exclusions you can have an element that does not float but, behaves like a floating element, so that content wraps around the element in much the way that floating elements do. Unfortunately, there is almost no support for this technology at the moment. That said, I would strongly encourage anyone interested to join the discussion and get more buzz going for the draft to maybe become a real spec. CSS Exclusions open up some really cool possibilities that, in my opinion, bring HTML out of the stone age in terms of document flow.
In the case of my problem here, I would simply be able to absolutely position my CSS image shape and get my layout without the need of Javascript. My text would be vertically aligned to the bottom because there would be no floats to say otherwise.
For those who want to know more about CSS shapes, read this excellent article.

How does intro.js works?

I have an on boarding tour in at my.bonify.de. It offers a similar experience to introjs.
We implemented this in a very ugly way using a cutout div with a very large box-shadow. We would like to improve upon this and use an overlay like introjs since it seems to have much better performance than our dirty hack.
Having read this, I do not understand how introjs works since the element to be highlighted should definitely be in a lower stacking context.
I have tried replicating the behaviour with our own onboarding but I can not get the element in the page to rise above the overlay.
I would like to know how introjs achieves this, I thought that this block of code was the secret but when I put a debugger the class is not added.
Easy, you just put a relative element with higher z-index on top of a fixed element. Sample classes:
.fixed-elem {
position:fixed;
top:0;
right:0;
bottom:0;
left:0;
z-index:2;
background: rgba(0,0,0,0.75);
}
.relative-elem {
position:relative;
z-index:10;
}
Here is a working fiddle:
https://jsfiddle.net/7ergcfvq/1/
Look at demo step 1 of intro.js, the <h1>Intro.js</h1> element has .introjs-relativePosition and .introjs-showElement, so it got position:relative and z-index:9999999!important.
And the <div class="intros-overlay">'s z-index 999999, smaller than <h1> & <div class="introjs-helperLayer">

How to reduce width of div using JQuery, CSS so that the left section is reduced and not the right?

This sounds like a stupid question but I cannot figure an easy way of doing it. Let us say that I have a fixed-width Div with the string ABCDEFGHIJ as its content. If I reduce the width it will stop showing HIJ or whatever from the right side. I want the visibility of the content from the left side getting impacted. So, let's say that the div has a width of 100px, then
$(div).css('width':'50px');
should not impact the display of EFGHIJ, for example.
Yes, I could have an inner div and shift its position to the left, for example, by the amount of width reduced. Is there a shorter way of doing this?
Thanks
To Hide the beginning letters but not the last letters, you need to change the direction of the letters using css direction: rtl.
and also to hide the letters, you should mention overflow: hidden and some width to the container.
Working Fiddle
One solution is to use a wrapper and CSS positioning:
jsFiddle example
<div id="outer">
<div id="inner">ABCDEFGHIJ</div>
</div>
#outer {
position:relative;
overflow:hidden;
border:1px solid #999;
width:50px;
height:20px;
}
#inner {
position:absolute;
right:0;
}

Div to be fixed at the top of the window

Guys I want to fix a div width and height as 100%. But the problem is that div is inside a wrapper with a fixed width.
I have a button above the div which onclick="" makes the div to change its class with full width and height. i want to position that div to the top-left corner of the window.My code is
<html>
<head>
<title>Javascript Change CSS Class of Div tag</title>
<style type="text/css">
#wrapper
{
width:75%;
height:75%;
margin:0 auto;
}
.minimize {
color : red;
width:500px;
height:200px;
background:#474747;
float:left;
}
.maximize {
color : blue;
width:100%;
height:100%;
float:left;
background:#ccc;
}
</style>
<script language="javascript" type="text/javascript">
function changeCssClass(navlink)
{
if(document.getElementById(navlink).className=='minimize')
{
document.getElementById(navlink).className = 'maximize';
}
else
{
document.getElementById(navlink).className = 'minimize';
}
}
</script>
</head>
<body> <div id="wrapper">
<div id="navlink" class="minimize"><input type="button" value="click here" onclick="changeCssClass('navlink')" /> </div>
</div>
</body>
</html>
But i want to make it to look like this with wrapper
<html>
<head>
<title>Javascript Change CSS Class of Div tag</title>
<style type="text/css">
.minimize {
color : red;
width:500px;
height:200px;
background:#474747;
float:left;
}
.maximize {
color : blue;
width:100%;
height:100%;
float:left;
background:#ccc;
}
</style>
<script language="javascript" type="text/javascript">
function changeCssClass(navlink)
{
if(document.getElementById(navlink).className=='minimize')
{
document.getElementById(navlink).className = 'maximize';
}
else
{
document.getElementById(navlink).className = 'minimize';
}
}
</script>
</head>
<body>
<div id="navlink" class="minimize"><input type="button" value="click here" onclick="changeCssClass('navlink')" /> </div>
</body>
</html>
Will any one help here....
If anyone has any suggestion??
I think this is what you were after, but it was hard to tell because you didn't specify exactly what states should be held for .minimize and .maximize.
Notice that the javascript is substantially different than your original.
Since 'class' is an attribute on DOM elements, it should be accessed using getAttribute and setAttribute. There was a very, very old bug in IE6 that would only let javascript access an element's classes via className, but that is no longer the case.
Additionally, take notice of how I'm handling the class attribute. Since you can specify multiple classes on an element, this code takes that into account. You can safely add more classes without fidgeting with maximize and minimize.
The 2nd thing to look at is the css. Using position:fixed will lock the element into position no matter what the scroll value is. In this example, there are 2 ways to set the div to be full screen. The first is specifying width and height at 100%. However, this is brittle.
Its better to set top, right, bottom, and left to 0. This gives you more control. Also, suppose you wanted a thin margin around the edges. Instead of worrying about mixing top and left with width and height, you can just specify a pixel or percentage value for the 4 properties I've mentioned to get an easy, uniform look.
I checked Berker's fiddle and it will fix your problem.
Sowmya uses this fiddle, but I have made a few changes, check this out:
Since class is an attribute on DOM elements, it should be accessed using getAttribute and setAttribute. There was a very, very old bug in IE6 that would only let javascript access an element's classes via className, but that is no longer the case.
Take a look at this fiddle, http://jsfiddle.net/Tv2pP/7/
I think this is what you were after, but it was hard to tell because you didn't specify exactly what states should be held for .minimize and .maximize.
Notice that the javascript is substantially different than your original.
Since 'class' is an attribute on DOM elements, it should be accessed using getAttribute and setAttribute. There was a very, very old bug in IE6 that would only let javascript access an element's classes via className, but that is no longer the case.
Additionally, take notice of how I'm handling the class attribute. Since you can specify multiple classes on an element, this code takes that into account. You can safely add more classes without fidgeting with maximize and minimize.
The 2nd thing to look at is the css. Using position:fixed will lock the element into position no matter what the scroll value is. In this example, there are 2 ways to set the div to be full screen. The first is specifying width and height at 100%. However, this is brittle.
Its better to set top, right, bottom, and left to 0. This gives you more control. Also, suppose you wanted a thin margin around the edges. Instead of worrying about mixing top and left with width and height, you can just specify a pixel or percentage value for the 4 properties I've mentioned to get an easy, uniform look.
Lastly, if you have the option you should use a standardized library like jQuery. It has become an incredibly useful tool over the years for doing exactly this kind of thing without you, the developer, having to worry about the underlying browser platform discrepancies too much.
Remove margin:0 auto from the wrapper class
Check this http://jsfiddle.net/PAj39/
Take a look at this fiddle, http://jsfiddle.net/Tv2pP/7/
I think this is what you were after, but it was hard to tell because you didn't specify exactly what states should be held for .minimize and .maximize.
Remove margin:0 auto from the wrapper class
Check this http://jsfiddle.net/PAj39/
The below method makes the inner div to align top left to the browser
add position:fixed; top:0; left:0 to .minimize
Demo http://jsfiddle.net/PAj39/2/
Just set the div width:100%; with position:fixed; to it.
But the wrapper must have position:absolute; property

Absolute positioning and floats

I have a rather unusual layout that I'm trying to make a reality. There is a div containing, for sake of argument, that needs to be fixed at 200px from the left and from the top of a wrapper.
I then have a collection of square images that would all be floated and would continue to the edge of the browser window, and wrap around the absolutely positioned div. I know that absolute positioning takes the div out of the doc flow, which means I can't think of a simple solution for this.
Has anyone worked out a way around this kind of problem? Potentially with javascript?
EDIT: Here's the rough layout: link
I'm guessing you want more flexibility, but just in case, if your design is reasonably fixed, you can just use 3 columns (container divs) and sort it all out per column.
If your html is fixed, you could use javascript but I don't know of any ready-made solutions.
I would probably use javascript to do some math and inject dummy images / elements behind the black box at the right positions (keeping the black box absolutely positioned). You could also do that server-side.
Edit: Judging from your image, I would personally use a table. However, it can be achieved with floats:
(image: http://i.stack.imgur.com/KAqxZ.png)
<style>
#cont {
width: 100px;
}
.small {
float:left;
height:25px;
width:25px;
background-color:#00F;
}
.big {
float:left;
height:50px;
width:50px;
background-color:#F00;
}
.long {
float:left;
height:50px;
width:25px;
background-color:#F0F;
}
.long .small {
background-color:#F0F;
}
</style>
<div id="cont">
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="long">
<div class="small"></div>
<div class="small"></div>
</div>
<div class="big"></div>
<div class="small"></div>
<div class="small"></div>
</div>
Original text:
I would do something like this:
<div class="absolute-wrapper">
<div><!-- whatever content you intended for the absolute div... --></div>
<div class="float-left">...</div>
<div class="float-left">...</div>
...
</div>
However, I feel inclined to recommend you search for another solution than an absolutely positioned element. They easily grow unmaintainable.
You could do this with a canvas element, but it has downsides. You will be depending on javascript, as you will need to do all positioning in javascript.
Not to be unhelpful, but I also think you should consider how important this exact design is, simply because I don't think there is any straightforward solution, since HTML as it is today isn't really built for these kinds of layout. The future is promising though, giving us things like multi-column and flexbox...
Using javascript/jQuery, it could be accomplished using the logic of the following pseudo code:
Create a function which preforms these steps....
Step 1: Remove any divs from the dom that have a class named fakeSquare. Something like
$('.fakeSquare').remove();
Step 2: Calculate the number of red divs in one row. Store this number in squaresPreRow. Something like: var squaresPreRow = floor( window width / square width ).
Step 3: After the squaresPreRow + 1 red square div, add two empty divs. Like so...
$("div.redSquare")
.index(squaresPreRow + 1)
.append("<div class="fakeSquare redSquare"></div><div class="fakeSquare redSquare"></div>");
Step 4: Add another two square for the third row...
$("div.redSquare")
.index((squaresPreRow * 2) + 1)
.append("<div class="fakeSquare redSquare"></div><div class="fakeSquare redSquare"></div>");
Step 5: And again...
$("div.redSquare")
.index((squaresPreRow * 3) + 1)
.append("<div class="fakeSquare redSquare"></div><div class="fakeSquare redSquare"></div>");
Finally you want to call this function when the DOM is ready and whenever the window changed.
This may need some tweaking, but hopefully it can get you started.

Categories

Resources