I'd like to build a page with some fixed centered elements surrounded by elements thats fill all the space available (depending on browser's width).
Here's a wireframe to illustrate it : http://s23.postimg.org/pm61hyam3/Sans_titre_6.jpg
CSS3, JS ... Is there a way to do that ?
Thanks for the help !
Solution #1
I think the future way how to tackle this problem will be with CSS Exclusions.
Check out this fiddle in IE10+
CSS Exclusions extend the notion of content wrapping previously
limited to floats. ... Elements layout their inline content in their content area and wrap around the exclusion areas in their associated wrapping context (--excerpts from the spec)
This msdn article also explains exclusions
...web authors can now wrap text so that it completely surrounds
elements, thereby avoiding the traditional limitations of floats.
Instead of limiting elements to floating either to the left or right
relative to their position in the document flow, CSS Exclusions can be
positioned at a specified distance from the top, bottom, left, or
right sides of a containing block, while remaining part of the
document flow.
Ironically, to date this only works in IE10 (look for wrap-flow:both here)
This is what the code looks like:
<div class="container">
<div class="exclusion1"></div>
<div class="exclusion2"></div>
<div class="dummy_text">
text here
</div>
</div>
CSS
.exclusion1, .exclusion2
{
-ms-wrap-flow: both;
-ms-wrap-margin: 10px;
z-index: 1;
position:absolute;
left:0;
right:0;
top:0;
bottom: 0;
margin: auto;
}
.exclusion1
{
width: 150px;
height: 150px;
background: yellow;
}
.exclusion2
{
width: 250px;
height: 50px;
background: blue;
margin-top: 320px;
}
Solution #2
The CSS-tricks article Faking ‘float: center’ with Pseudo Elements should help.
FIDDLE
Markup
<div id="page-wrap">
<img src="http://placekitten.com/250/250" id="logo">
<div id="l">
<p>left column text</p>
</div>
<div id="r">
<p>right column text</p>
</div>
</div>
CSS
#logo {
position: absolute;
top: 0;
left: 50%;
margin-left: -125px;
}
#l, #r {
width: 49%;
}
#l:before, #r:before {
content: "";
width: 125px;
height: 250px;
}
#l {
float: left;
}
#l:before {
float: right;
}
#r {
float: right;
}
#r:before {
float: left;
}
Related
I have this code:
<nav>
<div class="slider" id="slider"></div>
<div class="titleGroup">
<h2 onclick="selectArticles()" id="articlesButton" class="active">Articles</h2>
<h2 onclick="selectSocial()" id="socialButton">Social</h2>
</div>
</nav>
I need to make the slider appear on top of titleGroup but under its h2 childs, is there a way to do it using javascript? Making the h2s appear on top of everything would work too.
I tried doing it with z-index but obviously it doesn't work because z-index is relative to the parent.
Since you asked for JavaScript solution... you can prepend it to be the first child of the .titleGroup. But of course a better approach would have been to fix the HTML or try with z-index.
titleGroup.prepend(slider)
.titleGroup {
background: red;
height: 150px;
}
h2 {
position:relative;
background: black;
}
.slider {
opacity: 0.5;
background: yellow;
height: 100px;
width: 100%;
position: absolute;
}
<nav>
<div class="slider" id="slider">I am slider</div>
<div class="titleGroup" id="titleGroup">
<h2 onclick="selectArticles()" id="articlesButton" class="active">Articles</h2>
<h2 onclick="selectSocial()" id="socialButton">Social</h2>
</div>
</nav>
It's actually possible to solve your current problem using z-index and no JavaScript
(assuming you're not doing something funny with your titleGroup).
nav{
position:relative;
}
.titleGroup {
background: red;
height: 150px;
border: 1px solid yellow;
}
#slider{
z-index:1;
position: absolute;
top: 5px;
background: green;
color: white;
height: 80px;
left: 5px;
width: calc(100% - 10px);
padding: 5px;
box-sizing: border-box;
}
#slider::before{
content: "Slider in front of titleGroup background, but behind h2"
}
h2 {
position: relative;
background: cyan;
z-index: 2;
}
<nav>
<div class="slider" id="slider"></div>
<div class="titleGroup" id="titleGroup">
<h2 onclick="selectArticles()" id="articlesButton" class="active">Articles</h2>
<h2 onclick="selectSocial()" id="socialButton">Social</h2>
</div>
</nav>
Note that .titleGroup has no special value for position (or z-index for that matter), so no new stacking context is created.
(And if a css statement somehow affects your titleGroup element’s position property, you can use position:unset or position:static)
More about stacking context: Link1 (The stacking context
)
The following has an example where elements that are not siblings can be controlled just using z-index: Link2 (Stacking context example 1
)
In my example, h2 and #slider are not siblings, but since .titleGroup has no stacking context, in effect the behavior of z-indexes is comparable that of siblings.
Also note that this fails if your .titleGroup has opacity value less than 1, as it creates a new stacking context, and similarly if you have a special filter, etc. (described in the first link).
I am trying to create an effect that when you roll over an image a pointer will point towards it. The same as used in this website about half way down: https://thecleansekitchen.com.au/
I'm not sure where to begin or if there are any JQuery or plugins out there for this but I cant find any?
Any help appreciated.
I'm sure there are some jQuery plugins out there that do this but that's probably unnecessary. You can accomplish this pretty easily with some basic HTML, CSS and JavaScript.
I created a JSFiddle to try to help you get started. https://jsfiddle.net/x823m6ff/
Note that the above is very crude and you'll definitely need to massage it for your needs but hopefully it will help you start down the right path.
I'll lay out the code here as well to explain.
HTML:
<div class="container">
<div class="block">
<div class="arrow arrow-down"></div>
</div>
<div class="block">
<div class="arrow arrow-down"></div>
</div>
<div class="block">
<div class="arrow arrow-down"></div>
</div>
</div>
For the HTML, I created a container with three blocks (like your screenshot). Each block has a child arrow element that is hidden through CSS.
CSS:
.container {
width: 960px;
margin: 0 auto;
}
.block {
width: 100px;
height: 150px;
background-color: #000;
float: left;
margin-right: 20px;
position: relative;
}
.arrow {
display: none;
position: absolute;
top: 0;
left: 25%;
}
.arrow-down {
width: 0;
height: 0;
border-left: 25px solid transparent;
border-right: 25px solid transparent;
border-top: 25px solid #FFF;
}
The CSS sets up some widths and heights for our blocks and creates the arrow elements. We're positioning these arrow elements relative to each block and putting them at the top middle of each block.
JavaScript:
$(document).ready(function() {
$('.block').hover(function() {
$(this).find('.arrow').show();
}, function() {
$(this).find('.arrow').hide();
});
});
The above JavaScript is very simple and basically just listens for a mouse hover over our block and shows / hides our arrow depending on the state of the user's mouse over the block.
I've been experimenting with a way to get a page element to overlap the elements on either side of it and stay perfectly centered between them. My solution was to declare position:relative and set negative margin values roughly equal to 50% of the element's width, but the closest I've been able to come is to half the element's percentage of its parent's width:
<!DOCTYPE html>
<html>
<head>
<style>
.clap {
position:relative;
margin:auto -16.66%; // This element's share of the entire parent's width = 33.33%
color:#f00
}
</style>
</head>
<body>
<center>
<span style="display:inline-block">1234567890<span class="clap">1234567890</span>1234567890</span>
</center>
</body>
</html>
I'm trying to find a CSS-only solution that will use the width of the element itself, not the width of the container. I can't use JavaScript to do this because I plan to use it as a MathJaX fix by embedding it in a \style command. (As far as I know, MathJaX does not provide for embedded HTML or JavaScript code within its formulas, so you see why this must be CSS-only. I know it's possible with scripting. Is it possible with CSS, or is my endeavor hopeless?
Update: Thanks to a suggestion from #Daiwei, I think I'm on the road to the right solution. Thanks for all your answers. Here is the revised code:
.clap {
position:absolute;
display:inline-block;
transform: translate(-50%,0);
color:#f00 // for contrast
}
I'd love to show you the results, but I can't upload a picture. Sorry.
Another update: The solution I presented above works best in an HTML/CSS context, but it breaks in a MathJaX array, matrix, or similar tabular environment. Specifically, if the element is too long, it clips on the left side. Relative positioning moves the element halfway to the left but leaves a gaping space where it used to be! Any ideas for patching it up?
One pure CSS solution is to use transform.
element
{
position: relative;
top: 50%;
transform: translateY(-50%);
}
Notes:
You can use top: 50%; for vertical and left: 50%; for horizontal.
You would then use translateY(-50%) for vertical and translateX(-50%) for horizontal centering.
You can also use this trick to align elements to the bottom or right of it's parent, like in a table-cell by using 100% instead of 50% in the css.
If you want to support older browsers, then you'll need to use prefixes for transform. I highly recommend autoprefixer in your workflow.
As the size of the element is only known after it has been styled, how should the style be able to use it? Imagine this: Some element has a width of 200% of it's own width (=double size than "normal") set in CSS. One of it's children has its width set to 100% of the parent (=our element). The default width of an element is determined by its content. Content's of our element are as width as the element itself. Our element has no width yet however, as we're waiting for it to get some default, so we can double that one. Result: Nothing will ever get any width.
Therefore: What you're trying to do is not possible. But CSS3 has its calc, maybe you can get closer to what you want to acheive using it?
I don't know if this is what you wanted to do, but here is a demo: http://cdpn.io/bgkDf
HTML
<div class="container">
<div id="box-left"></div>
<div id="box-overlap">
<div id="box-overlap-inner"></div>
</div>
<div id="box-right"></div>
</div>
CSS
.container > div {
height: 50px;
float: left;
}
#box-left {
width: 40%;
background-color: red;
}
#box-right {
width: 60%;
background-color: green;
}
#box-overlap {
width: 0;
}
#box-overlap-inner {
position: relative;
z-index: 10;
height: 50px;
width: 50px;
transform: translate(-50%,0);
background-color: rgba(0,0,255,.5);
}
"Using element's own width for calculation or percentage" In general:
(Maybe not the best solution for your issue, but an answer to your question)
At the moment,the attr function doesn't work in Chrome. That would have been nice.
But you can use variables, if you either set the parent attribute yourself, or are able to use a predefined one. That way you can use the calc() function to calculate your child attribute.
Here is an example, using the browser defined viewport size, to calculate the width of an element:
<!DOCTYPE html>
<html>
<head>
<style>
:root {
--module-size: 33vw;
}
.clap {
display:inline-block;
width: calc(var(--module-size) / 2);
color:#f00;
border: 1px solid;
}
</style>
</head>
<body>
<center>
<span style="display:inline-block">1234567890
<span class="clap">1234567890</span>
1234567890</span>
</center>
</body>
This can be used in many interesting ways, to streamline your CSS. For instance with the #media style...
And if someone (like me) was trying to center the element by its parent, use this simple style:
.clap {
position:absolute;
left: 50%;
transform: translate(-50%,0);
}
What about converting the content to divs and enclose each within another div to use
margin: auto
?
Example (each super div within its own colour and shifted a little in height for clarity):
<html>
<head>
<style>
.dl
{
position: absolute;
left: 0px;
top: 0px;
max-width: 50%;
width: 50%;
text-align: left;
background: red;
opacity: 0.5;
}
.dls
{
margin: auto;
}
.dc
{
position: absolute;
left: 25%;
top: 10px;
max-width: 50%;
width: 50%;
text-align: center;
background: green;
opacity: 0.5;
color: white;
}
.dcs
{
margin: auto;
}
.dr
{
position: absolute;
right: 0px;
top: 20px;
max-width: 50%;
width: 50%;
text-align: right;
background: blue;
opacity: 0.5;
color: white;
}
.drs
{
margin: auto;
}
.overall-width
{
position: absolute;
left: 0%;
width:100%;
height: 20px;
margin: auto;
}
</style>
</head>
<body>
<div class="overall-width">
<div class="dl">
<div class="dls">
1234567890
</div>
</div>
<div class="dc">
<div class="dcs">
1234567890
</div>
</div>
<div class="dr">
<div class="drs">
1234567890
</div>
</div>
</div>
</body>
</html>
I am in a corner with this one. I have a layout with 2 containers. One of the containers represents a map (#main) and needs to stay in user view at all times, the other one (#sub) serves as a scroll-able content. Everything looks fine if content fits horizontally. However as soon as the horizontal bar appears (resize the window to replicate), the scroll-able content overlaps the fixed content and I am out of ideas how to fix it. I know of one way to fix it by positioning the fixed content absolutely instead and useing javascript to adjust its position from the top. Is there any way to fix it?
Sample code is below:
Html:
<div id="content">
<div id="main">main</div>
<div id="sub">
<strong>Sub</strong><br />
sub<br />
sub<br />
sub
</div>
</div>
Css:
#content {
width: 1200px;
margin: 0 auto;
}
#main {
position: fixed;
width: 849px;
height: 500px;
background: red;
}
#sub {
position: relative;
float: right;
width: 350px;
height: 3500px;
background: green;
}
JSFiddle link
Based on your comments it sounds like not allowing the user to scroll will solve the issue:
body {
padding: 0;
margin: 0;
overflow-x:hidden;
}
If you want them both to scroll you have to remove the fixed positioning:
#main {
position: relative;
width: 849px;
height: 300px;
background: red;
font-size: 50px;
text-align: center;
padding-top: 200px;
float:left;
}
I have a page that has 2 columns. The first column is a dynamic width. It contains a bunch of tabular data in tables. The 2nd column is a fixed width full of navigation stuff.
The 2 columns are divs with float left. I need to accomplish 2 things.
I need to center the 2 divs on the page. For example, if the first div is 600px wide as dictated by the data inside of it and the second div is a fixed 200px, the centering point is 400px.
I don't want the 2nd div to wrap down if the browser window is resized.
I'm thinking that I may have to nest the 2 divs inside of another div, set the parent div width using javascript, then center it.
I created this fiddle to help illustrate. http://jsfiddle.net/darthg8r/uhKdt/
Surround them with a div and set its style to:
width: ( whatever you need )
margin: 0 auto; // this centers the div
You can set the width dynamically with JavaScript if needed. As long as it's smaller than 100% of the surrounding container, it will stay centered.
You could achieve this with the following code:
HTML:
<div id="wrapper">
<div id="container">
<div id="variable">test</div>
<div id="fixed">test</div>
</div>
</div>
CSS:
#wrapper { overflow: hidden; }
#container {
float: left;
position: relative;
left: 50%; }
#container > div {
float: left;
position: relative;
right: 50%;
height: 300px; }
#variable {
background: red;
width: 300px; }
#fixed {
background: blue;
width: 200px; }
Preview: https://jsfiddle.net/Wexcode/mreLt/
You could also achieve this effect by wrapping the two elements in a container, setting them both to display: inline-block, and finally setting their container to have text-align: center.
The answer is a little more complicated than this, so let me know if you want to choose this route instead.
To make it so the elements don't fall to the next line, use inline-block.
<div id="container">
<div id="variable">
<p>test</p>
</div><div id="fixed">
<p>test</p>
</div>
</div>
CSS:
body { margin: 0; }
#container {
color: #fff;
text-align: center;
white-space: nowrap; }
#container > div {
height: 300px;
display: inline-block; }
#variable {
background: red;
width: 100px; }
#fixed {
background: blue;
width: 200px; }
Preview: https://jsfiddle.net/Wexcode/mreLt/2/