How to make a CSS shape with rounded and straight edges? - html

Desired Behaviour
I want to make this shape in CSS - it's a tab for a menu item.
[ example with text ]
The implementation scenario is an HTML template where CSS style sheets are switched to make color changes etc.
I want to use CSS to style the tab rather than background images so that I don't have to create a specific background image for each theme's version of a menu item tab.
What I've Tried
I looked around at some CSS shape sites and tried to pull them apart and adjust border widths etc, but haven't been able to get the desired result yet. Below are a few attempts.
.my_tab:before {
content: "";
position: absolute;
height: 0;
width: 0;
top: -45px;
left: 0px;
border-width: 0 105px 25px 0;
border-style: solid;
border-color: transparent transparent blue;
}
.my_tab {
position: relative;
width: 104px;
border-width: 20px 0 0 0;
border-style: solid;
border-color: red transparent;
top: 50px;
}
.my_tab_two {
background: purple none repeat scroll 0 0;
height: 22px;
position: relative;
top: 150px;
width: 104px;
}
.my_tab_two a {
color: white;
display: block;
font-family: arial;
margin: 0 auto;
text-align: center;
text-decoration: none;
width: 40px !important;
}
.my_tab_three {
background: green none repeat scroll 0 0;
border-radius: 0 5px 0 0;
height: 15px;
position: relative;
top: 113px;
width: 104px;
}
/* -------- */
p {
font-family: arial;
}
.para_two {
margin-top: 105px;
position: absolute;
}
<p>attempt 01:</p>
<div class="my_tab"></div>
<p class="para_two">attempt 02:</p>
<div class="my_tab_two">link
</div>
<div class="my_tab_three"></div>
<div class="my_tab_four"></div>
JSFiddle
http://jsfiddle.net/rwone/evz4d3mw/

