Showing posts with label selectors. Show all posts
Showing posts with label selectors. Show all posts

Friday, 8 November 2024

What is Adjacent Sibling Selector in CSS?

In CSS, selectors play a crucial role in determining how your styles are applied to HTML elements. Among the various selectors available, the adjacent sibling selector (+) is particularly useful when you want to style an element that immediately follows another. In this blog post, we'll dive deep into what the adjacent sibling selector is, how it works, and why it's essential for styling in your web projects.

What is the Adjacent Sibling Selector?

The adjacent sibling selector is a CSS selector that allows you to select an element that directly follows another element, provided both elements share the same parent.

 

The syntax for the adjacent sibling selector is:

 

Example

selector1 + selector2 {
  /* CSS properties */
}

 

1.   selector1: The preceding element.

2.   selector2: The element that immediately follows selector1.

 

Why is it Called the "Adjacent Sibling Selector"?

The name "adjacent sibling selector" accurately describes its function:

 

1.   Adjacent: The selector only targets an element that comes immediately after another element, without any elements in between.

 

2.   Sibling: The two elements must share the same parent, making them siblings in the DOM structure.

 

This specificity makes the adjacent sibling selector a powerful tool for applying styles precisely where you need them.

 

adjacent-sibling-selector.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hyperlink Pseudo-selectors Example</title>
    <link rel="stylesheet" href="../../css/selectors/adjacent-sibling-selector.css">
</head>
<body>
    <h2>Introduction</h2>
    <p>This is the first paragraph after the heading.</p>
    <p>This is the second paragraph.</p>

    <h2>Another Section</h2>
    <p>This is the first paragraph after another heading.</p>
    <p>This is another paragraph in the section.</p>

</body>
</html>

 

adjacent-sibling-selector.css

h2 + p {
  font-size: 1.5em;
  color: green;
}

 

Above snippet generate below screen.

 



 

 

Previous                                                    Next                                                    Home

Tuesday, 29 October 2024

Introduction To CSS Class Selectors: A Step-by-Step Guide with Practical Examples

A class selector in CSS is used to apply styles to HTML elements that have a specific class attribute. Class selectors are versatile because they allow you to apply the same styles to multiple elements, regardless of their type, making them ideal for consistent styling across your web pages.

Syntax

.class-name {
    property: value;
}

1.   .class-name: The period (.) indicates that you are selecting a class. Replace class-name with the name of your class.

2.   property: value;: This is where you define the CSS properties you want to apply.

 

Example Using External CSS File

Let's create an example where we apply styles using a class selector.

 

class-selector.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Class Selector Example</title>
    <link rel="stylesheet" href="../../css/selectors/class-selector.css">
</head>
<body>
    <h1 class="highlight">Welcome to My Website</h1>
    <p class="highlight">This is a paragraph styled using a class selector.</p>
    <p>This paragraph does not have the class and will not be styled.</p>
</body>
</html>

class-selector.css

/* CSS file: styles.css */
.highlight {
    color: white;
    background-color: green;
    padding: 10px;
    border-radius: 5px;
}

Open ‘class-selector.html’ file in the browser, you can see below kind of screen.



Explanation

1.   HTML File: In the class-selector.html file, two elements (h1 and p) have been assigned the class highlight.

2.   CSS File: In the class-selector.css file, the .highlight class is defined with the following styles:

a.   color: white;: Sets the text color to white.

b.   background-color: green;: Sets the background color to blue.

c.    padding: 10px;: Adds padding inside the elements.

d.   border-radius: 5px;: Rounds the corners of the elements.

 

When to Use Class Selectors

1.   Reusability: Use class selectors when you want to apply the same styles to multiple elements on the page.

2.   Consistency: They ensure a consistent look and feel across your website.

3.   Specificity: Classes are more specific than element selectors but less specific than ID selectors. They are a good middle ground for styling.

4.   Modularity: Class selectors allow you to create modular styles that can be reused in different parts of your site without redundancy.

 

This approach helps to maintain cleaner and more organized code, making it easier to update and manage your styles.

 

Previous                                                    Next                                                    Home

Sunday, 16 June 2019

Selectors: Asynchronous Operations with NIO


Blocked IO Operations
All the standard IO operations are blocked. Suppose, you trigger a read() operation on InputStream, thread that trigger this read() operation blocks until data is ready to be read. In blocked state, thred will not perform any other operations, leads use resource wastage.

Asynchronous IO operation
With NIO, we can make IO operations asynchronous. We trigger a read operation and continue to work on something else. When the data is ready to be read, we are called back.

Why Asynchronous IO matter?
As compared to CPU centric and in-memory operation, IO operations (such as file, network specific) are pretty slow. With Asynchronous IO, a single thread request for some data to be read and can perform other operations mean time, when the data is ready, call back gets called. With this, we can keep the thread busy with other tasks, and a single thread can able to perform multiple operations.

What is Selector?
Selector is used to inspect one or more NIO channels and determine which channels are ready for writing or reading.

Why to use selector?
Using selector, single thread can able to handle multiple channels.


How to create a selector?
Selector selector = Selector.open();

How to register a channel to selector?
Using register method, you can register a channel to selector.
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

The channel must be in non-blocking mode to be used by the selector.

