In the image below you can see a div (red background) with three divs (green background) inside and each of them with a label (blue background) and a control (input or checkbox) inside.
In the image you can see how the green divs adjust to the size of the screen and when they reach their minimum size and no longer fit in the line they move down, the problem is (as you can see in the third windows) it looks awful when they are in different lines because of their minimum size attributes, what I want to do is to make them occupy the 100% of the screen when they move down.
I hope I explained correctly.
By the way, I don't want to use plugins, so if there is a way of doing this with only HTML, CSS and Javascript I would be very happy.
Thank you so much by advance.
Here is my code:
.controlRow
{
display: flex;
flex-wrap: wrap;
padding: 5px 0px;
margin: 0px;
background-color: Red;
}
.controlColumn1-2, .controlColumn1-4, .controlColumnCheckbox
{
display: inline-flex;
background-color: green;
}
.controlColumn1-2 { width: 50%; min-width: 300px; }
.controlColumn1-4 { width: 25%; min-width: 300px; }
.controlColumnCheckbox { width: 230px; }
.controlColumn1-2 label, .controlColumn1-4 label, .controlColumnCheckbox label
{
margin-right: 5px;
min-width: 100px;
background-color: blue;
}
.controlColumn1-2 input, .controlColumn1-4 input
{
margin-right: 5px;
width: 100%;
}
.controlColumnCheckbox input
{
margin-left: 105px;
margin-right: 5px;
width: 14px;
}
<div class = "controlRow">
<div class = "controlColumn1-4">
<label id="lblNombre">Nombre:</label>
<input type="text" id="txtNombre" maxlength="100" />
</div>
<div class = "controlColumn1-2">
<label id="lblDescripcion">Descripcion:</label>
<input type="text" id="txtDescripcion" maxlength="100" />
</div>
<div class = "controlColumn1-4">
<div class = "controlColumnCheckbox">
<input type="checkbox" id = "checkActivo" checked="checked" />
<label id="lblActivo">Activo.</label>
</div>
</div>
</div>
Instead of this:
.controlColumn1-2 { width: 50%; min-width: 300px; }
.controlColumn1-4 { width: 25%; min-width: 300px; }
Try this:
.controlColumn1-2 { flex: 2 0 300px; }
.controlColumn1-4 { flex: 1 0 300px; }
DEMO
Learn more about the flex property at MDN.
Also a great reference: Common Values of Flex
Related
I want to reposition my browse button when the user uploaded a file. This is the sample of how it should really look before and after uploading the file:
Before:
After:
I change the content of my button "Browse file" to "Replace File"
This is my html code.
<div id="uploadModal" class="upload-modal">
<div class="modal-content">
<h2 style="font-size: 24px;">Choose file</h2>
<p>
Choose the csv file containing the data you want to create a forecast for.
</p>
<div class="browse-file">
<div id="filename"></div>
<input type="file" id="file-upload" multiple required />
<label for="file-upload">Browse file</label>
</div>
<div class="options">
<button class="cancel"><h4>Cancel</h4></button>
<button class="proceed"><h4>Proceed</h4></button>
</div>
</div>
</div>
Here is my CSS
.upload-modal {
display: none;
position: fixed;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 34, 2, 0.3);
}
input[type="file"] {
position: absolute;
opacity: 0;
z-index: -1;
}
input + label {
padding: 10px 24px;
background: #D4E8CF;
border-radius: 100px;
position: static;
width: 119px;
height: 40px;
border: none;
cursor: pointer;
z-index: 1;
}
#filename{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100px;
justify-content: left;
align-items: flex-start;
}
What's happening here is that my button moves according to the length of the file so I added max-width but no luck. Thanks!
EDIT: I added css for upload-modal
I'm not sure you need to use absolute positioning for what you want.
You could set div#upload-modal or div.modal-content to position: relative;
and then position the button element with left: or right: or use float: right;
https://developer.mozilla.org/en-US/docs/Web/CSS/position
https://developer.mozilla.org/en-US/docs/Web/CSS/float
This alternate version uses CSS's Flexbox and JavaScript's Event Listeners.
It probably doesn't do precisely what you want but should come close enough that reading through the comments a few times and playing around with the code should make clear how you can get to where you want to go using just a few lines of JavaScript to grab the file name and show it on the screen.
MDN (linked above) is a great place to get more clarity about any particular front-end feature that you're interested in using. Happy coding!
// Unnamed function runs as soon as the DOM elements are ready
window.addEventListener('DOMContentLoaded', () => {
// Identifies some of the DOM elements
const
filenameSpan = document.getElementById("filename-span"),
fileInput = document.getElementById("file-input"),
chooseBtn = document.getElementById("choose-btn");
// When the input changes (when a file is chosen), calls `updateDisplay`
fileInput.addEventListener("change", updateDisplay);
// Defines `updateDisplay`
function updateDisplay(){
// Puts first fiename in span and "unhides" it
const filename = fileInput.files[0]?.name;
filenameSpan.textContent = filename || "(choose file)";
filenameSpan.classList.remove("hidden");
};
});
*{
margin: 0;
}
#container{
width: 18rem; /* "rem" unit is the base character height */
padding: 2rem;
border-radius: 1.5rem;
background-color: lightgrey;
}
#header{
margin-bottom: 2rem;
}
#chooser{
/* flex w/ space-around makes choose-btn shift right when filename appears */
display: flex;
justify-content: space-around;
margin-bottom: 4rem;
}
#options{
text-align: right;
}
#filename-span{
padding: 1rem 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 6rem;
}
button{ /* the "options" buttons */
border: none;
font-weight: bold;
color: darkgreen;
background-color: lightgrey;
}
#choose-btn{
/* Not a true "button" element -- the "label" for file-input */
padding: 1rem 1.5rem;
background-color: darkseagreen;
border-radius: 2rem;
border: none;
font-weight: bold;
}
.hidden{ /* Uses a class so all styling happens thru CSS */
display: none;
}
<div id="container">
<div id="header">
<h2>Choose file</h2>
<p> Choose the csv file containing the data you want to create a forecast for</p>
</div>
<div id="chooser">
<!-- The span and input elements are initially "hidden" via CSS -->
<span id="filename-span" class="hidden"></span>
<label id="choose-btn">
<!-- input element is inside its stylable & clickable label -->
Browse File
<input id="file-input" type="file" class="hidden" />
</label>
</div>
<div id="options">
<button id="cancel-btn">Cancel</button>
<button id="proceed-btn">Proceed</button>
</div>
</div>
I have two sections one over the other.
What I want to do is that when I click the button, the first section display: none with a small transition and the second one appears. I need to do that with vanilla JavaScript as I'm learning it.
My goal is to be able to create a login when the password is entered, the person is moved to the second section. (this is just for Front end, nothing backend).
Here is the code below:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Login Background */
#first{
position: absolute;
width: 100%;
height: 100vh;
background-color: #464159;
z-index: 1;
}
/* Login */
.login-container{
position: absolute;
top: 50%;
right: 50%;
transform: translate(50%, -100%);
display: flex;
align-items: center;
justify-content: center;
}
.logo{
justify-content: center;
margin-right: 20px;
}
.logo img{
width: 180px;
height: auto;
}
.user{
display: flex;
flex-direction: column;
}
.w8u{
color: white;
font-size: 15px;
margin: 0 0 10px 0;
}
.submit{
flex: 1;
margin: 30px 0 0 10px;
}
/* Menu */
#second{
position: absolute;
width: 100%;
height: 100vh;
background-color: orangered;
z-index: -1;
}
<body>
<section id="first">
<div class="login-container">
<!-- Logo User -->
<div class="logo">
<img src="w-logo.jpg" alt="User">
</div>
<!-- User Name -->
<div class="user">
<div class="w8u">
<h3>User</h3>
</div>
<div>
<input class="input" type="password" placeholder="Enter your password" required>
</div>
</div>
<!-- Submit Button -->
<button id="btn-submit" class="submit" type="submit" onclick="">GO!</button>
</section>
<section id="second">
</section>
<script src="app.js"></script>
</body>
Yes, you can change CSS of elements using JavaScript:
function login(){
document.getElementById("first").style.display="none";
document.getElementById("second").style.display="block";
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Login Background */
#first{
position: absolute;
width: 100%;
height: 100vh;
background-color: #464159;
z-index: 1;
}
/* Login */
.login-container{
position: absolute;
top: 50%;
right: 50%;
transform: translate(50%, -100%);
display: flex;
align-items: center;
justify-content: center;
}
.logo{
justify-content: center;
margin-right: 20px;
}
.logo img{
width: 180px;
height: auto;
}
.user{
display: flex;
flex-direction: column;
}
.w8u{
color: white;
font-size: 15px;
margin: 0 0 10px 0;
}
.submit{
flex: 1;
margin: 30px 0 0 10px;
}
/* Menu */
#second{
position: absolute;
width: 100%;
height: 100vh;
background-color: orangered;
z-index: -1;
}
<body>
<section id="first">
<div class="login-container">
<!-- Logo User -->
<div class="logo">
<img src="w-logo.jpg" alt="User">
</div>
<!-- User Name -->
<div class="user">
<div class="w8u">
<h3>User</h3>
</div>
<div>
<input class="input" type="password" placeholder="Enter your password" required>
</div>
</div>
<!-- Submit Button -->
<button id="btn-submit" class="submit" type="submit" onclick="login()">GO!</button>
</section>
<section id="second">
Section 2
</section>
<script>
</script>
</body>
Short Answer:
You can solve your issue by using a common pattern of styling transitions and toggling classes in JavaScript.
/* Get Screen Container */
let context = document.querySelector("main.screen-container");
/* Helper Methods */
// Utility
const ele = context.querySelector.bind(context),
eles = context.querySelectorAll.bind(context);
// Action
const showScreen = inactiveScreen => {
const screens = eles(".screen");
screens.forEach(screen => screen.classList.remove("active-screen"));
inactiveScreen.classList.add("active-screen");
}
// Elements
const login_button = ele("#loginBtn"),
logout_button = ele("#logoutBtn"),
login_screen = ele("#login"),
loggedIn_screen = ele("#loggedIn");
// Add Event Listeners and Handlers
login_button.addEventListener("click", () => showScreen(loggedIn_screen));
logout_button.addEventListener("click", () => showScreen(login_screen));
.full-width-full-height {
width: 100%;
height: 100%;
}
.no-overflow {
overflow: hidden;
}
.inputs-container {
display: flex;
flex-direction: column;
justify-content: center;
height: 200px;
padding: 5px;
border: 5px black solid;
}
.inputs-container.inputs {
padding: 10px;
}
.screen#login {
display: flex;
justify-content: center;
}
.screen#loggedIn {
background: rgba(0,0,0,.5);
border: 5px solid rgba(0,0,0,.3);
text-align: center;
}
highlight {
color: rgb(0,100,0);
text-shadow: 3px 3px 10px rgb(0,200,0);
}
.screen-container {
height: 100%;
width: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
main section {
position: absolute;
height: 0px;
width: 0px;
opacity: 0;
transition: all .3s ease-in-out;
}
main section.active-screen {
height: 100%;
width: 100%;
opacity: 1;
}
<body class="full-width-full-height no-overflow">
<main class="screen-container full-width-full-height">
<section id="login" class="screen active-screen">
<div class="inputs-container">
<div class="inputs"><label>Username:</label><input type="text" id="username" placeholder="admin" /></div>
<div class="inputs"><label>Password:</label><input type="password" id="password" /></div>
<button id="loginBtn">login</button>
</div>
</section>
<section id="loggedIn" class="screen">
<h3>User Successfully <highlight>Logged In</highlight></h3>
<button id="logoutBtn">logout</button>
</section>
</main>
</body>
Explanation of Answer:
In your question you're asking for help in the following:
Using Sections as Different Screens in an Application
Change Screens on an Event such as click
Transition between Screens when the Screen Changes
Something like this isn't an atypical need and, in fact, just looking at the above you can see the resemblance between what you're looking for and common things like a carousel or tab navigation.
Since this is the case there is a pretty common pattern when designing markup based around these types of requirements and this pattern is used in frameworks like BootStrap, DataTables, JQuery, etc.
The Mark-Up Pattern:
Create a Container
Provide a class to define this type of container ( screen-container )
Create Visual Elements
In your case Section Elements dubbed Screens
Provide a class to define these specific elements
In your case something like screen
You will likely also want to provide an ID for each of these Visual Elements based on their Content.
In your case something like login and loggedIn
Create a class that will serve as the active Visual Element
In your case something like active-screen
Incorporating the above you end up with a basic outline:
<main class="screen-container">
<section id="login" class="screen active-screen"></section>
<section id="loggedIn" class="screen"></section>
</main>
Example:
html, body, main, .screen-container {
height: 100%;
width: 100%;
}
.screen-container
.screen {
padding: 3px;
background: rgba(24,24,24, .3);
border: 3px solid black;
width: 100px;
height: 100px;
}
.screen-container
.screen.active-screen {
border-color: green;
}
<main class="screen-container">
<section id="login" class="screen active-screen">login</section>
<section id="loggedIn" class="screen">logged in</section>
</main>
Styling:
In your initial question you say that you want to use the display property to hide and show your screens, however, you also state that you would like to have the screens transition from one to another.
Transitioning is definitely possible through the aptly named CSS transition property ( More info on MDN ).
The problem is that the display property is not able to be animated. If an element is configured to display: none; the page is immediately repainted with that element removed.
This means that you need to use a different property, and we typically would use opacity or visibility. Here are the differences between these three:
display: none;
immediately collapses the element
removes the element from view.
There's no transition allowed.
visibility: hidden;
Does not collapse the element
The space it occupied is blank.
removes the element from view
Transitions are allowed
The element will still pop out of sight.
opacity: 0;
Does not collapse the element
The space it occupied is blank.
removes the element from view
Transitions are allowed.
The element will fade until it is not visible.
Here is an example of the different way these properties affect the layout of the page:
const context = document.querySelector("#examples");
const ele = context.querySelector.bind(context),
hide = section => section.classList.toggle("hide"),
onClickHide = (btn, section) => btn.addEventListener("click", () => hide(section));
opacity = ele(".opacity"),
opacity_button = ele("#oBtn"),
visibility = ele(".visibility"),
visibility_button = ele("#vBtn"),
display = ele(".display"),
display_button = ele("#dBtn"),
toggle_button = ele("#tBtn");
onClickHide(opacity_button, opacity);
onClickHide(visibility_button, visibility);
onClickHide(display_button, display);
toggle_button
.addEventListener("click", function() {
hide(opacity);
hide(visibility);
hide(display);
});
html,
body,
#examples {
width: 100%;
height: 100%;
box-sizing: content-box;
margin: 0px;
padding: 0px;
}
#examples section {
display: flex;
flex-direction: column;
width: 100px;
height: 100px;
border: 5px solid black;
margin: 5px;
transition: all .5s ease-in-out;
}
#examples section.hide {
border-radius: 100px;
}
#examples section.opacity {
background-color: blue;
color: white;
}
#examples section.opacity.hide {
opacity: 0;
}
#examples section.visibility {
background-color: purple;
color: white;
}
#examples section.visibility.hide {
visibility: hidden;
}
#examples section.display {
display: block;
background-color: red;
color: white;
}
#examples section.display.hide {
color: black;
display: none;
}
<main id="examples">
<section class="opacity">opacity <button id="oBtn">hide</button></section>
<hr />
<section class="visibility">visibility <button id="vBtn">hide</button></section>
<hr />
<section class="display">display <button id="dBtn">hide</button></section>
<hr/>
<button id="tBtn">Toggle All</button>
</main>
Note: In the above there are actually two properties transitioning - opacity, visibility, or display - and border-radius. You should notice firstly how in the display example the border-radius change isn't seen at all, and secondly how the display example is the only one that collapses the element so that it no longer takes up space.
Applying Transitions:
By combining opacity: 0; with height: 0px; width: 0px; we can remove the element visually from the page while also removing any impact it has on other elements - meaning that it won't take up space and is transitionable.
setInterval(function() {
const screens = [
document.querySelector(".screen.active-screen"),
document.querySelector(".screen:not(.active-screen)")
];
screens[0].classList.toggle("active-screen");
screens[0].ontransitionend = () => {
screens[1].classList.toggle("active-screen");
screens[0].ontransitionend = undefined;
}
}, 1000)
html,
body,
main,
.screen-container {
height: 100%;
width: 100%;
}
.screen-container .screen {
transition: all .3s ease-in-out;
opacity: 0;
height: 0px;
width: 0px;
}
.screen-container .screen.active-screen {
background: rgba(24, 24, 24, .3);
border: 3px solid black;
padding: 3px;
border-color: green;
width: 100px;
height: 100px;
opacity: 1;
}
<main class="screen-container">
<section id="login" class="screen active-screen">login</section>
<section id="loggedIn" class="screen">logged in</section>
</main>
JavaScript
The final piece of the puzzle is the JavaScript mechanics of the Screens.
Any Programmer wants to make the switch as easy as possible, and this is done typically by providing a function that allows for quick reassignment of the class active-screen by removing it from the current active screen and applying it to the desired visual element.
One thing to take into account is that you want your queries for elements to be as specific as possible. Meaning that instead of document.querySelector you want to provide the smallest context of where to find your Visual Elements. a.e.
/* Get Screen Container */
let context = document.querySelector("main.screen-container");
/* Helper Methods */
// Utility
const ele = context.querySelector.bind(context),
eles = context.querySelectorAll.bind(context);
This prevents code collision where other code in your Application's JavaScript, Styling, or Mark-Up may utilize a screen or active-screen class that isn't relevant to what you're doing here.
Note: This is actually a problem in BootStrap currently. It searches for the active class in it's Tab architecture. This is such a generic class name that other libraries utilize it and it can cause a giant headache to get things to work properly. Writing explicit patching because you didn't think through your design fully is something I'd just as soon spare you from, so try to keep interactivity with other code in mind.
Lastly we write our function ( showScreen ) that allow for quick, easy switching between screens:
// Action
const showScreen = inactiveScreen => {
const screens = eles(".screen");
screens.forEach(screen => screen.classList.remove("active-screen"));
inactiveScreen.classList.add("active-screen");
}
And believe it or not, that's pretty much it!
All that's left to do is apply this functionality to your button click events and it works just as it should:
Result:
/* Get Screen Container */
let context = document.querySelector("main.screen-container");
/* Helper Methods */
// Utility
const ele = context.querySelector.bind(context),
eles = context.querySelectorAll.bind(context);
// Action
const showScreen = inactiveScreen => {
const screens = eles(".screen");
screens.forEach(screen => screen.classList.remove("active-screen"));
inactiveScreen.classList.add("active-screen");
}
// Elements
const login_button = ele("#loginBtn"),
logout_button = ele("#logoutBtn"),
login_screen = ele("#login"),
loggedIn_screen = ele("#loggedIn");
// Add Event Listeners and Handlers
login_button.addEventListener("click", () => showScreen(loggedIn_screen));
logout_button.addEventListener("click", () => showScreen(login_screen));
.full-width-full-height {
width: 100%;
height: 100%;
}
.no-overflow {
overflow: hidden;
}
.inputs-container {
display: flex;
flex-direction: column;
justify-content: center;
height: 200px;
padding: 5px;
border: 5px black solid;
}
.inputs-container.inputs {
padding: 10px;
}
.screen#login {
display: flex;
justify-content: center;
}
.screen#loggedIn {
background: rgba(0,0,0,.5);
border: 5px solid rgba(0,0,0,.3);
text-align: center;
}
highlight {
color: rgb(0,100,0);
text-shadow: 3px 3px 10px rgb(0,200,0);
}
.screen-container {
height: 100%;
width: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
main section {
position: absolute;
height: 0px;
width: 0px;
opacity: 0;
transition: all .3s ease-in-out;
}
main section.active-screen {
height: 100%;
width: 100%;
opacity: 1;
}
<body class="full-width-full-height no-overflow">
<main class="screen-container full-width-full-height">
<section id="login" class="screen active-screen">
<div class="inputs-container">
<div class="inputs"><label>Username:</label><input type="text" id="username" placeholder="admin" /></div>
<div class="inputs"><label>Password:</label><input type="password" id="password" /></div>
<button id="loginBtn">login</button>
</div>
</section>
<section id="loggedIn" class="screen">
<h3>User Successfully <highlight>Logged In</highlight></h3>
<button id="logoutBtn">logout</button>
</section>
</main>
</body>
Conclusion:
I hope this helps and gives you some insight into how this pattern is used! It's not a difficult thing to learn, but it's incredibly useful!
Good luck and Happy Coding!
This question already has answers here:
Scrollable div to stick to bottom, when outer div changes in size
(7 answers)
Closed 6 years ago.
Here's what I currently have:
https://jsfiddle.net/Lt4cmfbo/
CSS
.parent {
position: relative;
float: none;
height: 400px;
width: auto;
background: purple;
overflow: hidden;
display: flex;
flex-direction: column;
}
.childOne {
background: blue;
width: 100%;
height: auto;
overflow-y: auto;
flex-grow: 1;
}
.childTwo {
background: red;
}
.input-chat {
background-color: white;
margin: 5px auto;
border: solid 1px #000;
min-height:10px;
max-height: 100px;
overflow: auto;
width: 95%;
}
HTML
<div class="parent">
<div class="childOne">
<p>
content #1
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
hello
</p>
</div>
<div class="childTwo">
<div class="input-chat" contentEditable="true"></div>
</div>
</div>
Basically, I'm trying to build a chat. Inside of the parent div are two child divs: the top one is scrollable (for displaying messages) and the bottom one is for typing your message to send.
I am using flex boxes to control the height so that both child divs together always equal the parent div height. The bottom child div must expand or shrink based on content (which I have done), while the top child div expands or shrinks based on the height of the bottom child div (which I have also done).
The problem is that I also want the top div to retain its scroll position as its height changes. If I scroll to the bottom of the top child div and see 'hello', I want to still see 'hello' as I am typing up several rows in the bottom div. But instead, the bottom div seems to hide it unless I manually scroll to reveal it.
I hope this was clear enough, but if it's not, I can try to explain it some other way.
I am hoping that my answer is in CSS (or CSS3), but if that's not possible, jquery or pure javascript is fine.
Set the scrollTop equal to the scrollHeight:
let c1 = document.querySelector('.childOne'),
c2 = document.querySelector('.childTwo>div'),
b = document.querySelector('button');
b.addEventListener(
'click', () => {
c1.innerHTML += '<br>' + c2.innerHTML;
c1.scrollTop = c1.scrollHeight;
c2.innerHTML = '';
c2.focus();
},
false);
.parent {
position: relative;
float: none;
height: 400px;
width: auto;
background: purple;
overflow: hidden;
display: flex;
flex-direction: column;
}
.childOne {
background: blue;
width: 100%;
height: auto;
overflow-y: auto;
flex-grow: 1;
}
.childTwo {
background: red;
}
.test {
background-color: white;
margin: 5px auto;
border: solid 1px #000;
min-height: 10px;
max-height: 100px;
overflow: auto;
width: 95%;
}
<div class="parent">
<div class="childOne">
<p>
content #1
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
<br><br>hello
</p>
</div>
<div class="childTwo">
<div class="test" contentEditable="true"></div>
<button>
Add</button>
</div>
</div>
I would like to be able to add an animation to this simple query for when the div is transitioned to its new position.
<div class="container">
<div class="left-side-bar">
<div class="long blue" id="1">
1
</div>
<div class="short red" id="2">
2
</div>
</div>
<div class='middle-side-bar'>
<div class='long green' id="3">
3
</div>
</div>
<div class='right-side-bar'>
<div class='short yellow' id="4">
4
</div>
</div>
</div>
the CSS
.left-side-bar{
clear: both;
width: 32%;
text-align: center;
float: left;
margin-top: 1%;
margin-bottom: 100px;
}
.middle-side-bar{
width: 32%;
text-align: center;
float: left;
margin: 1% 0 1% 1.6%;
}
.right-side-bar{
width: 32%;
text-align: center;
float: left;
margin: 1% 0 1% 1.6%;
}
.green {
background-color: green;
}
.long {
height: 300px;
}
.short {
height: 200px;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
Basically I want the div to be moved to its new place as an animated transition, rather than have it simply appear.
here is the jsfiddle
DEMO
Unfortunately, the replaceWith method does not work with animate in jQuery. Instead, you will probably need to find an alternative method to your solution. Here's one that slowly transitions the red box on top of the yellow box... http://jsfiddle.net/aeyg89rd/4/
I added the following jQuery, note that I used offset() to get the left and top properties of the yellow box, then I moved the red box to those left and top positions using animate() :
$(document).ready(function () {
var num4 = $("#4").offset();
$("#2").animate({ top: num4.top, left: num4.left }, 1000);
});
And I changed some CSS attributes for .red class so that I can move it around with the jQuery code above. More specifically, I changed its position to absolute, and gave it a width dimension:
.red {
position: absolute;
top: 320px;
background-color: red;
width: 150px;
}
I have some modules on my project that are generated dynamically. This basic HTML will work fine as an example of what I want to achieve:
<div class="container">
<div class="image">
image here
</div>
<div class=" ellipsis">
<div class="description">
here we have a text not very long for a small module
</div>
</div>
<div class="end">
buttom
</div>
</div>
My problem is that I don't want this module to ever grow too much vertically, if the web administrator writes a long "description" (I can't limit how much he wants to write as the "description" text will show on other pages).
I found a nice CSS trick to add "ellipsis" to a multiple lines container. Here you can see this "trick" in the .ellipsis (plus the basic CSS):
.container {
background-color: #eee;
width:100px;
margin:20px;
float:left;
}
.image {
border:2px solid #999;
width:100px;
height:60px;
background-color: #fff;
margin-bottom:10px;
}
.end {
border:2px solid #999;
width:100px;
background-color: #fff;
}
.ellipsis {
overflow: hidden;
max-height: 200px;
line-height: 25px;
margin-bottom:10px;
position:relative;
}
.ellipsis:before {
content:"";
float: left;
height:100%;
width: 5px;
height: 200px;
}
.ellipsis > *:first-child {
float: right;
width: 100%;
margin-left: -5px;
}
.ellipsis:after {
content: "\02026";
box-sizing: content-box;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
float: right; position: relative;
top: -25px; left: 100%;
width: 20px; margin-left: -20px;
padding-right: 5px;
text-align: right;
background-color:#eee;
}
You can see everything together here: JSFIDDLE
The problem I have is that while ellipsis works fine, I don't want ALL the modules to have a fixed height. I just want to limit the max-height to a fixed size. (Just delete "height: 200px;" from ".ellipsis:before" to see what I want to achieve.)
So, the problem is the .ellipsis:before fixed height. 100% height won't work unless I turn the position to absolute, but then the "ellipsis" trick won't work as the float won't take effect.
Any help with my problem will be greatly appreciated. I don't think there may be a pure CSS solution, (trust me, I have tried) and I'm very bad a JavaScript/jQuery. However, if you have a jQuery solution that may help, I could implement it in the project (and give you nice rep points here :) ). I was thinking something like:
If div.ellipsis > 200px then add height:200px to ellipsis:before
Thanks a lot in advance and please excuse my poor English. Hope the question is clear enough.
There is no need of :before pseudo class. Check this fiddle.
.ellipsis:after {
content:"\02026";
position: absolute; /* removed position: relative */
top: 200px; /* equal to max-height value */
right: 0px;
margin-top: -25px; /* equal to line-height value */
/* other styles */ /* removed float property */
}
Working Fiddle
In the above fiddle, I removed :before pseudo class and set the position of the :after pseudo class to top by 200px which is equal to the given max-height value of the .ellipsis.
and to remove the default upper and lower gaps of the container, I added margin-top: -25px which is equal to the given line-height.
Note: You can apply just top: 175px which is result value of subtraction of given max-height and line-height values.
Here's a simple jQuery solution.
First add a class for when an ellipsis reaches the maximum height, let's call it maxed. Set the :before height for that to 200px:
.ellipsis.maxed:before {
height:200px;
}
Then as you say. you can do some simple jQuery to check the height. If it is the maximum, then add our maxed class to the ellipsis:
$(function() {
$('.container .ellipsis').each(function() {
var $this = $(this);
if($this.height() >= 200) {
$this.addClass('maxed');
}
});
});
Updated fiddle here
You can do it easily with jquery (I assume jquery is an available option in your project).
You just have to
Remove all "ellipsis" class from HTML
Add "ellipsis" whenever needed with JS (= when your content exceeds 200px).
For that, you can use the following :
$('.description').each(function(){
if($(this).height() >= 200 ){
$(this).parent().addClass('ellipsis');
}
});
Working JSfiddle
You can't directly manipulate pseudo elements like :before. What you could do here is add a class for large ellipsis with height: 200px. Then use jQuery to add the new class according to the height.
$(function() {
$('div.ellipsis').each(function (index, element) {
if ($(element).height() >= 200) {
$(element).addClass('ellipsis-large');
}
});
});
See the code snippet for the full example:
$(function() {
$('div.ellipsis').each(function(index, element) {
if ($(element).height() >= 200) {
$(element).addClass('ellipsis-large');
}
});
});
.container {
background-color: #eee;
width: 100px;
margin: 20px;
float: left;
}
.image {
border: 2px solid #999;
width: 100px;
height: 60px;
background-color: #fff;
margin-bottom: 10px;
}
.end {
border: 2px solid #999;
width: 100px;
background-color: #fff;
}
/* ellipsis class for small modules */
.ellipsis {
overflow: hidden;
max-height: 200px;
line-height: 25px;
margin-bottom: 10px;
position: relative;
}
.ellipsis:before {
content: "";
float: left;
height: 100%;
width: 5px;
/* height: 200px; */
}
.ellipsis > *:first-child {
float: right;
width: 100%;
margin-left: -5px;
}
.ellipsis:after {
content: "\02026";
box-sizing: content-box;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
float: right;
position: relative;
top: -25px;
left: 100%;
width: 20px;
margin-left: -20px;
padding-right: 5px;
text-align: right;
background-color: #eee;
}
/* ellipsis class for large modules */
.ellipsis-large:before {
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="image">
image here
</div>
<div class=" ellipsis">
<div class="description">
here we have a text not very long for a small module
</div>
</div>
<div class="end">
buttom
</div>
</div>
<div class="container">
<div class="image">
image here
</div>
<div class=" ellipsis">
<div class="description">
here we have a text not very long for a small module
</div>
</div>
<div class="end">
buttom
</div>
</div>
<div class="container">
<div class="image">
image here
</div>
<div class="ellipsis">
<div class="description">and here we have a much longer text to reach the 200px "ellipsis" div to activate the effect made with pure css. a nice discovery from http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/
</div>
</div>
<div class="end">
buttom
</div>
</div>