You can create this by placing after and before pseudo-elements the after pseudo-element is skewed to make the slanted edges.
Note:This may not be the best solution i would suggest svg for this
.tab{
width:100px;
height:100px;
background:darkred;
border-top-left-radius:15px;
color:#fff;
position:relative;
padding:10px;
border-left:5px solid #000;
border-bottom:5px solid #000;
border-top:5px solid #000;
cursor:pointer;
}
.tab:after{
position:absolute;
content:"";
width:30%;
height:50%;
background:darkred;
right:-30%;
transform:skewY(45deg);
top:11%;
border-top:7px solid #000;
border-right:5px solid #000;
box-sizing:border-box;
}
.tab:before{
position:absolute;
content:"";
width:30%;
height:60%;
right:-30%;
background:darkred;
bottom:-5px;
border-bottom:5px solid #000;
border-right:5px solid #000;
box-sizing:border-box;
<div class="tab">Some text</div>
Svg solution
.tab {
width: 200px;
height: 200px;
}
<div class="tab">
<svg width="100%" height="100%" viewbox="0 0 100 100">
<path d="m5 5 l 75 0 15 15 0 60 -90 0 z" fill="darkred" stroke="#000" stroke-width="5"/>
</svg>

Related

I'm trying to create a broken horizontal line with arrows on either end and text in the middle

I'm trying to create a responsive horizontal line with arrows on either end and text in the middle. I found ways to create the line with the text in the middle using before and after, but I'm stumped as to how to incorporate the arrows on either end. Ideally I would like to use a font icon, but am willing to use a generic html arrow if necessary.
This way you can achieve it:
Have the image as background.
Center align the text.
Give the text some background colour, matching the parent background colour.
Snippet
h1 {
font-size: 15pt;
font-weight: normal;
text-align: center;
background: url("http://www.signsbypost.com/sites/default/files/irun/uc_product/images/SELF-ADHESIVE-VINYL-STICK-ON-ARROW-DOUBLE-HEAD-5271.jpg") center center no-repeat;
background-size: contain;
}
h1 span {
display: inline-block;
padding: 5px;
background-color: #fff;
}
<h1><span>Hello</span></h1>
Preview
Only using CSS without images.
.line {
margin-top:8px;
width:10%;
background:blue;
height:3px;
float:left;
position:relative;
}
.arrowed .text{
padding: 0 10px 0 10px;
}
.arrowed span{
float:left;
display:block;
}
.line.first:before {
content: '';
position: absolute;
right: 100%;
top: -3px;
display:inline-block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-right: 5px solid blue;
}
.line.second:after{
content: '';
position: absolute;
left: 100%;
top: -3px;
display:inline-block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid blue;
}
<p class="arrowed">
<span class="line first"></span>
<span class="text">Continuous Improvement</span>
<span class="line second"></span>
</p>

Incomplete borders around div

I am looking for a way to create an incomplete square with borders with some text and a background with pure css. Here is what I am trying to achieve:
My initial idea is to create the shape based on three shapes and then colorize the borders accordingly:
But I am a bit concerned about the adaptive version - scaling three shapes. So maybe a better idea, anyone?
You can do with css pseudo ::after and ::before , something like this
.incomplete-box{
border: solid 1px #fff;
border-right: none;
width: 100px;
height: auto;
position: relative;
}
.incomplete-box::after,
.incomplete-box::before{
content: '';
position: absolute;
height: 30%;
width: 1px;
background-color: #fff;
right: 0;
}
.incomplete-box::after{
top: 0;
}
.incomplete-box::before{
bottom: 0;
}
Demo
Fixed width and height : https://jsfiddle.net/nikhilvkd/qt5ne3yw/
Auto width and height: https://jsfiddle.net/nikhilvkd/0v3k8rv8/2/
You can do this with :before and :after pseudo elements
Complete design Fiddle
.square {
width: 200px;
height: 300px;
border-left: 1px solid gray;
border-bottom: 1px solid gray;
border-top: 1px solid gray;
position: relative;
}
.square:before, .square:after {
content: "";
height: 20%;
position: absolute;
right: 0;
border-right: 1px solid gray;
}
.square:before {
bottom: 0;
}
<div class="square"></div>
or SVG
line {
stroke: #6996FB;
stroke-width: 2;
}
svg {
overflow: visible;
}
button {
padding: 10px 50px;
border: none;
color: white;
margin-right: 10px;
margin-top: 15px;
}
.btn-blue {
background: #5D8CFF;
}
.btn-green {
background: #33F1D9;
}
h3 {
margin: 0;
}
<svg width="250" height="300" version="1.1" xmlns="http://www.w3.org/2000/svg">
<line x1="1" y1="1" x2="250" y2="1"></line>
<line x1="0" y1="300" x2="250" y2="300"></line>
<line x1="1" y1="1" x2="1" y2="300"></line>
<line x1="249" y1="0" x2="249" y2="70"></line>
<line x1="249" y1="230" x2="249" y2="300"></line>
<foreignobject x="60" y="90" width="400" height="180">
<body xmlns="http://www.w3.org/1999/xhtml">
<h3>Lorem ipsum dolor sit <br> amet, consectetur adipisicing elit. Suscipit</h3>
<button class="btn-blue">Btn 1</button><button class="btn-green">Btn 2</button>
</body>
</foreignobject>
</svg>
This approach allows you to:
add any content and the borders will adapt around it regardless of height or width of the content
support transparent background and can be displayed over an image or non plain colors
doesn't add any unsemantic elements
It relies on 2 absolutely positioned pseudo elements and one div. The spacing between the content and the borders is controlled by the padding on the div :
div{
position:relative;
display:inline-block;
padding:50px 100px;
border-left:1px solid #000;
text-align:center;
}
div:before, div:after{
content:'';
position:absolute;
right:50%; left:0;
height:50px;
border-right:1px solid #000;
}
div:before{
top:0;
border-top:1px solid #000;
}
div:after{
bottom:0;
border-bottom:1px solid #000;
}
body{background:url('http://i.imgur.com/3IXm5qm.jpg');background-size:cover;}
<div>
<h2>This is a very long title on<br/> 2 lines</h2>
<button>Button</button>
<p>Some text</p>
</div>
Well, go with the above answers, I recommend using pseudo elements to achieve this effect.
But There is another way to accomplish this without using
pseudo-elements.
Here is how you should do this.
.row{display:table;table-layout:fixed;}
.col{display:table-cell;}
.row{width:250px; margin: auto;}
.mid.row > .col{ height: 100px; }
.col{ text-align: center;}
.top.col, .bottom.col{
border-top: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
height: 50px;
}
.bottom.col{
border-top: 0;
border-bottom: 1px solid black;
}
.mid.row > .col{
border-left: 1px solid black;
border-right: 0;
vertical-align: middle;
text-align: right;
}
.mid.row > .col span{
margin-right: -30px;
max-width: 300px;
}
<div class="row">
<div class="top col"></div>
</div>
<div class="mid row">
<div class="col">
<span>Hey you can achieve this without using pseudo elements :)</span>
</div>
</div>
<div class="row">
<div class="bottom col"></div>
</div>
We can do this with linear-gradients. No SVG, no pseudo-element. I used some variables to control everything easily.
.container {
/* you can change these variables */
--border-color: #000;
--border-width: 2px;
--space: 100px;
width: 200px;
height: 300px;
position: relative;
background: linear-gradient(var(--border-color), var(--border-color)) 0 0/var(--border-width) 100%,
linear-gradient(var(--border-color), var(--border-color)) 0 100%/100% var(--border-width), linear-gradient(var(--border-color), var(--border-color)) 0 0/100% var(--border-width),
linear-gradient(var(--border-color), var(--border-color)) 100% 0/var(--border-width) calc(50% - (var(--space) / 2)),
linear-gradient(var(--border-color), var(--border-color)) 100% 100%/var(--border-width) calc(50% - (var(--space) / 2));
background-repeat: no-repeat;
}
.content {
position: absolute;
width: 200px;
top: 50%;
transform: translateY(-50%);
right: -100px;
background: yellow;
}
<div class="container">
<div class="content">
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
</div>
</div>

