is CSS-only, full-width sidebar background possible? - html

I'm building a fixed width website (using the classic wrapper with margin:auto), but I want the sidebar background to extend to the right end of the screen.
So far I've accomplished this:
HTML
<div id="wrapper">
<div id="left">Content area</div>
<div id="right">
<div id="actual-sidebar">
Sidebar
<span class="clearme"></span>
</div>
</div>
</div>
CSS
body {
background: #333;
color: #fff;
overflow-x: hidden;
}
#wrapper {
width: 500px;
height: 1200px;
margin: auto;
border: 2px dashed #fff;
}
#left {
width: 300px;
height: 500px;
float: left;
}
#right {
width: 175px;
height: 500px;
margin-left: 325px;
margin-right: -9999px;
padding-right: 9999px;
background: #777;
}
#actual-sidebar {
width: 100%;
height: 100%;
border: 2px dotted #f0f;
}
​
You can see it in action here:
http://jsfiddle.net/knjDV/
http://www.spazionegativo.it/layout-test/
Is this kind of "full-width sidebar" possible using css only?
In the example above, the actual sidebar width is highlighted by the pink border, and the rest is all padding and negative margin; worked in chrome but IE broke it so I've added overflow-x: hidden to fix it.
The problem is, click-dragging to the right will scroll the view even if there's nothing to select, eventually hiding the content. I can't seem to get past this problem.
Is there a fix to the "drag-n-scroll" issue, or an entirely different way to accomplish this?

If you add to #right{ position: fixed;} that will get rid of the horizontal scrollbar. Is that acceptable?

