I'm trying to create a responsive triangle div which will sit at the top of the page as a header.
I was able to achieve that with the following code:
div{
width: 0;
height: 0;
border-style: solid;
border-width: 200px 400px 0 0;
border-color: #007bff transparent transparent transparent;
}
<div></div>
The problem is that I want this triangle to be responsive to the width of the page and change proportionally in height as well.
I tried setting width and height to percent based, however that produced a really small triangle which you can see here:
http://jsfiddle.net/Ltbzkq0e/1/
How to make the borders work with percent without having to use webkits? Is that possible, if not how do I achieve this effect with webkits?
EDIT:
I would also like to fit content in this div. At the moment the only way I can think of is to use absolute positioning and set height to -20px, etc... Is there a better way of accomplishing this?
You can use transform-rotate and a pseudo element to create a responsive triangle. This technique is detailed here : CSS triangles with transform rotate.
For your specific case it could look like this :
DEMO
.tr{
padding-bottom:30%;
position:relative;
overflow:hidden;
}
.tr:before{
content:'';
position:absolute;
top:0; left:0;
width:120%; height:100%;
background-color : #0079C6;
-webkit-transform-origin:0 100%;
-ms-transform-origin:0 100%;
transform-origin:0 100%;
-webkit-transform: rotate(-17deg);
-ms-transform: rotate(-17deg);
transform: rotate(-17deg);
}
.content{
position:absolute;
}
<div class="tr">
<div class="content"> ... CONTENT HERE ...</div>
</div>
If you need IE8 support, you will need to use a JS fallback. This answer describes a way to achieve it.
if you don't care about IE8 and recent Android support — and since you need to have border-width proportional to the page size — you can use viewport-based (vw and vh) units
e.g.
border-width: 100vw 100vh 0 0;
example fiddle: http://jsfiddle.net/swbfqemr/
Related
Demonstration Link: https://codepen.io/jodriscoll/pen/wRpQOw
I'm working on a "sidewards blind-like" animation behavior, where when a user hovers over an object (anchor), it expands the object (anchor) in width and creates a perception of showing more of the objects contain within (think of a clipping mask of sorts).
Initially the video/image object is styled in a way to prevent it from moving 1:1 with the "clipping mask" (anchor wrapping the video/image). Meaning, it is already offset to the position it should be when the user hovers over the anchor.
Both the image and the video are initially styled to fill the entirety of the anchor AND the gutter gaps; this helps when animating to create the perception that we're just showing more of the photo, no actually resizing it and causing it to move on screen (sorry, that might be confusing...):
left: -24px; // the width of each gutter gap
width: calc(100% + 48px); // fill the parent + fill the gutter gaps
When the user hovers over the anchor, the child elements change their CSS specs to:
left: 0; // stay flush with the anchor object
width: 100%; // fill the parent, which now includes the gutter gap(s)
Everything appears to work correctly when viewing the animation behaviors on Chrome / Safari / Firefox:
http://svg-gmmb-cis.pantheonsite.io/wp-content/uploads/2019/01/debugging_animations.mp4
Unfortunately, there is a slight hiccup on IE11/Edge:
http://svg-gmmb-cis.pantheonsite.io/wp-content/uploads/2019/01/IE_animation_bug.mp4
Questions and hopeful helpful insight towards reaching an answer:
After viewing the animation glitch, does IE11/Edge have issues with animating CSS measures using calc()?
Do I need to create a CSS animation with keyframes to remedy this hiccup in IE11/Edge?
Am I approaching this wrong and should be animating different properties?
You can do this easily with margin and avoid the use of calc.
Here is a simplified example:
.container {
border:1px solid;
padding: 0 24px;
height:100px;
}
.box {
height:100%;
background:red;
transition:.5s all;
}
.box:hover {
margin:0 -24px;
}
<div class="container">
<div class="box"></div>
</div>
Or like this:
.container {
border:1px solid;
margin: 0 24px;
height:100px;
}
.box {
height:100%;
background:red;
transition:.5s all;
}
.box:hover {
margin:0 -24px;
}
<div class="container">
<div class="box"></div>
</div>
I have an image:
with 3 parts:
, and
I want a button with a repeating part2, so the button text (centered) is variable.
But the button text should range 50% into the other pieces.
Part1 and part3 need a min width I think, unfortunately I have no useful example.
:before and :after didn't work very well (with position:absolute or similar), because the repeat part have to be fluid between the outer parts.
Any ideas? Greetz.
A modern posibility would be using border-image.
But if you want a wider support, do it with backgrounds.
The problem is that a repeating bkg is difficult to size . So, it's best to handle it in a pseudo element
.test {
min-width: 200px;
text-align: center;
line-height: 90px;
display: inline-block;
margin: 20px;
height: 100px;
padding: 0px 20px;
font-size: 30px;
color: white;
background-image: url('//i.stack.imgur.com/mYxcX.png'), url('//i.stack.imgur.com/TlpN0.png');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top, right top;
position: relative;
}
.test:after {
content: "";
position: absolute;
background-image: url('//i.stack.imgur.com/GMhMi.png');
background-size: auto 100%;
left: 90px;
right: 100px;
top: 0px;
bottom: 0px;
z-index: -1;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
And the same, using border image. Using this image
we will get this: (note the trick about height:0px to allow for a single image in all the left and right sides.)
.test {
display: inline-block;
margin: 20px;
height: 0px;
font-size: 30px;
border-width: 50px;
border-image-source: url(http://i.stack.imgur.com/oXiA6.png);
border-image-slice: 50% 49% 50% 50% fill;
border-image-repeat: repeat repeat;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
UPDATED and totally Changed:
Thanks to #vals comment below which let me had the "idea bulb" above my head, hence the "unless.." part in the comment.
This new solution is much cleaner in CSS and HTML, less code, no need to worry about position:absolute, no need for extra mess, just simply uses "multiple backgrounds" (1) as well as calc()(2) function with min-width too techniques. but first here's the code and comments will explain:
JS Fiddle
.test-class {
/* so that div can expand to contain the text as well as the padding */
width:auto;
/* min width = 173px left image width + 199px right image width */
/* without this it'll collapse */
min-width:372px;
padding:0 20px 0 10px; /* just to give it breathign space on sides */
line-height: 148px;
color: white;
font-size:24px;
/* no color background because the images are PNGs with alpha */
background-color: transparent;
/* setting multiple images having the middle "extendable" one as third background */
background-image: url('//i.stack.imgur.com/mYxcX.png'),
url('//i.stack.imgur.com/TlpN0.png'),
url('//i.stack.imgur.com/GMhMi.png');
/* set no repeat to all, even the extendable otherwise it'll appear behind the
other two images, instead we don't repeat it but control its size later */
background-repeat: no-repeat, no-repeat, no-repeat;
/* position each image to its corresponding position, the 46.5% for the middle
image is because the left-side image has less width than the one on the right */
background-position:left center, right center, 46.5% 50%;
/* finally giving the images on the sides their exact-pixel size, while for the
one on the middle we make use of calc() function, so the width size of the middle
image = full div size (100%) - the width values of the left and right image (173+199) */
background-size: 173px 148px, 199px 148px, calc(100% - 372px) 148px;
display: inline-block;
text-align:center;
}
<div class="test-class">Home</div>
<div class="test-class" style="margin-left:200px;">about company</div>
<div class="test-class">example dummy text for demo only</div>
Alternatively, as I commented, you can use the CSS Sliding Door technique which was so practical and used a lot before CSS border-radius and CSS shadow presented and simplified interfaces. another example perfect CSS sprite sliding doors button
This JS Fiddle 2 shows how to implement the sliding door method for achieving such task, while it looks kind too much wide for this images set, since the right side image has 199px width, it could be used for images with less width values.
And this JS Fiddle 3 is similar to sliding door but with :before and :after but with one issue that it has to have display:block which make it not workign for horizontal alignment but could be fixed with javascript after settign it's display to inline-block.
Also there's another way, using SVG as background image which is better first because it is scale-able especially for non linear images like the blue ink circle used in the great example by #vals .
Second benefit of using SVG is using inline SVG and because SVG is made of groups and element could be targeted with CSS just like targeting other DOM elements.
https://css-tricks.com/using-svg/
----------------------------------------------------------------------------
(1). Resources:
caniuse - Multiple backgrounds
MDN - Using CSS multiple backgrounds
(2). Resources:
caniuse CSS calc()
MDN - calc()
CSS-Tricks - A couple of use cases for calc
I want a border on the right hand side of a div.
I do:
<div class="span6" style="border-right: 2px solid #727272;">
the things is I'd like my border not to run to the top and bottom of the div. Maybe 5px from the top and 5px from the bottom. Or 90% of the height of the div. How do I do this?
Thanks
You can use a pseudo element to hold the border. The following would make the "border" be 90% of the height of the parent element:
http://cssdeck.com/labs/kyrvt8hf
div {
position: relative;
}
div:after {
display: block;
content: '';
position: absolute;
top: 5%;
bottom: 5%;
right: 0;
border-right: 2px solid red;
}
I could be wrong, but I don't believe there is any way to really make this happen that you would probably want to roll with. In fact, I thought of three "hacky" ways that might work, but all three can't get you to the desired state, assuming a variable height.
Assuming a fixed height, you could create a 2px wide by 90% div height image of the color you want, then set it as the background image of the div. Something like:
.span6 { background: #fff url(bgBorder.png) no-repeat right center; }
Update
A variation based on what Tyblitz said in the comments. This allows for dynamic height. I am still inclined to go with the :after option, as it keeps your DOM cleaner, but in case that is not possible:
http://jsfiddle.net/designingsean/bsbgX/1/
HTML:
<div class="span6">The content div<div class="border"></div></div>
CSS:
.span6 {
width:50%;
height:400px;
background-color:#ddd;
position:relative;
padding:10px;
}
.border {
width:2px;
background-color:#222;
position:absolute;
top:5%;
bottom:5%;
right:0;
}
Note that to make it a fixed distance (say, in pixels), just change the top and bottom from a percentage to the px you want. See http://jsfiddle.net/designingsean/bsbgX/2/ for the example.
This picture show's how border's work
You can either set margin to curtail the border or set padding to extend the border. Currently there is no option in CSS to target the border and make it bigger or smaller(not talking about width obviously). You can however use padding, margin, another div or pseudo element's to reach the desired effect.
Hi I have two columns of content within a container, the first column has text and the second is a span with a background sprite image. The problem is when I get to smaller screen resolutions, I want the background sprite image to have a width in percentage to be able to scale it along with the H5 with a percentage width, is there a way to do this?
h5{
float:left;
display:block;
width:800px;
}
.sprite{
background-image: url("assets/img/website_sprite_a.png");
background-position: -60px -60px;
float:left;
display:block;
width:64px;
}
<div class="container">
<h5>Title
</h5>
<span class="sprite">
</span>
</div>
In your case I would go with a single background-image, but in the case you will have a lot of images or you really want to do this you can use the background-size property.
From MDN:
The background-size CSS property specifies the size of the background images. The size of the image can be fully constrained or only partially in order to preserve its intrinsic ratio.
.sprite{
background-image: url("assets/img/website_sprite_a.png");
background-position: -30% -30%; //use % instead pixels
float:left;
display:block;
width:64px;
background-size: 100%; //play with this
}
You also should read this:
Scaling background images
I have played a little bit with this on JSFIddle. Resize the browser to see the effect.
nearly a year too late, but I was trying to figure out the same and wasn't able to come up with or find a direct answer. After a little fooling around with multiple pieces of advice, I figured it out. Haven't had a chance to test this on IE8 yet, and stopped bothering with IE6/7, so please bear that in mind.
The trick I found is to use a combination of background-position (using percentages—of the sprite image—as mentioned before), padding-top (again, using percentages—this is the percentage of the total width of the sprite image), and background-size: cover.
Play around with it at jsfiddle.
#wrapper {
position: relative;
width: 100%;
}
.div {
position: absolute;
top: 0;
left: 0;
background-image: url('http://upload.wikimedia.org/wikipedia/en/2/2e/Sprite_logo.jpg');
background-repeat: no-repeat;
background-position: 0% 0%;
background-size: cover;
padding: 50% 0 0 0;
width: 40%;
}
<div id="wrapper">
<div class="div"></div>
</div>
I have a project where I am building slides described inside of an XML file but it requires to allow image positioning of the slides based on offset values.
Now I have Y offsets down pat, only problem now is that I require the ability to offset something in the X by an amount but still keep the %'age value behavior.
So basically is there anyway to have background-position's x start at 50% and then offset it by a pixel amount and keep the relative behavior of the %'age( 50% + offsetInPixels)?
You can do this, but it isn't widely supported.
background-position: -moz-calc(50% - 20px) 0;
background-position: calc(50% - 20px) 0;
Currently (May 2011) this only works in Firefox 4 and IE9.
See http://caniuse.com/#calc for compatibility.
You can't do that with plain CSS (at this point in time, see Rich Bradshaw's answer).
You could accomplish that in javascript with something like:
var totalWidth = 960;
var xOffset = 10;
el.style.backgroundPosition = ((totalWidth/2) + xOffset) +"px 50px";
I'd say your best bet is sticking the background image as an image inside the containter... It's bit of a hack, but it works Also, consider (As Jesse said) adding overflow:hidden if you don't want the bg pouring out.
<div id="main" >
<div id="bg"><img src="http://www.google.com/images/logos/ps_logo2.png"/> </div </div>
#main {
width:400px;
height:300px;
background-color:blue;
position:relative;
}
#bg {
margin-left: 10px;
position:absolute;
width:100%;
height:100%;
margin-left:50%;
}
demonstrated: http://jsfiddle.net/mhy3r/10/
I found another solution using CSS3. However, it requires the container to have a fixed size.
HTML:
<div id="example">Example</div>
CSS:
#example {
width: 200px;
height: 200px;
padding-left: 100px;
background-origin: content-box;
background-position: 10px 10%;
}
It's a bit of a hack I guess. Rather than starting the background-position from the left top corner of the border-box, it uses the content-box instead which has 50% (i.e. 100px) padding. Like I said, you will need to know the exact value of 50% padding because writing padding-left: 50%; will be interpreted as 50% of the parent element.
If you need the full space inside this container you can put another <div> into it with margin-left: -100px;