CSS design for cancel/cross

I am trying to design the following image
The following has been my attempt so far, but i am just not able to get the content "x" to reach the four corners of the div.
HTML
<div id="cancel">X</div>
CSS
#cancel{
float: right;
border: 1px solid yellow;
font-family: 'Helvetica', 'Arial', sans-serif;
font-weight: lighter;
font-size: 3em;
width: 10%;
text-align: center;
background-color: #d5d6da;
color: white;
width: 12%;
cursor: pointer;
}
The following image is the output i was to be get to so far
I'd use a bit of scale for it - and a pseudo element :
Example
#cancel {
width: 0.9em;
height: 0.9em;
position: relative;
font-family: helvetica, arial, sans-serif;
font-weight: lighter;
font-size: 3em;
color: white;
background-color: #d5d6da;
cursor: pointer;
}
#cancel:after {
content: 'X';
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%) scaleX(1.2);
transform: translate(-50%,-50%) scaleX(1.2);
}
Or without any fonts and full control over how it looks :
Demo
#cancel {
width: 40px;
height: 40px;
position: relative;
background-color: #d5d6da;
cursor: pointer;
}
#cancel:before, #cancel:after {
content: '';
width: 110%;
height: 3px;
position: absolute;
top: 50%;
left: 50%;
background: white;
}
#cancel:before {
-webkit-transform: translate(-50%,-50%) rotate(45deg);
transform: translate(-50%,-50%) rotate(45deg);
}
#cancel:after {
-webkit-transform: translate(-50%,-50%) rotate(-45deg);
transform: translate(-50%,-50%) rotate(-45deg);
}
Here we create two pseudo elements (:before and :after) that are rectangles, both having a width of 110% of the parent and a few pixels height. They are then centered horizontally and vertically inside the parent with absolute positioning and a transform: translate. Last step is to make one rotate 45 degrees and the other the same amount but in the opposite direction. This will make them form a cross - the more width the elements are given, the closer they will be to the corners of the parent (at 141% they will be touching exactly since this is the length of the diagonal compared to it's the width).
I might recommend using an image file such as an svg so that you get a consistent look across all browsers. If you use text like an "X" or a multiplication sign, you might get an unexpected result if the user doesn't have the same fonts installed as you do.
Here is a live example of how you could go about using inline svg. Of course if you want to reuse the icon, you should use an img tag with an external .svg file instead:
Screenshot:
Demo:
#container {
width: 50px;
height: 50px;
background-color: gray;
}
<div id="container">
<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="47" viewBox="0 0 14 14" overflow="visible" enable-background="new -1.301 -0.015 17.553 14.978" xml:space="preserve">
<g>
<line fill="none" stroke="#FFFFFF" stroke-width="2" x1="1" y1="1" x2="14" y2="14" />
<line fill="none" stroke="#FFFFFF" stroke-width="2" x1="14" y1="1" x2="1" y2="14" />
</g>
</svg>
</div>
You are looking for the Unicode Character 'MULTIPLICATION SIGN'. Perhaps there is a more elegant solution. This should work.
HTML
<div class="close"></div>
CSS
.close {
height: 100px;
width: 100px;
background-color: #2980b9;
border-radius: 5px;
}
.close:after {
position:relative;
content:"\d7";
font-size:235px;
color:white; /* #c0392b; */
font-weight:bold;
top:-100px;
left:-24px
}
JSFiddle
http://www.fileformat.info/info/unicode/char/00d7/index.htm
I like the svg solution as it will scale nicely, but if you want a CSS only solution, you can achieve something "similar" by doing this:
Create the box and assign it a relative position.
Use the pseudo-elements ::before and ::after to create the X (by positioning them absolutely, using the top border, and rotating them 45 and -45 degrees).
Here is a sample on how to do it:
.cancel {
position:relative;
width:100px;
height:100px;
background:#d0d0d0;
}
.cancel::before, .cancel::after {
content:"";
position:absolute;
top:calc(50% - 5px);
left:0px;
width:100%;
border-top:10px solid white;
transform:rotate(45deg);
transform-origin: 50% 50%;
}
.cancel::after {
transform:rotate(-45deg);
}
<div class="cancel"></div>
Some good things about this solution:
It can be easily animated using CSS3 transitions/animations (for example animate the X when clicked);
It "scales" a little: as it uses percentages for the ::before and ::after, the X grows proportionally if you grow/shrink the size of the .cancel box. Example.
Some cons about this solution:
It doesn't scale as nicely as the SVG.
You many need to use prefixes to make it work on some browsers.
Not sure if this is what you're looking for - but perhaps try a CSS solution with no "X" content? This solution is built with four div's that are all shaped like triangles with the help of CSS borders. Depending on how you position the triangles, your "X" in the middle can be as thin or as thick as you like, and the "X" will go all the way to the corners. The positioning in what I've posted isn't incredibly elegant, but you can get around this using floats and padding. I hope this helps!
HTML:
<div class="crossBox">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
CSS:
.crossBox div {
display: inline-block;
}
.crossBox div:first-child {
width: 0;
height: 0;
border-top: 58px solid blue;
border-left: 58px solid transparent;
border-right: 58px solid transparent;
background-color: transparent;
border-bottom: none;
position: relative;
top: -34px;
left: 5px;
}
.crossBox div:nth-child(2) {
width: 0;
height: 0;
border-left: 58px solid blue;
border-top: 58px solid transparent;
border-bottom: 58px solid transparent;
background-color: transparent;
border-right: none;
position: relative;
left: -118px;
top: 30px;
}
.crossBox div:nth-child(3) {
width: 0;
height: 0;
border-right: 58px solid blue;
border-top: 58px solid transparent;
border-bottom: 58px solid transparent;
background-color: transparent;
border-left: none;
position: relative;
left: -116px;
top: 30px;
}
.crossBox div:nth-child(4) {
width: 0;
height: 0;
border-bottom: 58px solid blue;
border-left: 58px solid transparent;
border-right: 58px solid transparent;
background-color: transparent;
border-top: none;
position: relative;
top: 36px;
left: -239px;
}