Use CSS3 gradients as a background for the body (with the same color as the sidebar) to create the illusion that it extends to the edge of the screen.
.sidebar {
background: salmon;
}
body {
background: -webkit-gradient(linear, 100% 50%, 0% 50%, color-stop(50%, #fa8072), color-stop(50%, #ffffff));
background: -webkit-linear-gradient(right, #fa8072 50%, #ffffff 50%);
background: -moz-linear-gradient(right, #fa8072 50%, #ffffff 50%);
background: -o-linear-gradient(right, #fa8072 50%, #ffffff 50%);
background: linear-gradient(right, #fa8072 50%, #ffffff 50%);
}​
Demo

Related

Weird artefact showing behind only one of before/after pseudo selector in my breadcrumbs

I am trying to create 3 section breadcrumbs type element with an arrow divider. This is a simple mockup.
There is a weird artefact showing between section 2 and 3. In this case section three's red background is visible (slightly) to the left of the blue arrow of section 2, however the same problem doesn't occur with section 2's background interfering with section 1 arrow. thankfully but weirdly. For me this is only happening on Chrome for Mac too (the browser window isn't zoomed in/out either). Haven't tested Windows etc. Any suggestions as to how to fix this bizarre issue?
A zoomed up view of the weird artefact (the red vertical line) occurring between section 2 and 3:
No such weird artefact occurs between section 1 and 2.
The codepen:
https://codepen.io/reacting/pen/xeewdO
The html:
<div class="container">
<div class="section">section one</div>
<div class="section two">section two</div>
<div class="section">section three</div>
</div>
The css/scss:
.container {
background-color: white;
border: 1px solid grey;
box-sizing: border-box;
width: 100%;
display: flex;
}
.section {
flex: 1;
position: relative;
height: 100px;
background-color: black;
color: white;
display: flex;
justify-content: center;
align-items: center;
&:before {
content:"";
background-color: grey;
-webkit-clip-path: polygon(0% 100%, 100% 50%, 0% 0%);
clip-path: polygon(0% 100%, 100% 50%, 0% 0%);
z-index: 1;
position: absolute;
right: -26px;
top: 0;
width: 25px;
height: 100px;
}
&:after {
content:"";
background-color:black;
-webkit-clip-path: polygon(0% 100%, 100% 50%, 0% 0%);
clip-path: polygon(0% 100%, 100% 50%, 0% 0%);
z-index: 2;
position: absolute;
right: -25px;
top: 0;
width: 25px;
height: 100px;
}
&:last-of-type {
background-color: red;
color: black;
}
&:last-of-type:before {
display: none;
}
&:last-of-type:after {
display: none;
}
&.two {
background-color: blue;
&:after {
background-color: blue;
}
}
}
body {
background-color: #333;
}
I don't just want to change the right: attribute of the before/after pseudo selectors to be less 1 pixel as that just feels hacky and wrong.
Many thanks!
Edit: I wonder if the issue is related to the high resolution of my Mac display - as when I resize the chrome browser window slightly the problem comes and goes and changes to occur for section 1/2 or both section 1/2 and 2/3 or none. depending on the size of the browser window. But strangely in Firefox and Safari this doesn't occur when dragging the window at all.
You can optimize the code and consider clip-path on the element without the need of pseudo element then consider some background coloration to simulate the border
.container {
background-color: white;
border: 1px solid grey;
box-sizing: border-box;
display: flex;
height: 100px;
}
.section {
flex: 1;
color: white;
display: flex;
justify-content: center;
align-items: center;
margin-left:-25px; /* Create an overlap with the previous element */
/* the clip path (note the 25px that is the same as margin*/
-webkit-clip-path: polygon(100% 0, 100% 50%, 100% 100%, 0% 100%, 25px 50%, 0% 0%);
clip-path: polygon(100% 0, 100% 50%, 100% 100%, 0% 100%, 25px 50%, 0% 0%);
/* the border (note the 25px in the gradient)*/
border-left:3px solid grey; /* this will push the background and control the thickness of the border*/
background:
linear-gradient(to top right, grey 48%,transparent 50%) top left /25px 50%,
linear-gradient(to bottom right, grey 48%,transparent 50%) bottom left/25px 50%;
background-repeat:no-repeat;
background-color: black;
}
.section:last-of-type {
background-color: red;
color: black;
}
.section:first-of-type {
/* Remove everything from the first element */
clip-path:none;
margin-left:0;
border-left:0;
background:black;
}
.section.two {
background-color: blue;
}
body {
background-color: #333;
}
<div class="container">
<div class="section">section one</div>
<div class="section two">section two</div>
<div class="section">section three</div>
</div>

Two triangles to make a rectangle

I am trying to get two triangles to make a rectangle. I then want to put content into each triangle. I am following a previous question's answer from here: Previous Question.
My issue is that I cannot get the rectangle to be width: 80vw without the height being massive. Then, I am not sure how I can put content into an after element or if this is even the best way to design this knowing that I will be putting content into the triangles.
Does anyone know how I can do this or have any better solutions?
#tierBoxSec {
position: relative;
height: auto;
width: 100%;
}
.box {
width: 80vw;
height: 200px;
background: radial-gradient(at top left, #FFF 49%, #b82222 50%, #b82222 100%);
}
<section id="tierBoxSec">
<div class="box"></div>
</section>
I've made a snippet better illustrating how to do this with linear gradients:
red 50%, blue 50% is setting a "color stop" of 50% for each color, meaning they won't continue past 50% of the gradient area. You could create different demarcation lines by doing something like red 25%, blue 25%, for example.
#box {
width: 100px;
height: 100px;
background: linear-gradient(45deg, red 50%, blue 50%);
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient -->
<body>
<div id="box">
</div>
</body>
Here is an improvement for the linear-gradient solution to have a responsive block:
.box {
width: 80vw;
height: 80vh;
background: linear-gradient(to top right, red 49.9%, blue 50.1%);
}
<div class="box"></div>
Here is a solution using borders and box-sizing:
#box {
height: 8vh;
width: 80vh;
box-sizing: border-box;
background: red;
border-style: solid;
border-width: 8vh 80vh;
border-color: blue red red blue;
}
<div id="box"></div>
⋅
⋅
⋅
If you really want two distincts triangles, here is a "forked" solution of the above, using the ::after pseudo-element :
#box {
position: relative;
height: 8vh;
width: 80vh;
box-sizing: border-box;
border: solid transparent;
border-width: 8vh 80vh;
border-top-color: blue;
border-right-color: blue;
}
#box::after {
position: absolute;
content: '';
border: solid transparent;
border-width: 8vh 80vh;
border-bottom-color: red;
border-left-color: red;
transform: translate(-50%, -40%); /* Change -40% to -50% if you want the two triangle to stick */
}
<div id="box"></div>
<br>
(I've let a space just to show you)
Hope it helps.

CSS diagonal div background

For a website I'm developing I need to include some diagonal shaped borders to a div. These are the main examples which I need to recreate.
double diagonal top border, triangle shaped
Now been scouting the web on how to achieve this, and my first thought as well would be by using ::before. However I can't get it to work without it being positioned absolute which messes up the entire page.
This is my code I have tried to achieve something like this:
.slider-container{
background-color: $blue;
width: 100%;
overflow: hidden;
position: relative;
.col-md-3{
img{
padding: 40px;
width: 100%;
max-width: 400px;
margin: auto;
}
}
&::before {
background: red;
bottom: 100%;
content: '';
display: block;
height: 100%;
position: absolute;
right: 0;
transform-origin: 100% 100%;
transform: rotate(-15deg);
width: 150%;
}
}
<section id="slider">
<div class="container-fluid">
<div class="row slider-container">
<div class="col-md-3">
<p>imgae 1</p>
</div>
<div class="col-md-3">
<p>imgae 2</p>
</div>
<div class="col-md-3">
<p>imgae 3</p>
</div>
<div class="col-md-3">
<p>imgae 4</p>
</div>
</div>
</div>
</section>
Note: it won't work in here but this is the result I get result
With just css and a bit tweaking based on your divs size you could create something like this:
.myclass {
width: 100px;
height: 100px;
background: linear-gradient(45deg, black 0%, black 26%, transparent 26%), linear-gradient(-45deg, black 0%, black 27%, transparent 27%)
}
.myclass2 {
width: 100px;
height: 100px;
background: linear-gradient(-45deg, blue 0%, blue 27%, transparent 27%), linear-gradient(45deg, blue 0%, blue 26%, red 26%)
}
With transparency:
<div class="myclass">My content here</div>
<br/>
Not as easy with transparent:
<div class="myclass2">My content here</div>
Edit: Just tested this in chrome, you might need special linear-gradients for older/other browsers.
The most simple way to achieve this would probably be to use a background image, though the effect may prove to be inconsistent on smaller devices. For this reason, you may want to consider using a hard-stop gradient.
.grad {
background: lightblue; /* For browsers that don't support gradients */
background: -webkit-linear-gradient(170deg, white 0%, white, 15%, lightblue 15%, lightblue 100%);
background: -o-linear-gradient(170deg, white 0%, white, 15%, lightblue 15%, lightblue 100%);
background: -moz-linear-gradient(170deg, white 0%, white, 15%, lightblue 15%, lightblue 100%);
background: linear-gradient(170deg, white 0%, white, 15%, lightblue 15%, lightblue 100%);
width: 100%;
padding: 20px;
}
<div class="grad">
<h1>Hard-stop gradient</h1>
<p>Using this type of gradient, you can create an angled background without using a background image.</p>
</div>
Using this, you can create a gradient from 0% to 15% that is white on both ends, followed by a gradient from 15% to 100% that's fully black. This completely removes the fading effect, giving you your angled background. It's probably the most efficient way as well since it only requires one line of CSS.
Something like this?
div {
background: yellow;
height: 150px;
overflow: hidden;
position: relative;
width: 300px;
}
div::before {
background: red;
bottom: 100%;
content: '';
display: block;
height: 100%;
position: absolute;
right: 0;
transform-origin: 100% 100%;
transform: rotate(-15deg);
width: 150%;
}
<div></div>
You can use clip-path.
body {
margin: 0;
padding: 0;
color: #ffffff;
}
.wrapper {
min-height: 100vh;
min-width: 100vw;
max-width: 100vw;
width: 100vw;
background-color: red;
}
.bg {
min-height: 100vh;
min-width: 100vw;
background-color: blue;
clip-path: polygon(80% 0, 100% 0, 100% 100%, 50% 100%);
}
<div class="wrapper">
<div class="bg"></div>
</div>
For me, the linear-gradient is not smooth ...
I would suggest either clip-path or svg:
svg {
display: block;
width: 100%;
height: 55px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 10" preserveAspectRatio="none">
<polygon points="100 0 100 10 0 10" fill="white" />
</svg>
.arrow-right {
width: 0;
height: 0;
border-top: 60px solid green;
border-bottom: 60px solid transparent;
border-left: 60px solid green;
}

CSS: Colored div with transparent box [duplicate]

This question already has answers here:
turning a div into transparent to see through two containers
(4 answers)
Closed 6 years ago.
Is there any way to have a div with a background-color that takes up 100% width and a transparent box inside it that shows the original background?
Solution 1: Clip-path
Clip path can be quite useful, as it keeps the code clean and simple. However, it does not have great support (yet) in browsers, and should hence only be used in test environments.
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
height: 300px;
width: 100%;
background: tomato;
position: relative;
-webkit-clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0, 50% 0, 50% 20%, 80% 20%, 80% 80%, 20% 80%, 20% 20%, 50% 20%, 50% 0);
}
<div>
</div>
Solution 2: Box shadow Trick
The box shadow trick uses a pseudo element and overflow:hidden; to create the box shadow/colouring of the element.
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
height: 300px;
width: 100%;
overflow:hidden;
position: relative;
}
div:before{
content:"";
position:absolute;
top:20%;width:60%;height:60%;left:20%;
box-shadow:0 0 0 999px tomato;
}
<div></div>
Solution 3: Gradients
You could use multiple gradient background, however this may or may not be suitable as gradients don't always turn out rendered very nicely:
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
position: relative;
height: 300px;
width: 100%;
background: linear-gradient(tomato, tomato), linear-gradient(tomato, tomato), linear-gradient(tomato, tomato), linear-gradient(tomato, tomato);
background-size: 100% 20%, 20% 100%, 100% 20%, 20% 100%;
background-position: left bottom, right bottom, left top, left top;
background-repeat: no-repeat;
}
<div></div>
Solution 4: Borders
Whilst this may or may not be suitable for you, there is still a chance that it may help, so will post here anyway:
html {
background: url("http://butlers-web.co.uk/Content/Images/BWLOGO.png") 100% 100%;
}
div {
position: relative;
height: 300px;
width: 100%;
box-sizing: border-box;
border-left: 20vw solid tomato;
border-right: 20vw solid tomato;
border-top: 50px solid tomato;
border-bottom: 50px solid tomato;
}
<div></div>
Solution 5: Background attachment
I have recently come across the background-attachment property, so am still coming to grips with it. However, if you wished the background to appear behind you may be able to alter the below snippet to your needs:
body {
background: url('http://butlers-web.co.uk/Content/Images/BWLOGO.png');
background-attachment: fixed;
}
.wrapper {
width: 100%;
height: 300px;
background: tomato;
position: relative;
}
.inner {
width: 80%;
height: 80%;
background: url('http://butlers-web.co.uk/Content/Images/BWLOGO.png');
background-attachment: fixed;
position: absolute;
top: 10%;
left: 10%;
box-sizing:border-box;
border:2px solid black;
}
<div class="wrapper">
<div class="inner"></div>
</div>
You're going to need two div for that. A parent, with the red background, then the inner div.
give the inner div margin: 10px auto; as a start.

