Hardware and software setup

How to make shapes in html. Creating Perfect Responsive Shapes with CSS vw Units

Front-end developer and vector illustrator

The work of vector artists and front-end developers is often separated. The reason is that, as a rule, many companies have enough people in the state, so the separation occurs for the sake of increasing productivity. Another common reason is that some people want to focus entirely on front-end development, while others are more attracted to illustrations. Both industries have specific niches where you can focus on learning really good and valuable skills.

Of course, this approach is very prudent, but I think that a front-end developer can gain a lot from working with illustrations, even if this is not his main focus.

The fact is that both skills, in essence, consist in connecting various components to create the final product. Illustrators put together various shapes and work with shapes in order to end up with a drawing. Front-end developers, in turn, put together code components to create a web page.

Learning the basics of vector graphics introduces you to layouts, color patterns, shape dynamics, and generally the creativity that goes into being a front-end developer.

I started this conversation about the benefits of being front-end developers familiar with vector graphics to the fact that images on pure CSS serve as an example of how great the intersection between the work of vector illustrators and front-end developers can be.

Creating a pure CSS image means that instead of using vector illustration software (such as Inkscape, Illustrator, Affinity Designer, or Sketch), you work directly with CSS code.

Despite the similarity of professions, I think that as an illustrator the ton of CSS code required to create an image can be intimidating, however, as well as for a front-end developer, the prospect of creating an image using code.

For that reason, here's a guide to creating your first pure CSS image, which I hope:

  • will increase the credibility of creating images in pure CSS;
  • help you understand how pure CSS images are created;
  • if you are a front-end developer, it will increase your interest in vector graphics;
  • if you are a vector illustrator, it will increase interest in front-end development;
  • will provide a basic template for creating pure CSS images.

Pure CSS Image Components

First, let's figure out what "pure CSS" is.

Creating "pure CSS" images involves adding CSS styling to several HTML div tags.

For example, we can create a square with just one div and style applied to it:

Body( background: #1D1F20; ) .square( width: 100px; height: 100px; background: #A58CB6; )

We will create shapes by styling blocks to form the final picture.

Each pure CSS project will consist of the following components:

  • a div tag for each shape;
  • a specific CSS class assigned to each div ;
  • an invisible block that will serve as the canvas.

Here is the final version of the image created in pure CSS, for which we will use only the components listed above.

But before we start writing the code, let's figure out what specific shapes the image of this koala consists of.

The structure of the figures

First, the entire image of the koala was built on top of an invisible square canvas (that's not the official term). This invisible box will be centered on the body and the head will be centered on the box. Personally, I think this is a good practice that makes responsive design easier (more on that at the end of the article).

For now, just keep in mind that we'll be dealing with an invisible rectangular box, which I've highlighted below:

Secondly, we have a circle in the center of the web page, on the basis of which we will create head.

Next, we will create ears, which are located on the sides of the head. Each ear is made up of two colored circles, which overlap each other, one circle being slightly smaller than the other. We'll be making a distinction between an ear div and an "inner ear" div.

In addition, we have two eyes, which are also in circles superimposed one on top of the other. They differ in color and size: the larger circle is white, and the smaller circle (pupil) is black.

And the final touch - two bunches of gray hair in the form of triangles, having different positions on the top of the koala.

Another important thing to mention is that we will also be using different layers to create the image. The ears will be behind the head, the nose in front of the eyes, and so on. This will become clearer as we move on to working with CSS.

HTML

Note To add hair to our koala, we will use the clip-path method. It is supported in Chrome, Safari and Opera. If you're using Firefox, I suggest you switch to a different browser while you're reading this guide.

Typically, I add one div that will be the shape, then I style it, and then move on to the next div .

However, since this is an instruction, let's first take a look at the HTML code and break it down:

It's important to note that some divs are nested within others. Let's take a look at our koala's right ear div:

"Ear-right" (right ear) is the parent div and "inner-ear" (inner ear) is the child.

This distinction is important because the shapes will be given a fixed position, width, and height, expressed as a percentage.

For example, let's say we have a div nested in body with height: 100% and width: 100% :

The some-div class is assigned a fixed position that is 10% below the top of the parent block. Since some-div is embedded in body , which has 100% width and 100% height, the div will be positioned 10% below the top of this block.

Now nest another div inside some-div and give it the same style:

As you can see, we will get a completely different layout.

In this example, another-div (blue square) is 10% lower than some-div (red square).

Now move another-div from some-div to body and increase padding to 30%:

another-div is now indented 30% from the top of body , not some-div .

With that in mind, let's move on to CSS styles.

CSS styles

body

First, let's set the background color of the body . Let it be a shade of blue, like Twitter:

Body(background: #25A9FC; )

box

Now let's add styles to the invisible block. It will be centered horizontally (add a background or border to it to keep track of the field position):

Box( position: relative; margin: auto; display: block; // optional background and border background: white; border: solid 4px red; // code here)

position: relative means that the element is positioned relative to its normal position, which is the top left corner, since it's the first div in the body .

When the position property is set to relative , use display: block; and margin: auto; to automatically center the field horizontally.

We can then add the following piece of code to position the box 8% lower, and set the height and width to the same dimensions as in the image above, and finally set the background value as needed:

Box( position: relative; margin: auto; display: block; margin-top: 8%; width: 600px; height: 420px; background: none; )

Note that we are using the margin-top: 8% property to lower the margin by 8%. Because we're customizing top , this won't affect our previous margins set with margin:auto .

Now that the margin is set up, all of our other divs will be nested within it. Again, this is important because when we assign absolute percentage positions, this will position the div at the same percentage of the margin, but not from body . The same principle will work with our height and width.

Head

Let's look at the code for creating the head, and then we'll break it down step by step:

Head( position: absolute; top: 16.5%; left: 25%; width: 50%; height: 67%; background: #A6BECF; border-radius: 50%; )

The percentages for top and left mean that the div will be 15% from the top of the box and 25% from the left. The div's width is 50% of the field's width and the height is 67% of the field's height. After that we set the background color to light gray.

Next, we use border-radius: 50% . If you omit this property, the head will always be in the shape of a rectangle (or square). border-radius is the property that changes the shape. If you're familiar with Illustrator, you can compare adding the border-radius property to dragging the edges of a square to round it. To round the shape to a circle, we always use a factor of 50%.

border-radius can be used not only to create a circle, but also to round any shape, such as the rectangle for our koala's nose.

Before we go any further, I'll explain where I got the top, left, width, and height percentages from. We've given the field a width of 600px, so 50% gives us 300px. Given that the box was only 400 pixels high, the percentage for the head should be higher.

Most likely you are expecting me to give you the exact formula for calculating the height. To be honest, I usually find the desired value by typing.

The more images you create in pure CSS, the faster you will find the optimal values. But what you really need to think about now is the height and width of the parent div and how big the child div needs to be in relation to its parent.

Now, having position percentages, it is much easier to calculate the absolute center. Here is the formula:

Left = (100 - width) / 2 top = (100 - height) / 2 // our case (100 - 67)/2 = top: 16.5%; (100-50)/2 = left: 25%;

Now this piece of code works for our head div because we want to center it. However, we, for example, do not want to place the ears in the very center. We'll get to that point shortly, and I'll also explain when to use bottom and right instead of top and left .

The last thing to say about this section is that each subsequent div will be nested inside the head div, since each shape that is added will be placed on top of it.

Here is what we should get at this stage:

head copy

.head-copy( width: 100%; height: 100%; position: absolute; background: #A6BECF; border-radius: 50%; z-index: 2; )

The head copy div is made solely so that the ears can appear behind the head. For this, the z-index property is used. Pay attention to the last line of the previous code snippet:

Z-index: 2;

z-index is used to indicate the level at which divs are positioned relative to others along an axis that is perpendicular to the screen (that is, towards or away from you). Layers are set using this property.

In our final image, the eyes will be above the head, the nose will be above the eyes, and so on. All this will be controlled by z-index . The higher the z-index value, the higher the div is positioned.

So if you have two divs, z-index: 1 will be your bottom layer and z-index: 2 your top layer. When we add a copy of the head, we give it a z-index: 2 , which means our koala's ears will be positioned behind the head.

If you want, you can remove the copy of the head when we add the ears and see what happens.

We shouldn't see any changes. The image still looks like this:

Ears

As mentioned earlier, we will have one ear, consisting of circles, for each side. Two larger light gray circles and two smaller dark gray circles on top of each ear (let's call them inner-ears).

Ear-left( position: absolute; width: 60%; height: 65%; left: -20%; top: 5%; background: #A6BECF; border-radius: 50%; z-index: 1; ) .ear -right( position: absolute; width: 60%; height: 65%; right: -20%; top: 5%; background: #A6BECF; border-radius: 50%; z-index: 1; ) .inner- ear( position: absolute; border-radius: 50%; width: 80%; height: 80%; top: 10%; left: 10%; background: #819CAF; )

For each class we use border-radius:50% since we need circles and then add color using background .
As you can see, we wrote two different styles for the ears, but only one for the inner ear. This will become apparent when we deal with positioning.

The parent div for the right and left ear is the head. This way the percentages will be calculated relative to the head, just like the height and width. We calculate the height and width based on the fact that we want big ears, which, however, should be smaller than the head. So we get width:60% and height:65% .

The inner ears are inserted into the left and right ear. We know they need to be a little smaller, so we give them 80% width and height. We also want the inner ear to be in the very center of the ears, so we can use the familiar formula again:

Left = (100 - width) / 2 top = (100 - height) / 2 // our case (100 - 80)/2 = top: 10%; (100-80)/2 = left: 10%;

Since left and right are relative to the ears, we can use the same style for the left and right ear, so we only have one inner ear div. We are forced to use two separate divs for the ears, because they will have different left and right values, because they are positioned relative to the head.

We want the ears to stick out to the left and right of the head. We use negative values ​​left: -20% and right: -20% to shift in the indicated direction.

Here's what happened in the end:

//left ear width: 60%; height: 65%; left: -20% top: 5%; //right ear width: 60%; height: 65%; right: -20%; top: 5%;

Finally we add z-index: 1 ; so our ears go under the head. Here is what we should get:

Eyes

.eye-left( position: absolute; background: white; width: 30%; height: 33%; top: 25%; left: 21%; border-radius: 50%; z-index: 3; ) .eye- right( position: absolute; background: white; width: 30%; height: 33%; top: 25%; right: 21%; border-radius: 50%; z-index: 2; ) .pupil( position: absolute ; width: 28%; height: 30%; top: 35%; left: 36%; border-radius: 50%; background: #27354A; )

As you can see, our koala's eyes are similar to its ears. We have two large white circles (left and right eye) and one pupil.

For them we use border-radius:50% , since they are circles, and also use background to set the appropriate color.

We have a pupil that fits in each eye. We guess the height and width of the pupil, center it and get this result:

Width: 28%; height: 30%; top: 35%; left: 36%

You can also use the trial and error method or the above formula to determine the left eye padding. Meanwhile, we just guess the height and width indicators until we find the optimal value.

//left eye width: 30%; height: 33%; top: 25%; left: 21% //right eye width: 30%; height: 33%; top: 25%; right: 21%;

As for the z-index , the following values ​​will place the nose right above the eyes:

//left eye z-index: 3; //right eye z-index: 2;

As a result, we should get this picture:

Nose

.nose( position: absolute; background: #BE845F; width: 25%; height: 42.5%; left: 37%; top: 45%; border-radius: 50px; z-index: 4; )

Now let's do the nose. We select all values ​​in the same way, here are the optimal ones:

Width: 25%; height: 42.5%; left: 37% top: 45%;

We set the background color to brown using background , and depth with z-index:4 so that the nose is above the eyes.

We also use border-radius: 50px , which we use to round the corners of the rectangle the way we want. When a shape needs to be rounded just a little, it's easier to specify the number of pixels rather than percentages.

Now we have this image:

Hair

Almost done! The last step is to style our two tufts of hair, left and right, after which we will have our finished koala.

Hair-left( position: absolute; top: -8%; left: 30%; width: 20%; height: 20%; background: #A6BECF; -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%); clip-path: polygon(50% 0%, 0% 100%, 100% 100%); ).hair-right( position: absolute; top: -4%; left: 48 %; width: 20%; height: 20%; background: #A6BECF; -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%); clip-path: polygon(50% 0%, 0% 100%, 100% 100%); )

As you can see, here we don't use border-radius , but we have code like this with clip-path:

webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%); clip-path: polygon(50% 0%, 0% 100%, 100% 100%);

For any shape other than a square, triangle, and circle, it's easier to use the clip-path method.

This may seem a bit confusing, but luckily there is a great tool called Clippy that gives you clip-paths for various shapes. On the right you will see many different shapes:

In the image above, the triangle is selected, so you can copy the clip-path and paste it into the hair CSS class.

We again set the color with background and set the width and height to 20% for both beams. We set the left beam to left: 30% and the right beam to left: 48% . This good example to discuss what to use: right or left . Let's say we want to move the right beam 5% to the right. We can add 5% to 48% to get left:53% . However, the rule of good form is the transition from left to right and vice versa at a value above 50%. Therefore left: 53% will be equivalent to right:47% .

The top offsets will be negative because we want both tufts of hair to stick out above the head. The left beam will stick out a little more, so we give it a height: 8% , and the right beam is slightly smaller, with height: 4% .

Our koala picture is ready!

As a result, the CSS code should look like this:

Body( background: #25A9FC; ) .box( position: relative; margin: auto; display: block; margin-top: 8%; width: 600px; height: 420px; background: none; ) .head( position: absolute; top:16.5%; left: 25%; width: 50%; height: 67%; background: #A6BECF; border-radius: 50%; ) .head-copy( width: 100%; height: 100%; position: absolute; background: #A6BECF; border-radius: 50%; z-index: 2; ).ear-left( position: absolute; width: 60%; height: 65%; left: -20%; top: 5% ;background: #A6BECF;border-radius: 50%; z-index: 1; ) .ear-right( position: absolute; width: 60%; height: 65%; right: -20%; top: 5%; background: #A6BECF; border-radius: 50%; z-index: 1; ) .inner-ear( position: absolute; border-radius: 50%; width: 80%; height: 80%; top: 10%; left: 10%; background: #819CAF; ) .eye-left( position: absolute; background: white; width: 30%; height: 33%; top: 25%; left: 21%; border-radius: 50% ; z-index: 3; ) .eye-right( position: absolute; background: whit e; width: 30% height: 33%; top: 25%; right: 21%; border-radius: 50% z-index: 3; ) .pupil( position: absolute; width: 28%; height: 30%; top: 35%; left: 36%; border-radius: 50%; background: #27354A; ) .nose( position: absolute; background: #BE845F; width: 25%; height: 42.5%; left: 37%; top: 45%; border-radius: 50px; z-index: 4; ) .hair-left( position: absolute; top: -8% ; left: 30%; width: 20%; height: 20%; background: #A6BECF; -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%); clip-path: polygon(50% 0%, 0% 100%, 100% 100%); ) .hair-right( position: absolute; top: -4%; left: 48%; width: 20%; height: 20%; background : #A6BECF; -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%); clip-path: polygon(50% 0%, 0% 100%, 100% 100%) ; )

Further practice

I hope this article has given you a clear idea of ​​how to create pure CSS images and inspired you to continue exploring this topic. Also, you should now have nice pattern, which you can use for further practice.

I also offer you two free ways pump up your skills on this topic:

  1. Pure CSS Images Video Course.
  2. Daily CSS Images Challenge.

Hint for programmers: if you register for the competition Huawei Honor Cup, get free access to the online school for members. You can level up in different skills and win prizes in the competition itself. .

From the author: Rectangle within rectangles: this is how our web pages have always been built. We've been trying to break free of these limitations for a long time by using CSS to create geometric shapes, but these shapes never affect the content inside the styled elements, or how other elements on the page are positioned relative to the styled element.

The new CSS specification for shapes changes the current state of affairs. Introduced by Adobe in mid-2012, it aims to give web designers the ability to change the flow of content in and around relatively complex shapes—something we've never been able to achieve before, even with JavaScript.

For example, notice how the text wraps around the round pictures in the following design. Without the Shapes, the text would be rectangular – throwing out a subtle trick that takes the design to the next level.

Notice how the text takes about round shape along the edges of the plate in this example. Using CSS Shapes we can create a similar design for a web page.

Let's take a closer look at how Shapes work and how you can get started using them.

Browser support

CSS Shapes is currently only supported in Webkit Nightly and Chrome Canary, but their Level 1 Module has reached PhD status, so the properties and syntax defined in the spec are fairly stable. It won't be long before other browsers support them. This level focuses on those Shape properties that change the flow of content around the shape. In particular, he concentrates on the shape-outside property and related ones.

Combined with other latest features such as Clipping and Masking , CSS Filters and Collaging and Merging , CSS Shapes will allow us to create more complex exquisite design without having to resort to graphic editors such as Photoshop and InDesign.

Future levels of CSS Shapes will also focus on decorating content within shapes. For example, today it's easy enough to create a diamond shape with CSS: just flip an element 45 degrees, and then flip the content inside it the other way around so it fits horizontally on the page. But the content inside the diamond will not take the appropriate shape, and will always remain rectangular. By the time the shape-inside property is implemented, we will be able to make the content rhombic as well, creating markup similar to the image below.

Soon CSS Shapes will also allow text to be wrapped inside, like these diamonds, so that instead of clipping or using overflow, the text itself is positioned relative to the edges of the container..

To use CSS Shapes in Chrome Canary today, you'll need to check the box to enable experimental features.

Creating CSS Shapes

You can apply a shape to an element using the Shapes properties. You pass a shape property a shape function as a value. The shape function is where you pass parameters that specify the shape you want to apply to the element.

Shapes can be created using one of the following functions:

Each shape is defined by a set of points. Some functions take dots as parameters; others take offset parameters, but they all end up rendering the shapes on the element as a set of points. We will analyze the parameters for each of these functions with examples.

A shape can also be determined from an image using alpha channel extraction. When an image is passed to the shape property, the browser will extract the shape from the image based on the shape-image-threshold value. The shape is defined by pixels whose alpha value is above the specified threshold. The image must be CORS compatible. If the provided is not available for some reason (for example, it doesn't exist), then no shape will be applied.

The following shapes accept the above functions as values:

shape-outside: makes the content wrap around the shape (outside)

shape-inside: content takes the shape of a shape from the inside

You can use the shape-outside property in combination with shape-margin to add an outer margin around a shape, which will push content away from the shape, leaving space between them. Just like shape-outside gets a shape-margin property, shape-inside gets a shape-padding property, which adds padding.

Using shape properties or functions, declaring a shape element can be done with just one line of CSS code:

Element ( shape-outside: circle(); /* content will wrap around the circle given to the element */ )

Element ( shape-outside: url(path/to/image-with-shape.png); )

Element ( shape - outside : url (path / to / image - with - shape . png ) ; )

But... If you apply this line of CSS code to an element, the shape will not be applied to it unless the following conditions are met:

The element must be floating. Future CSS Shapes levels will allow us to define shapes for non-floating elements, but this is not yet possible.

The element must be sized. The height and width given to the element will be used to establish the coordinate system.

As you saw in the functions above, shapes are defined by a set of points. Because points have coordinates, the browser needs a coordinate system in order to know exactly where each point on an element should be placed. So the example above would work if it had the following:

Element ( float: left; height: 10em; width: 15em; shape-outside: circle(); )

Element ( float : left ; height : 10em ; width : 15em ; shape - outside : circle () ; )

However, giving certain sizes to an element does not affect its responsiveness (we'll talk about this later). Since each shape is defined as a set of points located using a pair of coordinates, changing the coordinates of a point will directly affect the created shape. For example, the following figure shows a hexagon that can be created using the polygon() function. The figure consists of six points. Changing the horizontal coordinate of the orange dot will change the final shape and will also affect the placement of content inside/outside of any element that the shape is applied to.

If the element is floating and right-aligned and has a shape applied to it, the content to its left will change its position when one of the coordinates of the orange dot inside the polygon() function is changed.

Reference block Shapes

CSS Shapes are defined and created inside a reference box, where the shape is drawn. In addition to the element's height and width, the element's box model components—margin box, content box, padding box, and border box—are also references for determining the element's shape.

By default, the margin box is used as a reference, so if the element you're applying a shape to already has a bottom margin, the shape will end at the edge of the margin, not the border. If you want to use some other box model values, you can specify them along with the shape function that you pass to the shape property:

shape-outside: circle(250px at 50% 50%) padding-box;

shape - outside : circle (250px at 50% 50% ) padding - box ;

The padding-box keyword in this rule defines the application of the shape and the padding box constraint. The circle() function defines the circle, its dimensions and placement relative to the element.

Defining Shapes with Functions

We'll start by making info text wrap around a round user avatar image, like for a user profile or testimonial.

Using CSS Shapes, the text around the user's image wraps around the shape instead of keeping it rectangular.

We will use the circle() function to apply a circle shape to the profile picture using the following markup:

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum itaque nam blanditiis eveniet enim eligendi quae adipisci?

Assumenda blanditiis voluptas tempore porro quibusdam beatae deleniti quod asperiores sapiente dolorem error! Quo nam quasi soluta reprehenderit laudantium optio ipsam ducimus consequatur enim fuga quibusdam mollitia nesciunt modi.

< img src = "//api.randomuser.me/0.3.2/portraits/men/7.jpg" alt = "(!LANG:profile image" / > !}< p >Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum itaque nam blanditiis eveniet enim eligendi quae adipisci?< / p > < p >Assumenda blanditiis voluptas tempore porro quibusdam beatae deleniti quod asperiores sapiente dolorem error! Quo nam quasi soluta reprehenderit laudantium optio ipsam ducimus consequatur enim fuga quibusdam mollitia nesciunt modi.< / p >

You may be asking, "Why can't we apply a border-radius to round the image?" Answer: The border-radius property has no effect on the placement of content inside and outside the element it is applied to. It only affects the element's borders or background. The background is cropped at the rounded corners, that's all. The content inside the element will remain rectangular, and the content outside the element will behave as if the element remains rectangular.

We're going to use the border-radius property to make the image round - here's what we do to round pictures or other elements on the page:

img ( float : left ; width : 150px ; height : 150px ; border - radius : 50 % ; margin - right : 15px ; )

Without CSS Shapes, the text sees the image as square and wraps around the square shape instead of the round one.

In a browser that doesn't support CSS Shapes, the content around the round image will be positioned as if it weren't round. This is how it will look in older browsers. To change the flow of content around a specific shape, use the shape's properties.

img ( float: left; width: 150px; height: 150px; border-radius: 50%; shape-outside: circle(); shape-margin: 15px; )

img ( float : left ; width : 150px ; height : 150px ; border - radius : 50 % ; shape - outside : circle () ; shape - margin : 15px ; )

With this code, the text will be able to "see" the round shape applied to the image and wrap around it as shown in the first screenshot. (You can look at the result.) In browsers that don't support shapes, this will look like the second image.

You can use the pure circle() function or pass parameters to it. Here is its official syntax:

circle() = circle([ ]? ? [ at< position > ] ? )

The question marks indicate that these parameters are optional and can be omitted. The parameters you skip will take on the default values. When you use circle() as is, instead of specifying the position directly, by default, the center of the circle will be at the center of the element you apply it to.

You can set the radius of the circle using any unit of length (px, em, pt, etc.) You can also set the radius with parameters using closest-side or furthest-side, but closest-side is the default which means the browser will use the distance from the center of the element to the nearest side as the radius, farthest-side uses the distance from the center to the farthest side.

shape-outside: circle(farthest-side at 25% 25%); /* defines a circle whose radius is half the longest side, located at coordinates 25% 25% in the element's coordinate system */ shape-inside: circle(250px at 500px 300px); /* defines a circle whose center is 500px horizontally and 300px vertically, with a radius of 250px */

The ellipse() function works just like circle(), with the same set of values, except that instead of a radius parameter, it takes two: one on the x-axis and one on the y-axis.

ellipse() = ellipse([ (2)]? ? [ at< position > ] ? )

The inset() function is not directly related to a circle or an ellipse, it is used to create rectangular shapes within an element. Since the elements are already rectangular, we don't need it to create rectangles. Instead, inset() can help us create rounded rectangles so that the content wraps around the rounded corners.

The inset() function takes one to four offset parameters that specify an offset relative to the edges of the reference box, which locates the box within the element. Rounded corners are specified in exactly the same way as border-radius, using one of four values, in combination with the round keyword.

inset() = inset(offset(1,4) ?)

inset() = inset (offset ( 1 , 4 ) [round< border - radius > ] ? )

The following code will create a rounded rectangle on a floating element.

Element ( float: left; width: 250px; height: 150px; shape-outside: inset(0px round 100px) border-box; )

Element ( float : left ; width : 250px ; height : 150px ; shape - outside : inset (0px round 100px ) border - box ; )

The final Shapes function is polygon(), which defines more complex ambiguous shapes using any number of points. The function takes a set of pairs of coordinates, where each pair defines the position of a point.

In the following example, the floating image is positioned at the right edge, taking up the full height of the screen and using viewport units. We want the text on the left to wrap around the hourglass inside the image, and we use the polygon() function to define a custom shape for the image.

The CSS code for the image above looks like this:

img.right ( float: right; height: 100vh; width: calc(100vh + 100vh/4); shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60 %, 45% 40%); )

img . right ( float : right ; height : 100vh ; width : calc (100vh + 100vh / 4 ) ; shape - outside : polygon (40% 0 , 100% 0 , 100% 100% , 40% 100% , 45% 60% , 45% 40% ) ; )

You can set the coordinates of the points that define the shape in units of length or in percentages, like mine. This code will give the desired result, but as you can see, the shape function does not affect the remaining parts of the image outside the given shape. The point is that applying the shape function to an element - be it an image or a container or something else - will not affect anything other than the content's wrapping area. The background, borders and everything else will remain unchanged.

To visually represent the created polygon, we need to "crop" the parts of the image outside the shape. The clip-path property from the CSS Masking Module specification will help us with this.

The clip-path property accepts the same shape functions and values ​​as the shape property. If we pass the same polygonal shape that we used for the shape-outside property to the clip-path property, it will clip the part of the image that is outside the shape.

img.right ( float: right; height: 100vh; width: calc(100vh + 100vh/4); shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60 %, 45% 40%); /* clipping the image along the outline of the shape */ clip-path: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40% ); )

img . right ( float : right ; height : 100vh ; width : calc (100vh + 100vh / 4 ) ; shape - outside : polygon (40% 0 , 100% 0 , 100% 100% , 40% 100% , 45% 60% , 45% 40%); /* crop the image along the outline of the shape */ clip-path : polygon (40% 0 , 100% 0 , 100% 100% , 40% 100% , 45% 60% , 45% 40% ) ; )

The result looks like this:

The clip-path property is currently supported along with prefixes, i.e. it will work in Chrome with the --webkit- prefix added. You can look at the demo.

The clip-path property is a great companion to the shape property, as it helps visualize the created shapes and clip the parts outside of the shape, so you'll probably use them together a lot.

The polygon() function also accepts an optional keyword for padding, which can be either nonzero or evenodd. It defines how the intersecting regions within the polygon will behave. Check out the SVG fill-rule property for details.

Defining a Shape with an Image

To define a shape using an image, the image must have an alpha channel from which the browser will extract the image.

A shape is defined by pixels whose alpha value is above a certain threshold. The default value for the threshold is o.o (fully transparent), or you can set it directly with the shape-image-threshold property. Thus, any opaque pixel can be used as part of the figure defined by the image.

A future layer of CSS Shapes may allow you to switch to using image brightness data instead of an alpha channel. If this happens, the shape-image-threshold will be expanded to include a threshold for either the brightness or the alpha channel, depending on the state of the switch.

We use the following image to define the element's shape and make the text wrap around it:

) ; shape - margin : 15px ; shape-image-threshold : 0.5 ; background : #009966 url(path/to/background-image.jpg); mask-image: url(leaf.png); )

Of course, if you applied a background to an element, the background will need to be clipped outside of the given shape. The mask-image property (with appropriate prefixes) from the Mask Module can help with this, since the clip-path property does not take an alpha channel value as a value. The result looks like this:

If you create complex shapes, you may find it convenient to define the shape using a picture. This will allow you to use the alpha channel of the image in Photoshop, instead of having to set the points manually.

You'll also find it handy to use an image instead of a shape function when you have a lot of floats or exceptions inside an element - because on this moment there is no way to declare multiple shapes to one element. But if the image contains multiple regions, the browser will extract those regions and use them.

CSS Shapes in Responsive Design

Can CSS Shapes Work for Responsive Design? The current specification for shape-outside includes this point, because it allows you to specify the dimensions of an element either in percentages or in units of length, and the points that define the shape (shape function parameters) can also be specified in percentages. This means that an element with a given shape-outside can be fully responsive, just like any floating element with percentage sizes.

The shape-inside property is not yet responsive, but that's because it's been moved to a Level 2 Module. Many of his current limitations will go away at the next level.

Shape Tools

Creating complex shapes using functions can be a tedious task, especially if you are creating a shape with many points and coordinates using polygon(). Luckily, the Adobe Web Platform team is working on producing interactive tools to make this process much easier. Bear Travis has created a collection of Shape Tools that allows us to visually create polygonal shapes. The tool generates a shape function. This can be useful, but it has its limitations if you want to create a shape based on a specific image, because the tool does not provide such an option.

A more advanced and interactive tool has been developed by the Adobe web platform team. The tool was recently released as an extension for the free Brackets editor. It allows you to render and edit shapes right in the browser, and has an online preview feature that updates the shape's values ​​in the style sheet when you change them on the page. This gives an instant visual feedback your changes, allowing you to see how the shapes interact with other elements on the page.

Editing a polygonal shape directly in the browser using the preview mode in Brackets. Screen recording by Razvan Caliman.

This tool will become indispensable as it facilitates the creation, editing and debugging of figures. Razvan Caliman, which explains how to bring up the Brackets Shape editor and start using it.

Future: CSS Exceptions

The CSS Shapes specification was a specification dedicated to CSS Shapes and Exclusions, but it has been split. While CSS Shape defines the shape-inside and shape-outside properties, CSS Exceptions define properties that force content to wrap around non-floating elements, such as those that are absolutely positioned. They make it possible for content to flow around an entire shape from different directions, as shown in the image below.

In the future, CSS Exceptions will allow content to wrap around a shape such as a notch, as shown in the front page of the magazine. The notch can also be round, and the text will wrap around it exactly the same..

New Figure Level

The current CSS Shapes specification is just the first step. Soon, new features will give us more control over the creation and flow of content, so it will be easier for us to turn layouts into live designs with just a few lines of code. As of today, the spec editors are focused on finalizing the shape-outside, and you may see more browser support for CSS Shapes by the end of 2014.

You can use Shapes today as part of a progressive enhancement strategy, knowing that they have an acceptable replacement in non-supporting browsers. I recently started using them on my site and the replacement looks quite acceptable. For more complex designs, you can use a script to check for browser support, and provide any replacement if not supported. You can also use Modernizr's tests with this script to check if the shape-outside property is supported, or load your own build that includes this test.

CSS Shapes allow us to create another bridge between print and web design. The examples in this article are simple, but they should give you a basis for creating a design comparable to a magazine or poster in complexity without worrying about whether you can recreate it on screen. Whatever you're exploring - from non-rectangular layouts to Shape animation - now is the time to experiment.

As page layout becomes more complex, developers need access to more units of measurement to bring the design to life. In addition to the familiar percentages, em and rem, and pixels, there are newer units of vw and vh, and related vmin and vmax, which provide more powerful ways creation adaptive design, which can often help eliminate the use of @media breakpoints.

Going beyond the use of percentages

Traditional CSS units create the following problems in web design:

  • The percentage unit does not always work as expected. Developers have to keep margins in mind when sizing elements. Do not use the percentage unit to set the height of the body element. The font-size: 50% entry sets the text to half its standard size, rather than establishing a relationship between the size of the text and the size of its containing element.
  • It's nearly impossible to create perfectly shaped shapes for different browser window sizes. It is very difficult to achieve an element that is perfectly square and at the same time responsive.

The vw and vh units pretty much solve all these problems.

Maintaining ideal proportions

With vw and vh units, it's very easy to create perfect shapes on web pages. These units can be used to set sizing values ​​for almost all CSS properties. Therefore, if you want to create an element that, at any size of the browser window, takes up 20% of its width and at the same time remains square, you need to set the same values ​​for the width and height properties, using the vw unit:

Div.twentysquare ( background : # 999 ; width : 20vw; height : 20vw; )

Check out the demo of this example below, follow the link and try resizing the viewbox to see the shapes resize.

Using the same method, you can easily create a rectangle whose height is twice its width for any size of the browser window:

Div.onetworect ( width : 20vw; height : 40vw; )

Setting a banner to the ideal aspect ratio is easy with the following CSS code:

Div.goldenrect ( width : 100vw; height : 61 .8vw ; background : red ; )

For optimal scaling of the text in the adaptive block, taking up all the space provided for it with a breakdown into lines, you just need to set the font size in units of vw.

Translation - Desk

Problem

Cropping images into a diamond shape is a common visual design technique, but implementing it in CSS is far from easy. In fact, until recently, this was almost impossible.

Therefore, in order to implement their ideas, designers had to first crop the required images in graphics editor. Needless to say, this way of applying the effect means enormous complexity in maintaining the website and guaranteed confusion in the future if someone wants to change the styling of the images. Definitely, today we should already have a better way. In fact, there are two such ways!

Transformation Solution

The basic idea is the same as the first solution from previous secret(see "Parallelogram" secret above) - we need to wrap our image in

, and then apply the opposite transformation to it rotate()
HTML



.picture(
width: 400px
transform: rotate(45deg);
overflow: hidden;
}
.picture > img(
max-width: 100%
transform: rotate(-45deg);
}
However, as you can see in the figure, we did not manage to achieve the required stylization with a swoop. Of course, if you were planning on cropping the image into an octagon shape, you can say you're done and move on to something else. But in order to crop the picture in the shape of a diamond, you still have to sweat.

The opposite transforms of rotate() are not enough to achieve the desired effect (the div called .picture is indicated by a dotted outline)
The main problem lies in the max-width: 100% declaration. 100% refers to the side of our container.picture . However, we want the width of the final image to be equal to the diagonal of the original, not its side. You guessed it, we again need the help of the Pythagorean theorem (if you need to refresh it in your memory, then you will find the explanation in the secret). According to the theorem, the diagonal of a square is equal to its side times .

Therefore, it makes sense to set the max-width value to 2 × 100% ≈ 141.4213562% or, rounding up, 142% , since we do not want the image to shrink in any way (and if it turns out to be slightly larger, then everything ok since we cut it off anyway).

In fact, it's even better to scale the image with the scale() transform, and there are two reasons for this: we want to keep the image size at 100% in a situation where CSS transforms are not supported;
When an image is scaled up using the scale() transform, it is scaled from the center (unless a different transform-origin value is specified). If you increase it by changing the value of the width property, then it will scale from the top left corner and in order to move it, we need to use negative margin values. Putting it all together, we get the following final version of the code:
.picture(
width: 400px
transform: rotate(45deg);
overflow: hidden;
}
.picture > img(
max-width: 100%
transform: rotate(-45deg) scale(1.42);
}
As you can see in the picture, this finally gives us the desired result.

TRY YOURSELF!
http://play.csssecrets.io/diamond-images

Clipping path solution

The previous solution works, but it's inherently a dirty trick. He demands additional element HTML, which means it's a messy, confusing, and brittle solution: if we have to deal with non-square images, the result will be dismal.


In reality, there are many The best way achieve the desired result. The main idea is to use the property clip path- another feature borrowed from SVG. This property can now be applied to HTML content as well (at least in supporting browsers), and with a nice and readable syntax, unlike the SVG equivalent, which is notorious for driving people crazy.

It has only one drawback (at the time of this writing) - limited browser support. However, this solution gracefully falls back to a simplified rendering (no cropping), so it's a worthy candidate to consider. Chances are you're already familiar with clipping paths thanks to image-editing apps like Adobe Photoshop. Clipping paths allow you to clip an element to any shape you wish. In this case, we are going to use the polygon() shape.

We will define a rhombus, but in general this shape allows you to define any polygon by a sequence of points separated by commas. You can even use percentages - the final values ​​will be calculated relative to the overall dimensions of the element. The code is very simple:
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);

Believe it or not, but that's it! But instead of two HTML elements and eight lines of obfuscated CSS code, we achieved our goal with just one simple line. But the wonderful abilities of clip-path are not limited to this. This property even supports animation - as long as we animate the transition between two identical shape functions (polygon() in our case) with the same number of points. Thus, if we want to smoothly expand the full image on hover, this can be done in this way:
img(
clip-path: polygon(50% 0, 100% 50%,
50% 100%, 0 50%);
transition: 1s clip-path;
}
img: hover (
clip-path: polygon(0 0, 100% 0,
100% 100%, 0 100%);
}
Also, this method adapts nicely to non-square images, Ah, the joys of modern CSS…
TRY YOURSELF!

Hello. Today we will touch on a rather unusual topic, namely the future of web design, these are CSS shapes.

As you know, it is very fashionable now, but it mainly consists of rectangles, which, in turn, greatly limit the horizons of designers. And then there's adaptability .. Which is very limiting about creativity. But there is one huge plus here - this is wrapping text around a rectangle, it’s easier than ever, but how to make text wrap around round or uneven shapes, that’s already more difficult. Because pictures cannot be made round.

Just in this case, the figures run to our aid. The popular W3C CSS site published the first documentation on shapes. Here is this post in English CSS Shapes Module Level 1 . This module was released recently on June 20th. So far, this is a beta version, which includes such shapes as a rectangle, triangle, ellipse, circle and polygon.

Now let's take a closer look at what is the advantage of CSS shapes using an example.

To begin with, let's take a simple HTML markup thanks for it http://www.webdesignerdepot.com :

This is an example text