How to create a border gap illusion

This is the illusion that I am attempting to create:
Notice that my designer wants the border cut off in the middle of the div, this is what I need to know how to do. I don't think overlapping with a z-index will work because of how the HTML is laid out.
This is the HTML code of which the structure may not be changed for maximum device compatibility, however, if adding an element is the solution, I believe that may be done:
<div id="nav_icons_con" class="mopn">
<div id="inner_nav_container" class="show_inner_nav">
<div class="nav_link_container">Home</div>
</div>
</div>
Here is the basic current CSS code:
#nav_icons_con {
z-index: 1;
cursor:pointer;
height: 5.005em;
width: 5.005em;background-image:url(background.png);
background-size:70%;
background-repeat:no-repeat;
background-position:center;
margin:.385em .385em 0 0;
}
#nav_icons_con.mopn{
background-color:#FFF;
border:2px solid #83C5E6;
border-bottom:none;
box-shadow:5px 5px 10px #666;
}
#inner_nav_container, .inner_nav_container{
cursor:pointer;
display:none;
position:absolute;
top:5.39em;
right:.385em;
width:12.5em;
white-space:normal;
background-color:#FFF;
border:2px solid #83C5E6;
border-top:none;
box-shadow:5px 5px 10px #666;
}
#inner_nav_container.show_inner_nav, .inner_nav_container.show_inner_nav{display:block;}
The typical way to do this is to position the tab element over the sub element, so as to cover up that section of the border. However, the use of box-shadow complicates this.
One way is to add another element inside the root element, so that the root element can still cast the shadow, but the element inside is positioned above. See my code below, for a basic example.
Working Example:
.icon {
width: 50px;
height: 50px;
position: relative;
/*Create the shape for the shadow.*/
border: 5px solid #83C5E6;
box-shadow: 5px 5px 10px #666;
}
.icon-content {
background: #fff;
position: relative;
/*Move back over the border.*/
top: -5px;
left: -5px;
/*Make tall enough to cover the top border.*/
width: 50px;
height: 55px;
/*Add border, except on the bottom.*/
border: 5px solid #83C5E6;
border-bottom: 0;
/*Position up a layer.*/
z-index: 1;
}
.nav {
position: absolute;
left: -5px;
top: 100%;
width: 400px;
padding: 1em;
background: #fff;
border: 5px solid #83C5E6;
box-shadow: 5px 5px 10px #666;
}
<div class="icon">
<div class="icon-content">
</div>
<div class="nav">
<div class="item">Home</div>
</div>
</div>