linear-gradient (arrow/triangle) works only in google chrome

This is what I have tried:
http://codepen.io/helloworld/pen/DkgbF
PLEASE use google chrome to watch the pen because in chrome v28 the linear-gradient (white triangle/arrow) works but it works NOT in IE10 or FF22 or Safari 5.1.7 on windows.
This way it looks in google chrome:
Why does it work only in google chrome?
<ul class="_7/5Z" style="display: table; height: 100%; float: left; font-size: 7px;background:green;">
<li style="list-style: none;background:blue; display: table-row;">
<div style="height: 99%;padding-left:1%;padding-top:1%;">
<div style="background: red; width: 50%; height: 100%; float: left;">
<div style="height: 100%;" class="segmentTriangle"></div>
</div>
<div class="fontsize vertical-center" style="font-size:20px;height: 100%; background: yellow; width: 50%; float: left;">33333
</div>
</div>
</li>
</ul>
body, html {
width: 100%;
height: 100%;
font-family: arial;
/*overflow: hidden;*/
}
* { /* Every element which has a border or padding value puts this value inside the div */
box-sizing: border-box;
-moz-box-sizing: border-box;
padding: 0;
margin: 0;
}
._7\/5Z {
width: 17.50%;
}
.horizontal-right {
text-align: right;
}
.horizontal-center {
text-align: center;
}
.vertical-center {
vertical-align: middle;
}
.segmentTriangle {
width: 100%;
height: 100%;
left: 0px;
top: 0px;
background: linear-gradient(to right bottom, white 50%, transparent 50%);
background: -o-linear-gradient(to right bottom, white 50%, transparent 50%);
background: -moz-linear-gradient(to right bottom, white 50%, transparent 50%);
background: -webkit-linear-gradient(to right bottom, white 50%, transparent 50%);
background: -ms-linear-gradient(to right bottom, white 50%, transparent 50%);
}
UPDATE
More information:
I am using knockoutjs for data-binding data to html. Now imagine my ul-tag has a foreach-binding and everything inside the ul that means every li-tag and its content is repeated 7 times because thats my requirement. I have updated my init question with a code sample that you understand better. Just use my code and make 7 copies of the li-tag and its content and paste all this inside the ul-tag to imitate a foreach loop then you will see that your latest display:table-cell workaround breaks everything. Hope that helps. :)
See this sample: http://codepen.io/helloworld/pen/gfeqK