Second argument of register method specifies, what event you are interested to listen on this channel via selector.

There are 4 types of events. Below table summarizes the events.
Event
Description
OP_READ
Specifies read operation
OP_WRITE
Specifies write operation
OP_ACCEPT
Specifies socket accept operation
OP_CONNECT
Specifies socket connect operations

If you are interested in more than one event, combine them using bitwise | operator.

int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT;

How to build server using Selector?
Step 1: Create ServerSocketChannel and make it to work in non-blocking mode.

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);

Step 2: Create an instance of ServerSocket from ServerSocketChannel and bind it to the port.
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress(1234));

Step 3: Create a selctor and register server socket channel to the selector.
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

Step 4: Wait for the events to come.
int noOfEvents = selector.select();

‘select()’ method Selects a set of keys whose corresponding channels are ready for I/O operations. This method blocks until atleast one channel is selected.

Step 5: Get all the Selected keys and iterate over each selected key and take necessary action based on key's ready-operation set.
Set<SelectionKey> selectionKeys = selector.selectedKeys();

for (SelectionKey selectionKey : selectionKeys) {
 if ((selectionKey.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {

  // Accepting the client connection.
  System.out.println("Accepting the connection.......");
  ServerSocketChannel tempChannel = (ServerSocketChannel) selectionKey.channel();
  SocketChannel socketChannel = tempChannel.accept();
  socketChannel.configureBlocking(false);
  socketChannel.register(selector, SelectionKey.OP_READ);
  selectionKeys.remove(selectionKey);

 } else if ((selectionKey.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {

  // Reading the content from the channel
  try (SocketChannel tempChannel = (SocketChannel) (selectionKey.channel());) {
   ByteBuffer buffer = ByteBuffer.allocate(1024);
   tempChannel.read(buffer);
   buffer.flip();

   CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer);

   String data = new String(charBuffer.array());

   System.out.println("Received : " + data);

   buffer.clear();
   selectionKeys.remove(selectionKey);

   selectionKey.cancel();
  }

 }

}

Build a client socket to communicate with server socket
Step 1: Open SocketChannel for given address.
InetSocketAddress inetSocketAddress = new InetSocketAddress(1234);
SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);

Step 2: Get the Socket instance from socketChannel.
Socket socket = socketChannel.socket();

Step 3: Write the data to SocketChannel.
CharBuffer charBuffer = CharBuffer.allocate(1024);
charBuffer.put("Hello World");
charBuffer.flip();

ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(charBuffer);

socketChannel.write(byteBuffer);

Step 4: Close the socket.
socket.close();

Find the below working application.


AsyncServerSocket.java
package com.sample.app;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Set;

public class AsyncServerSocket {

 public static void main(String... args) throws IOException {

  // Create ServerSocketChannel and make it to work in non-blocking mode
  ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
  serverSocketChannel.configureBlocking(false);

  // Create an instance of ServerSocket from ServerSocketChannel and bind it to
  // the port
  ServerSocket serverSocket = serverSocketChannel.socket();
  serverSocket.bind(new InetSocketAddress(1234));

  // Create a Selector
  Selector selector = Selector.open();

  // Register the ServerSocketChannel with the selector. IO Channel is going to
  // send OP_ACCEPT events to the selector.
  serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

  while (true) {
   System.out.println("Waiting for the events......");

   // select() is a blocking call, it will be unblocked if there is atleast one
   // channel is selected.
   int noOfEvents = selector.select();
   System.out.println("Received " + noOfEvents + " events");

   Set<SelectionKey> selectionKeys = selector.selectedKeys();

   for (SelectionKey selectionKey : selectionKeys) {
    if ((selectionKey.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {

     // Accepting the client connection.
     System.out.println("Accepting the connection.......");
     ServerSocketChannel tempChannel = (ServerSocketChannel) selectionKey.channel();
     SocketChannel socketChannel = tempChannel.accept();
     socketChannel.configureBlocking(false);
     socketChannel.register(selector, SelectionKey.OP_READ);
     selectionKeys.remove(selectionKey);

    } else if ((selectionKey.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {

     // Reading the content from the channel
     try (SocketChannel tempChannel = (SocketChannel) (selectionKey.channel());) {
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      tempChannel.read(buffer);
      buffer.flip();

      CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer);

      String data = new String(charBuffer.array());

      System.out.println("Received : " + data);

      buffer.clear();
      selectionKeys.remove(selectionKey);

      selectionKey.cancel();
     }

    }

   }
  }
 }
}


MySocketClient.java
package com.sample.app;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;

public class MySocketClient {

 public static void main(String args[]) throws IOException {

  InetSocketAddress inetSocketAddress = new InetSocketAddress(1234);
  SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);

  Socket socket = socketChannel.socket();

  CharBuffer charBuffer = CharBuffer.allocate(1024);
  charBuffer.put("Hello World");
  charBuffer.flip();

  ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(charBuffer);

  socketChannel.write(byteBuffer);

  socket.close();

 }
}

Run 'AsyncServerSocket' application.

Run MySocketClient application.

You can able to see below messages in console of 'AsyncServerSocket' application.

Waiting for the events......
Received 1 events
Accepting the connection.......
Waiting for the events......
Received 1 events
Received : Hello World
Waiting for the events......



Previous                                                 Next                                                 Home