how to achieve this css display?

I found this image while searching the web and I tried to implement this display on my own. This is what I have so far:
My HTML code is here:
<ul>
<li>
<span style="display:block;"><a href="">
<span><img src="../creation/images/samps/unnamed4.png" width="48" align="absmiddle"/></span>
<span class="price" >Freeep</span>
<span class="appname">Name of the apps that is so long</span>
<span class="developer">by scamexdotexe</span>
</a>
</span>
</li>
</ul>
This is my CSS style:
<style type="text/css">
li{
list-style: none;
width:200px;
border:1px solid #00CCFF;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
padding: 0px;
}
li:hover{
border:1px solid red;
}
li a{
margin: 0px;
display: block;
width: 100%;
height: 100%;
white-space:nowrap;
text-overflow:ellipsis;
overflow:hidden;
text-decoration:none;
padding:2px;
}
li a span img{
padding: 5px;
}
.price{
position:absolute;
margin-top:4px;
margin-bottom:4px;
color:#0099FF;
font-size:12px;
}
.appname{
}
.developer{
font-size:12px;
color:#666666;
margin:0;
position:inherit;
display:inline;
white-space:nowrap;
}
</style>
I spent hours on cloning the display on the first image but it seems that I have no luck. Can you point what I am doing wrong here? What I really want to do is align the app name and the price horizontally and also align the app name, rating, total downloads vertically.
For starters, I'd change the border radius to 5px, and add a drop shadow:
li {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-moz-box-shadow: 0px 0px 5px #333;
-webkit-box-shadow: 0px 0px 5px #333;
box-shadow: 0px 0px 5px #333;
}
Do you want to use the same colors as well?
Here's a start for you: http://jsfiddle.net/k8ejp/4/
Notes:
the "avatar" div could of course be an image
absolute positioning can be used instead of floating if you want a more complex layout (or find it easier to work with position)
my example uses a few newer features of CSS (like text-overflow) but they should degrade without changing the layout.
HTML
<div class="box">
<div class="avatar">foo</div>
<div class="price">Free!</div>
<div class="name">A long app name A long app name A long app name A long app name</div>
<div class="info">Other info about the app goes here.</div>
</div>​
CSS
.box{
font: 11px/1.5 sans-serif;
padding: 8px;
background-color: #ccddcc;
width: 400px;
border-radius: 4px;
border: 1px solid silver;
box-shadow: 2px 2px 2px #ddd;
}
.avatar {
width: 32px;
height: 32px;
background-color: #555;
float: left;
margin-right: 12px;
}
.price {
float: right;
color: green;
}
.name {
width: 200px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
I have created an example here: http://jsfiddle.net/D26Hj/1/.
It just needs an app logo and star sprite image.
I have drawn up a star sprite image and quickly made a fake logo in Paint.NET.
Info about the sprite:
Each star is 9px wide.
There are 5 stars in a rating, so therefore each rating is 45px wide.
Therefore, to change the rating change the background-position as per below.
Here are the background-positions to use for different star ratings:
-0px 0 Stars
-45px 1 Star
-90px 2 Stars
-135px 3 Stars
-180px 4 Stars
-225px 5 Stars
I have added classes to make it easier, use rating-0 to rating-5 for 0 stars to 5 stars.
HTML:
<div class="app">
<div class="image"></div>
<div class="title">
App title
</div>
<div class="price">$0.00</div>
<div class="rating rating-3">3 stars</div>
<div class="info">1024 downloads</div>
</div>
CSS:
body {
padding: 20px;
}
.app {
position: relative;
width: 225px;
height: 50px;
padding: 5px;
background: #8f8;
font-family: Arial, Helvetica, sans-serif;
font-size: 13px;
border: 1px solid #484;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
box-shadow: 0 0 2px #484;
-moz-box-shadow: 0 0 3px #888;
-webkit-box-shadow: 0 0 3px #888;
}
.app a {
text-decoration: none
}
.app .image, .app .title, .app .price, .app .rating, .app .info {
position: absolute;
}
.app .image {
left: 5px;
top: 5px;
width: 48px;
height: 48px;
background-image: url('http://i.imgur.com/JAgto.png');
}
.app .title {
left: 60px;
top: 7px;
}
.app .price {
right: 5px;
top: 7px;
color: #262;
}
.app .rating {
left: 65px;
top: 25px;
width: 45px;
height: 10px;
text-indent: -999px;
background-image: url('http://i.imgur.com/giWyQ.png');
background-position: -135px 0;
}
.app .info {
left: 60px;
top: 40px;
font-size: 11px;
color: #666;
}
.rating-0 {
background-position: 0 0;
}
.rating-1 {
background-position: -45px 0;
}
.rating-2 {
background-position: -90px 0;
}
.rating-3 {
background-position: -135px 0;
}
.rating-4 {
background-position: -180px 0;
}
.rating-5 {
background-position: -225px 0;
}
I'm not so sure you should use span, personally I would use div instead since it's default display style is already block, which I see is what you try to achieve on the description block.
And about the Price and AppName, I would suggest that you wrap them inside a Div container on the same level with rating and downloads count and make that container display style inline-block then adjust the width for both Price and AppName.
It would be like this
<div class="main-container">
<div class="image"> Image Goes Here </div>
<div class="description">
<div class="description-top">
<div class"description-top-title"> Title Goes Here</div>
<div class"description-top-price"> Price Goes Here</div>
</div>
<div class="description-middle"> Rating Goes Here</div>
<div class="description-bottom"> Download Count Goes Here</div>
</div>
</div>
.main-container{
display: inline-block;
}
.image{
width: 30%;
}
.description{
display: block;
width: 70%;
}
.description-top{
display: inline-block;
}
.description-top-title{
width: 60%;
}
.description-top-price{
width: 40%;
}